核心錯誤應該是
[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>