今天修改写页面的时候发现一个Bug,底部导航栏默认是在首页,在其他页面进行刷新的时候,导航栏active又回回到首页,这样体验很不好

环境

"vue-router": "^4.0.10",
"vue": "^3.0.5",
"vant": "^3.1.5",
<!-- template -->
<router-view />
<van-tabbar
            v-model="navActive"
            active-color="#e43130"
            inactive-color="#000"
            >
  <van-tabbar-item to="/" icon="home-o">首页</van-tabbar-item>
  <van-tabbar-item to="/category" icon="search">分类</van-tabbar-item>
  <van-tabbar-item to="/cart" icon="friends-o">购物车</van-tabbar-item>
  <van-tabbar-item to="/mine" icon="setting-o">我的</van-tabbar-item>
</van-tabbar>

代码

// <script lang="ts">
import { defineComponent, ref } from 'vue'
export default defineComponent({
  name: 'App',
  setup: () => {
    const navActive = ref<number>(0)
    return { navActive }
  }
})

代码很简单,就只是一个Vant组件,对应着4个页面,首次默认active是0,下面我们写我们想要的效果

import { useRouter } from 'vue-router'
const router = useRouter()

// getRouters() 获取注册的router列表
// currentRoute.value.path 当前页面的path
router.getRoutes().map((item, index) => {
  if(item.path === router.currentRoute.value.path){
    navActive.value = index
  }
})

这段代码理论上可以实现我们的需求,但是实际上并不能,刷新首次加载获取到的是/,但是期望值是/category

实现方式有很多种,setTimeOut()等页面渲染完成,再执行代码,但更推荐使用watch或者vue3新出的watchEffect

// 添加<script lang="ts">
// watch方法,此方法和vue2的watch完全等效
import { watch } from 'vue'
watch(
  () => router.currentRoute.value.path,
  (path, oldPath) => {
    router.getRoutes().map((item, index) => {
      if (path === item.path) {
        navActive.value = index
      }
    })
  },
  {
    deep: false, // 是否采用深度监听
    immediate: false // 首次加载是否执行
  }
)
// 添加<script lang="ts">
// watchEffect方法,Vue3新增方法,自动收集依赖
// 每次首次都会自动执行,相当于 immediate: true
import { watchEffect } from 'vue'
watchEffect(() => {
  router.getRoutes().map((item, index) => {
    if(item.path === router.currentRoute.value.path){
      navActive.value = index
    }
  })
})

这样我们想要的功能就实现了

Logo

前往低代码交流专区

更多推荐