核心错误应该是[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
,我想了想可能是我对子路由的运用有问题,就取消了子路由,
<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>