前提:
需求如下图:
编辑和新增商品是同一个页面,路由配置如下:
routes: [{
path: 'add',
component: () => import('@/views/product/edit'),
name: 'product-add',
meta: { title: '新增商品' }
}, {
path: 'edit/:id',
component: () => import('@/views/product/edit'),
name: 'product-edit',
meta: { title: '编辑商品' }
}]
解决办法:
我原来的做法如下:
computed:{
id:{
return this.$route.params.id
}
},
watch:{
if (val) {
this.getDetail() // 编辑
} else {
this.reset() // 清空
}
}
这种做法有一个弊端:
假设现在还有一个列表页(list.vue)和一个可以查看列表页单条数据的详情页(detail.vue),路由如下:
routes: [{
path: 'list',
component: () => import('@/views/product/list'),
name: 'list',
meta: { title: '列表' }
}, {
path: 'list/:id',
component: () => import('@/views/product/detail'),
name: 'detail',
meta: { title: '详情' }
}]
如果此时我已经打开了某个商品的编辑页edit.vue(url是/edit/12),再去打开列表的详情页detail.vue(url是/list/34),这时edit.vue中的id会变成detail.vue中的id,也就是34。因为不存在id=34的这条商品数据,所以调用后台接口就会报错。解决方式就是修改路由中参数的名称(即id),但是在项目中查看详情页的情况太多了,每个需要查看详情页的路由都用一个独特的参数名称很为难(对我而言是这样啦!因为我现在的项目中太多需要查看详情页的需求)、所以我就改成了下面这种解决方式:
data:{
id: ''
},
beforeRouteEnter (to, from, next) {
next(vm => {
vm.id = to.params.id || '' // 注意这行:to.params.id有值代表编辑,赋值给id;没有值代表新增,空字符串赋给id
})
},
beforeRouteUpdate (to, from, next) {
this.id = to.params.id
next()
},
watch:{
if (val) {
this.getDetail()
} else {
this.reset()
}
}
但是又有了新的问题。我发现beforeRouteEnter中next的回调函数(vm => { vm.id = to.params.id || '' })有时候不会执行。如果我先打开编辑页,会执行,再打开新增页,就不会执行。如果我先打开新增页,会执行,再打开编辑页,就不会执行。这是什么原因呢?请大家帮忙解惑。如果有更好的实现方式也请告知,谢谢
泻药~
快被你绕晕了,哈哈。
首先,你的新增页和编辑页引用的是同一个组件,所以如果不做处理的话,肯定会出现切换不同的路由的时候肯定会出现钩子函数不执行的问题。这个可以通过
watch route
或者router-view
里添加唯一键来处理,如<router-view :key="$route.fullpath"></router-view>
。你看看是否有帮助