vue 跳转页面返回时tab状态有误的解决办法

一、前言

最近在做新vue项目的时候遇到了一个问题,就是tab间的切换没有问题,当跳转到其他页面时,且这个页面并非子路由,再用浏览器的返回按钮返回首页时,tab的active始终指向默认的第一个选项。

感觉这还是个比较常见的问题,但是在网上居然没怎么搜索到,自己摸索了一下,搞了一个解决办法出来。由于项目的骨架部分及tab并不是我写的,在此只根据原本的代码给出一个解决方案。

二、代码

1. 监听返回

想要解决这个问题,首先要监听到返回首页的事件,然后把具体的路由值传到Tabbar这个组件里。

// index.vue

<template>
    <div>
        <router-view></router-view>
        <Tabbar :active="tabActive"></Tabbar>
    </div>
</template>

<script>
import Tabbar from './../components/tabbar'
export default {
    data() {
        return {
            tabActive: 'home/home'
        }
    },
    components:{
       Tabbar 
    },
    beforeRouteEnter: (to, from, next) => {
        next(vm => {
          vm.tabActive = 'home/' + to.name;
        });
    },
}
</script>

这里用到了beforeRouteEnter这个路由钩子,在vue-router的官网叫做组件内的路由导航守卫。这个钩子可以监听到从其他非子路由的页面通过点击浏览器的返回按钮跳转到首页的事件,然后把这个路由to.name传递到Tabbar组件内。

2. 改变组件内状态

// Tabbar.vue

<template>
    <div class='tabbar'>
        <Item txt='自选' mark='home/home' :sel='selected' @change='getVal'>
            <img src='../assets/images/index1.png' slot='activeImg'/>
            <img src='../assets/images/index0.png' slot='normalImg'/>
        </Item>
        <Item txt='询价' mark='home/inquiry' :sel='selected' @change='getVal'>
            <img src='../assets/images/inquiry1.png' slot='activeImg'/>
            <img src='../assets/images/inquiry0.png' slot='normalImg'/>
        </Item>
        <Item txt='订单' mark='home/hold' :sel='selected' @change='getVal'>
            <img src='../assets/images/hold1.png' slot='activeImg'/>
            <img src='../assets/images/hold0.png' slot='normalImg'/>
        </Item>
        <Item txt='账户' mark='home/mine' :sel='selected' @change='getVal'>
            <img src='../assets/images/mine1.png' slot='activeImg'/>
            <img src='../assets/images/mine0.png' slot='normalImg'/>
        </Item>
    </div>
</template>

<script>
import Item from './item'

export default {
    props: ['active'],
    components: {
        Item
    },
    data: function(){
        return {
            selected: 'home/home'
        }
    },
    watch: {
        'active'(newVal,oldVal) {
            this.selected = newVal;
        }
    },
    methods: {
        getVal: function(val){
            this.selected = val;
        }
    }
}

</script>

<style>
    .tabbar{width: 100%; height: 2.8rem; border-top: 1px solid #ccc; position: fixed; left: 0; bottom: 0;background-color: white;}
</style>

在Tabbar组件内首先通过props接受到外部传进来的active值,再用watch监听器监听active的变化,将新值赋给selected,这样就可以完美解决这个问题了。

最后给出其中Item组件的代码:

<template>
    <div class='itemWrap' @click='fn'>
        <span v-show='bol'><slot name='activeImg'></slot><br/></span>
        <span v-show='!bol'><slot name='normalImg'></slot><br/></span>
        <span :class='{active: bol}'>{{ txt }}</span>
    </div>
</template>

<script>
export default {
    props: ['txt', 'mark', 'sel'],
    computed: {
        bol: function(){
            if (this.mark == this.sel){
                return true;
            }
            return false;
        }
    },
    methods: {
        fn: function(){
            this.$emit('change',this.mark);
            this.$router.push('/' + this.mark);
        }
    }
}
</script>

<style>
.itemWrap{width: 25%; float: left; text-align: center; font-size:0;}
.itemWrap img{width: 1.2rem;height: 1.2rem;margin-top: 0.5rem;}
.itemWrap span{font-size: 0.6rem; color: #666;}
.itemWrap .active{color: #dc4537;}
</style>

三、结语

感觉这个Tabbar写得有些复杂,但是解决此问题的办法应该是比较通用的。希望可以帮到和我遇到一样问题的人。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值