记一次踩雷经历:Vue引入vant /van-tabs组件后不显示/van-tabs和子路由的封装后Failed to resolve directive: keep-scroll-position

在这里插入图片描述
核心错误应该是[Vue warn]: Property or method "$t" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property和下面的提示Error in render: "TypeError: _vm.$t is not a function"以及最后的TypeError: "_vm.$t is not a function"

问题出现在我是按需引入的插件,在main.js中引入的时候出错了,可以看到tabbar下面有个小波浪号,首字母要大写
在这里插入图片描述
如果此时还是出错,则删掉npm uninstall i babel-plugin-import -D按需引入的,以及相关的js配置文件中一起删掉,选择全部一起引入,否则会找不到Vant。
但是当vant可以全局引入的时候会报同样的错误。所以应该不是引入方式的问题,网上普遍说是引入vux插件的问题,但是我又没有引入这个插件。并且我在引入button的时候是没有问题的,因此问题应该出现在我引入的tabBar。

    <!--下方的TabBar-->
    <van-tabbar v-model="tabBarSelect">
      <van-tabbar-item v-for="(item, i) in tabItemList" :key="i" :to="item.to" replace>
        <div class="tab-txt">{{$t(item.name)}}</div>
        <img :src="getTabIconSrc(item, props.active)" slot="icon" slot-scope="props" class="icon-img"/>
      </van-tabbar-item>
    </van-tabbar>

然后这里的tabitemlist是这样的,我确保了图片和路径的正确,img主要是想要一个点击之后的高亮:

        tabItemList: [
          {
            active: 'main_tab_3.png',
            normal: 'main_tab_2.png',
            name: 'tab_home',
            to: "home"
          },
          {
            active: 'main_tab_5.png',
            normal: 'main_tab_4.png',
            name: 'tab_products',
            to: "products"
          },
          {
            active: 'main_tab_7.png',
            normal: 'main_tab_6.png',
            name: 'tab_discovery',
            to: "discover"
          },
          {
            active: 'main_tab_1.png',
            normal: 'main_tab_8.png',
            name: 'tab_mine',
            to: "mine"
          },
        ],

首先我测试了一下别的方式引入tabbar是不会出错的,进一步说明不是引入的问题。

   <van-tabbar v-model="tabBarSelect" >
       <van-tabbar-item icon="gem-o" url="/Home">精选</van-tabbar-item>
       <van-tabbar-item icon="shop-o">分类</van-tabbar-item>
       <van-tabbar-item icon="shopping-cart-o">购物车</van-tabbar-item>
       <van-tabbar-item icon="manager-o">我的</van-tabbar-item>
   </van-tabbar>

接下来实现路由跳转。注意我这里的路由设置是这样的,设置了一个公共的副路由mainpage,mainpage里面引入tabbar组件,并且进行第二次的路由跳转。

//routes.js
const routes = [{
    path: '/',
    name:"main",
    // component: App,
    component: (resolve) => require(['../page/mainpage/index'], resolve),
    //父路由是APP.vue,子路由在副路由中出现
    children: [
        {
            path: '/index',
            name:'home',
            meta: {
                title: '首页',
                keepAlive: true
            },
            component: (resolve) => require(['../page/home/index'], resolve)
        },
        {
            path: '/item',
            name:'item',
            meta: {
                title: '分类',
                keepAlive: true
            },
            component: (resolve) => require(['../page/item'], resolve)
        },
        {
            path: '/cart',
            name:'cart',
            meta: {
                title: '购物车',
                keepAlive: true
            },
            component: (resolve) => require(['../page/cart'], resolve)
        },
        {
            path: '/mine',
            name:'mine',
            meta: {
                title: '我的',
                keepAlive: true
            },
            component: (resolve) => require(['../page/mine'], resolve)
        },
        {
            path: '*',
            redirect: '/index'
        }
    ], meta: {keepAlive: true}
}]

改进后可以实现路由跳转的mainpage的tab组件部分,只需要加一个onchange来监听tabbar发生变化:

        <van-tabbar v-model="tabBarSelect"  @change="onChange">
            <van-tabbar-item icon="gem-o" url="/home">精选</van-tabbar-item>
            <van-tabbar-item icon="shop-o">分类</van-tabbar-item>
            <van-tabbar-item icon="shopping-cart-o">购物车</van-tabbar-item>
            <van-tabbar-item icon="manager-o">我的</van-tabbar-item>
        </van-tabbar>

