方法一:(自用)
封装Tabbar.vue
<template>
<div class="tabbar">
<tabbar v-model="tabbarIndex">
<tabbar-item
:link="item.pagePath"
v-for="item in tabList"
:key="item.text"
>
<span slot="icon" class="iconfont gray" :class="item.iconPath"></span>
<span
slot="icon-active"
class="iconfont blue"
:class="item.selectedIconPath"
></span>
<span slot="label">{{ item.text }}</span>
</tabbar-item>
<!-- <tabbar-item show-dot link="/workTable">
<span slot="icon" class="iconfont gray icon-wanggea-bianzu4"></span>
<span
slot="icon-active"
class="iconfont blue icon-wanggea-bianzu22"
></span>
<span slot="label">工作台</span>
</tabbar-item> -->
<!-- <tabbar-item link="/performance">
<span slot="icon" class="iconfont gray icon-wanggejixiao"></span>
<span
slot="icon-active"
class="iconfont blue icon-wanggejixiaobeifen"
></span>
<span slot="label">绩效</span>
</tabbar-item> -->
<!-- <tabbar-item badge="2" link="/mine">
<span slot="icon" class="iconfont gray icon-wanggea-bianzu21"></span>
<span
slot="icon-active"
class="iconfont blue icon-wanggebianzu1"
></span>
<span slot="label">我的</span>
</tabbar-item> -->
</tabbar>
</div>
</template>
<script>
import { Tabbar, TabbarItem } from "vux";
export default {
name: "TabbarView",
components: {
Tabbar,
TabbarItem,
},
props: {
tabList: {
type: Array,
default: [],
},
},
data() {
return {
tabbarIndex: null,
};
},
watch: {
$route: {
handler(newV) {
this.tabbarIndex = this.tabList.findIndex(
(i) => i.pagePath === newV.path
);
},
immediate: true,
deep: true,
},
},
methods: {},
};
</script>
<style lang="scss" scoped>
.tabbar {
.weui-tabbar {
position: fixed;
background-color: #fff;
}
/deep/ .weui-tabbar__icon {
// width: 17px;
height: 17px;
margin: 5px 0;
}
/deep/ .weui-tabbar__label {
font-size: 10px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #5e6166;
}
/deep/ .weui-tabbar__item {
padding: 5px 0 10px;
}
/deep/ .weui-tabbar__item.weui-bar__item_on {
.weui-tabbar__icon,
.weui-tabbar__icon > i,
.weui-tabbar__label {
color: #3875c6;
}
}
.iconfont {
font-size: 20px;
}
.gray {
color: RGBA(94, 97, 102, 1);
}
.blue {
color: RGBA(56, 117, 198, 1);
}
}
</style>
App.vue引入
<template>
<div id="app">
<div class="container">
<router-view></router-view>
</div>
<!-- 底部选项卡 -->
<Tabbar ref="TabbarView" :tabList="tabList" v-if="tabbarShow"></Tabbar>
</div>
</template>
<script>
import Tabbar from "@/components/tabbar.vue";
export default {
name: "app",
data() {
return {
msg: "Home",
tabList: [
{
pagePath: "/",
iconPath: "icon-wanggebianzu3",
selectedIconPath: "icon-wanggea-bianzu23",
text: "首页",
},
{
pagePath: "/workTable",
iconPath: "icon-wanggea-bianzu4",
selectedIconPath: "icon-wanggea-bianzu22",
text: "工作",
},
{
pagePath: "/performance",
iconPath: "icon-wanggejixiao",
selectedIconPath: "icon-wanggejixiaobeifen",
text: "绩效",
},
{
pagePath: "/mine",
iconPath: "icon-wanggea-bianzu21",
selectedIconPath: "icon-wanggebianzu1",
text: "我的",
},
],
};
},
components: {
Tabbar,
},
// 监听,当路由发生变化的时候执行
watch: {
$route(to, from) {
//判断是否显示tabbar
if (
to.path == "/" ||
to.path == "/workTable" ||
to.path == "/performance" ||
to.path == "/mine"
) {
this.$store.commit("setTabbarShow", true);
} else {
this.$store.commit("setTabbarShow", false);
}
},
},
computed: {
tabbarShow() {
return this.$store.getters.getTabbarShow;
},
},
};
</script>
store.js
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
tabbarShow:true
},
getters:{
getTabbarShow(state){
return state.tabbarShow
}
},
mutations: {
setTabbarShow(state, payload) {
state.tabbarShow = payload;
}
},
actions: {}
});
方法二:
tabbar.vue
<template>
<div class="tabbar">
<tabbar>
<tabbar-item selected link="/index">
<img slot="icon" src="../../assets/images/icon.png">
<img slot="icon-active" src="../../assets/images/active-icon.png">
<span slot="label">首页</span>
</tabbar-item>
<tabbar-item>
<img slot="icon" src="../../assets/images/icon.png">
<img slot="icon-active" src="../../assets/images/active-icon.png">
<span slot="label">开庄</span>
</tabbar-item>
<tabbar-item >
<img slot="icon" src="../../assets/images/icon.png">
<img slot="icon-active" src="../../assets/images/active-icon.png">
<span slot="label">我的投注</span>
</tabbar-item>
<tabbar-item link="/mine">
<img slot="icon" src="../../assets/images/icon.png">
<img slot="icon-active" src="../../assets/images/active-icon.png">
<span slot="label">我的</span>
</tabbar-item>
</tabbar>
</div>
</template>
<script>
import { Tabbar, TabbarItem } from 'vux'
export default {
components: {
Tabbar,
TabbarItem
},
data(){
return {
}
},
methods:{},
created(){},
mounted(){}
}
</script>
<style scoped>
</style>
App.vue引入
<template>
<div id="app">
<transition :name="viewTransition">
<router-view class="router-view" />
</transition>
<Tabbar v-if="tabbarShow"></Tabbar>
</div>
</template>
<script>
import Tabbar from '@/pages/common/tabbar.vue'
export default {
name: 'App',
components: {
Tabbar
},
// 监听,当路由发生变化的时候执行
watch:{
$route(to,from){
//判断是否显示tabbar
if(to.path == '/' || to.path == '/index' || to.path == '/mine'){
this.$store.commit('updateTabbarShow',true);
}else{
this.$store.commit('updateTabbarShow',false);
}
}
},
computed: {
tabbarShow(){
return this.$store.getters.getTabbarShow
}
},
}
</script>
<style lang="less">
</style>
store.js
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
tabbarShow:true
},
getters:{
getTabbarShow(state){
return state.tabbarShow
}
},
mutations: {
updateTabbarShow(state, payload){
state.tabbarShow = payload
}
},
actions: {}
});
方法三:
<!-- 入口文件 -->
<template>
<div id="app">
<!-- 视图层 -->
<router-view></router-view>
<!-- 底部选项卡 -->
<tabbar @on-index-change="onIndexChange" v-if="tabbarShow">
<tabbar-item selected link="/home">
<img slot="icon" src="./assets/img/ic_tab_home_normal.png">
<img slot="icon-active" src="./assets/img/ic_tab_home_active.png">
<span slot="label">首页</span>
</tabbar-item>
<tabbar-item show-dot link="/audioBook">
<img slot="icon" src="./assets/img/ic_tab_subject_normal.png">
<img slot="icon-active" src="./assets/img/ic_tab_subject_active.png">
<span slot="label">书影音</span>
</tabbar-item>
<tabbar-item badge="2" link="/mine">
<img slot="icon" src="./assets/img/ic_tab_profile_normal.png">
<img slot="icon-active" src="./assets/img/ic_tab_profile_active.png">
<span slot="label">我的</span>
</tabbar-item>
</tabbar>
</div>
</template>
<script>
// 引入 vux tabbar 组件
import { Tabbar, TabbarItem } from 'vux'
// 引入 vuex 的两个方法
import {mapGetters, mapActions} from 'vuex'
export default {
name: 'app',
components:{
Tabbar,
TabbarItem
},
data() {
return {
select:"Home"
}
},
// 计算属性
computed:mapGetters([
// 从 getters 中获取值
'tabbarShow'
]),
// 监听,当路由发生变化的时候执行
watch:{
$route(to,from){
if(to.path == '/' || to.path == '/home' || to.path == '/audioBook' || to.path == '/mine'){
/**
* $store来自Store对象
* dispatch 向 actions 发起请求
*/
this.$store.dispatch('showTabBar');
}else{
this.$store.dispatch('hideTabBar');
}
}
},
methods: {
onIndexChange (newIndex, oldIndex) {
console.log(newIndex, oldIndex);
}
}
}
</script>
<style lang="less" scoped>
</style>
方法四:
components/Tabbar.vue
<template>
<div>
<tabbar v-model="tabbarIndex" style="position: fixed">
<tabbar-item @on-item-click="gotoTabbarPage(0)">
<img slot="icon" src="../../assets/images/tabbar/homepage.png">
<img slot="icon-active" src="../../assets/images/tabbar/homepage_fill.png">
<span slot="label">首页</span>
</tabbar-item>
<tabbar-item @on-item-click="gotoTabbarPage(1)">
<img slot="icon" src="../../assets/images/tabbar/dynamic.png">
<img slot="icon-active" src="../../assets/images/tabbar/dynamic_fill.png">
<span slot="label">监控</span>
</tabbar-item>
<tabbar-item @on-item-click="gotoTabbarPage(2)" badge="待">
<img slot="icon" src="../../assets/images/tabbar/remind.png">
<img slot="icon-active" src="../../assets/images/tabbar/remind_fill.png">
<span slot="label">告警</span>
</tabbar-item>
<tabbar-item @on-item-click="gotoTabbarPage(3)">
<img slot="icon" src="../../assets/images/tabbar/people.png">
<img slot="icon-active" src="../../assets/images/tabbar/people_fill.png">
<span slot="label">我的</span>
</tabbar-item>
</tabbar>
</div>
</template>
<script>
import { Tabbar, AlertModule, TabbarItem, Group, Cell, TransferDomDirective as TransferDom } from 'vux'
export default {
name: 'MyTabbar',
directives: {
TransferDom
},
components: {
Tabbar,
TabbarItem,
Group,
Cell
},
data () {
return {
// 从state中获取全局tabbarIndex
tabbarIndex: this.$store.state.tabbarIndex,
show: false
}
},
methods: {
gotoTabbarPage (tabbarIndex) {
if (tabbarIndex === 2) {
AlertModule.show({
title: '敬请期待',
content: '敬请期待',
onShow () {
console.log('Module: I\'m showing')
},
onHide () {
console.log('Module: I\'m hiding now')
}
})
} else {
// 由于这里需要更改全局tabbarIndex,所以必须通过mutations方式去跳转
// 更新底部菜单index
this.$store.dispatch('updateTabbarIndex', {tabbarIndex: tabbarIndex})
}
}
},
watch: {
tabbarIndex: function (val, oldVal) {
// 这里就可以通过 val 的值变更来确定
console.log(val)
}
}
}
</script>
store/index.js
// vuex配置
import Vue from 'vue'
import Vuex from 'vuex'
import * as actions from './actions.js'
import mutations from './mutations.js'
import state from './state.js'
Vue.use(Vuex)
const debug = process.env.NODE_ENV !== 'production'
export default new Vuex.Store({
state,
actions,
mutations,
strict: debug
})
store/state.js
export default {
tabbarIndex: 0
}
store/actions.js
import * as types from './mutation-types.js'
export const goTo = ({commit}, user) => {
setInterval(() => {
commit(types.GOTO, {
userId: user.userId
})
}, 2000)
}
// 更新全局tabbar索引
export const updateTabbarIndex = ({commit}, param) => {
commit(types.UPDATE_TABBAR_INDEX, {
tabbarIndex: param.tabbarIndex
})
}
store/mutation-types.js
export const GOTO = 'GOTO'
export const UPDATE_TABBAR_INDEX = 'UPDATE_TABBAR_INDEX'
store/mutations.js
import * as types from './mutation-types.js'
import VueRouter from '../router/routes.js'
export default {
[types.GOTO] (state, {userId}) {
console.log('进入GOTO,userId=' + userId)
VueRouter.push({
name: 'list', params: {userId: userId, title: state.title}
// 如果需要传参,则不能使用path,需要使用name
})
},
[types.UPDATE_TABBAR_INDEX] (state, {tabbarIndex}) {
console.log('执行UPDATE_TABBAR_INDEX,tabbarIndex=' + tabbarIndex)
// 改变值
state.tabbarIndex = tabbarIndex
if (tabbarIndex === 0) {
VueRouter.push({
path: '/home'
})
}
if (tabbarIndex === 1) {
VueRouter.push({
path: '/moni'
})
}
if (tabbarIndex === 2) {
VueRouter.push({
path: '/warn'
})
}
if (tabbarIndex === 3) {
VueRouter.push({
path: '/account'
})
}
}
}
Home.vue
<template>
<div class="home">
<grid style="border: none; background-color: #fff">
<grid-item link="/apiCenter" style="display: inline-block !important">
<img slot="icon" src="../assets/images/home/api_center_fill.png" />
<span slot="label">API中心</span>
</grid-item>
<grid-item @on-item-click="onItemClick('wait')">
<img slot="icon" src="../assets/images/home/my_moni_fill.png" />
<span slot="label">我的监控</span>
</grid-item>
<grid-item link="/apiMyCall" @on-item-click="onItemClick">
<img slot="icon" src="../assets/images/home/analysis_fill.png" />
<span slot="label">接口分析</span>
</grid-item>
<!-- 导航跳转 -->
<grid-item @on-item-click="onItemClick('moni')">
<img slot="icon" src="../assets/images/home/dynamic_fill.png" />
<span slot="label">监控管理</span>
</grid-item>
</grid>
<myTabbar></myTabbar>
</div>
</template>
<script>
import {
Grid,
GridItem,
AlertModule,
TransferDomDirective as TransferDom,
} from "vux";
import myTabbar from "../components/tabbar/Tabbar.vue";
export default {
name: "Home",
directives: {
TransferDom,
},
components: {
myTabbar: myTabbar,
Grid,
GridItem,
AlertModule,
},
data() {
return {};
},
methods: {
onItemClick(type) {
if (type === "moni") {
this.$store.dispatch("updateTabbarIndex", { tabbarIndex: 1 });
}
if (type === "wait") {
AlertModule.show({
title: "敬请期待",
content: "敬请期待",
onShow() {},
onHide() {},
});
}
},
},
};
</script>
参考
Tabbar
tabbar组件里面关于selected选项 #1881
tabbar切换后刷新,选中状态问题 #2388