Vue动态路由无匹配Vuex设备数据时跳转404页面的实现问题
Vue动态路由匹配不到设备数据跳转404解决方案
现有写法不生效的原因
你当前将校验逻辑写在详情页组件顶层,触发失败通常是两个原因:
- 若
store.state.stationName是异步请求获取的,组件初始化时数据还未返回,storedDeviceList.value为空数组,判断逻辑提前执行完成,等数据更新后不会重新触发校验 - 没有对路由参数和设备列表做响应式监听,参数或列表更新后无法重新执行校验逻辑
方案1:修复组件内的校验逻辑
新增响应式监听逻辑,保证数据更新后可以重新触发校验:
import { watch, computed } from 'vue' import { useRoute, useRouter } from 'vue-router' import { useStore } from 'vuex' const route = useRoute() const router = useRouter() const store = useStore() const storedDeviceList = computed(() => store.state.stationName) watch([storedDeviceList, () => route.params.device], ([newDeviceList, newDeviceName]) => { // 先判断设备列表已加载完成,避免异步请求未完成导致的误判 if (newDeviceList.length && !newDeviceList.includes(newDeviceName)) { // 用replace代替push,避免无效路由进入历史记录 router.replace({ name: 'NotFound' }) } }, { immediate: true }) // 初始化时立即执行一次校验
方案2(更推荐):使用路由独享守卫
直接在路由配置层做校验,不需要侵入业务组件代码,逻辑更聚合:
修改router/index.js配置如下:
// 先引入项目的Vuex实例 import store from '../store' const routes = [ { path: '/', name: 'Main', component: Main }, { path: '/:device', name: 'Detail', component: Detail, // 新增路由独享前置守卫 beforeEnter: (to, from, next) => { const targetDevice = to.params.device const deviceList = store.state.stationName if (deviceList.length && !deviceList.includes(targetDevice)) { // 匹配失败直接跳转到404 next({ name: 'NotFound' }) return } // 匹配成功/设备列表未加载完成,放行 next() } }, { path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound }, ]
如果你的设备列表是异步加载的,可在全局前置守卫中等待列表请求完成后再执行校验,避免出现空列表的误判。
内容的提问来源于stack exchange,提问作者air walk
相关产品推荐
相关产品推荐