发生变化后触发了方法:

     methods: {
         onChange(index) {
             const routerArray = [
                 "/home",
                 "/item",
                 "/cart",
                 "/mine"
             ];
             this.$router.push(routerArray[index])
         },
     },

但是现在还有一个问题就是,每次店家home页面时会刷新缓存。并且还是有个警告:Failed to resolve directive: keep-scroll-position,我想了想可能是我对子路由的运用有问题,就取消了子路由,

改成了直接把组件放在app.vue中。

<template>
  <div id="app">
    <!--缓存的页面-->
    <keep-alive>
      <router-view v-if="$route.meta.keepAlive"/>
    </keep-alive>
    <!--不缓存的页面-->
    <router-view v-if="!$route.meta.keepAlive"/>
    <tabbar v-if="$route.meta.showTab" />
  </div>
</template>

<script>
import Tabbar from './components/Tabbar'
export default {
  name: 'App',
  components: {
    Tabbar
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}
</style>

文件结构是:
在这里插入图片描述
路由设置是:

import Vue from 'vue'
import VueRouter from 'vue-router'
// import App from '../App.vue'

const routes = [
        {
            path: '/index',
            name:'home',
            meta: {
                title: '首页',
                keepAlive: true,
                showTab: true
            },
            component: (resolve) => require(['../page/home/index'], resolve)
        },
        {
            path: '/item',
            name:'item',
            meta: {
                title: '分类',
                keepAlive: true,
                showTab: true
            },
            component: (resolve) => require(['../page/item'], resolve)
        },
        {
            path: '/cart',
            name:'cart',
            meta: {
                title: '购物车',
                keepAlive: true,
                showTab: true
            },
            component: (resolve) => require(['../page/cart'], resolve)
        },
        {
            path: '/mine',
            name:'mine',
            meta: {
                title: '我的',
                keepAlive: true,
                showTab: true
            },
            component: (resolve) => require(['../page/mine'], resolve)
        },
        {
            path: '*',
            redirect: '/index'
        }

]

然后tabbar的组件的设置是,要特别的注意这里的tabbar没有设置属性route,所以需要自己设置监听动作onChange,否则只需要直接在van-tabbar-item中设置to就能实现路由跳转,但是此时不会自动改变颜色:

<template>
    <div class="tabbar">
        <van-tabbar v-model="tabBarSelect"  @change="onChange" :active-color="color" :fixed="false">
            <van-tabbar-item icon="gem-o" url="/home">精选</van-tabbar-item>
            <van-tabbar-item icon="shop-o">分类</van-tabbar-item>
            <van-tabbar-item icon="shopping-cart-o">购物车</van-tabbar-item>
            <van-tabbar-item icon="manager-o">我的</van-tabbar-item>
        </van-tabbar>
    </div>
</template>

<script>
    export default {
        name: "index",
        watch: {

        },
        computed: {
            color(){
                return "#1c99e2c0";
            }

        },
        data() {
            return {
                tabBarSelect: 0,
            };
        },
        methods: {
            onChange(index) {
                const routerArray = [
                    "/index",
                    "/item",
                    "/cart",
                    "/mine"
                ];
                this.$router.push(routerArray[index])
            },
        },
        mounted() {

        }
    }
</script>

<style scoped>
    .tabbar {
        width: 100vw;
        position: fixed;
        bottom: 0;
        left: 0;
        border-top: 2px solid #f5f5f5;
    }
</style>

tabbar的另外一个写法,,此时需要额外的设置高亮:

    <div class="tabbar">
      <van-tabbar v-model="active" :active-color="variables.theme" :fixed="false" route>
        <van-tabbar-item to="/" icon="wap-home">首页</van-tabbar-item>
        <van-tabbar-item to="/category" icon="bars">分类</van-tabbar-item>
        <van-tabbar-item to="/cart" icon="shopping-cart">购物车</van-tabbar-item>
        <van-tabbar-item to="/user" icon="manager">我的</van-tabbar-item>
      </van-tabbar>
    </div>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章