記一次踩雷經歷: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>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章