12.vue-router路由复用统一组件,页面不刷新
leezozz 2/21/2023 笔记
# vue-router路由复用统一组件,页面不刷新
# 场景1
多路由使用同一组件
如:添加博客(path为:/addBlog)和编辑博客(path为:/editBlog)都对应同一个组件(EditBlog.vue)
# 场景2
动态路由
如:用户详情页采用动态路由,其path为:/user/:id,组件都是UserDetail.vue
# 分析
vue中相同的组件实例将被重复使用。如果两个路由都渲染同个组件,复用比销毁在创建更高效。但是复用组件的生命周期函数(created, mounted...)不会被调用。通常调用后端接口会放到created, mounted等钩子函数中,此时生命周期函数没有调用,也就无法获取后端数据
# 方案1
watch 监听路由变化
watch(
() => route,
() => {
// xxx
},
{
immediate: true
}
)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 方案2
给router-view绑定相应的key值
设置router-view的key属性值为route.path,或route.fullpath
# 方案3
onBeforeRouteUpdate
钩子加载顺序:onBeforeRouteUpdate => created => mounted
// 如:当前在页面 /detail/111 ,通过点击 router-link 访问 /detail/222
// 同一个路由,只是更新了 route.params.id ,组件处于被复用的状态,这样会触发 update 钩子
import { defineComponent, onMounted } from 'vue'
import { useRoute, onBeforeRouteUpdate } from 'vue-router'
export default defineComponent({
setup() {
// 其他代码略...
// 查询文章详情
async function queryArticleDetail(id: number) {
// 请求接口数据
const res = await axios({
url: `/article/${id}`,
})
// ...
}
// 组件挂载完成后执行文章内容的请求
// 注意这里是获取 `route` 的 `params`
onMounted(async () => {
const id = Number(route.params.id) || 0
await queryArticleDetail(id)
})
// 组件被复用时重新请求新的文章内容
onBeforeRouteUpdate(async (to, from) => {
// ID 不变时减少重复请求
if (to.params.id === from.params.id) return
// 注意这里是获取 `to` 的 `params`
const id = Number(to.params.id) || 0
await queryArticleDetail(id)
})
},
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37