12.vue-router路由复用统一组件,页面不刷新

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

给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

参考文章 (opens new window)

最近更新时间: 2/22/2023, 6:39:10 AM
강남역 4번 출구
Plastic / Fallin` Dild