vue项目中解决路由缓存组件不重新请求数据问题

Posted 奥特曼 

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue项目中解决路由缓存组件不重新请求数据问题相关的知识,希望对你有一定的参考价值。

场景:

当点击个护标题时再点击严选标题时页面数据没有发生请求

当点击标题时只有我们通过<router-link to="${xx}"></router-link>的路由id变了,并没有去重新请求页面的变化,只有刷新页面后才会去请求当前id的数据,其实也是可以理解的, 对比一下这两个路由 只是后面路由的参数变了,但是组件并没有销毁在创建,你也可以理解为,当你手动在浏览器输入id值时,并没有点击回车键或搜索,浏览器就不会自动去搜索数据,总结出现的问题:路由地址变了,匹配的是同一个路由规则,所以组件没有更新

地址对比

 解决方案① key

在当前路由出口加上key属性值为路由的id

    <router-view :key="$route.fullPath"></router-view>

 我们配置了动态路由,并且给每个标题传了不同的id值 通过$route.fullpath就可以拿到传过去的id

 浅谈 key的作用

在之前我们只是给for绑定过key 并没有给其他元素绑定过key, key的作用可以更好的检测到是否要更新哪些部分,这就涉及到了diff算法,再生成真实dom前 会产生虚拟dom 也可以称为虚拟节点(vNode) 当数据发生改变后 通过vNode和oldvNode进行比较,判断哪些数据需要去更新,如果需要更新就把之前的元素删掉,换成最新的元素,如果不需要改变那就原封不动, 这也是diff算法的巧妙之处,话往回唠,通过 绑定:key=$route.params.id,只要fullpath的id发生变化  那么整个组件会进入创建销毁的过程,类似于v-if, 只要重新创建销毁 就会重新进行请求数据

 解决方案② watch

  // 二、监听id的变化进行请求数据
    watch(() => { return route.params.id }, () => {
      getData()
    }, { immediate: true })

watch还是比较好理解的了,只要监听id的变化就重新请求数据 而且深度监听后一开始会立即执行,省去了一开始调用函数去请求数据

watch使用的注意点: 

1. 监听对象里的属性 要用回调函数去监听

2.此处是vue3的用法 vue 语法略有不同

3.vue3中 使用watch记得先引用

4.重点!如果只请求一级类目的数据是没问题的,如果当请求二级类目的时候也使用监听,那么就会报错,原因:一级和二级都监听了路由id变化 只要有一个变 重新发请求时 就会把 一级和二级的路由id都会发生过去,

解决方案 ③ 路由钩子

   onMounted(() => {
      getData(route.params.id)
    })
    onBeforeRouteUpdate((to) => {
      console.log(to)
      getData(to.params.id)
    })

onBeforeRouteUpdate 路由钩子函数 注意 在参数里面不能写 route.params.id 因为代表路由更新前 所有每次拿路由id都是拿到的上一次的id,所有要用路由中的to参数 to参数可以看到前往哪的路径或参数,因为在初次没有请求 所以可以在onMounted钩子函数中 在创建的时候就调用一次 

总结

三个方法到底使用哪个呢?

第一种:使用起来简单 只需要加 :key='变化的值'  但是呢和v-if一样 都会进入组件创建销毁的过程 比较影响性能 如果你想快速完成工作就可以使用

第二种:watch 监听 个人感觉好理解 只要掌握watch监听的书写格式  就可以实现,只是重新请求数据 没有创建销毁 不损耗性能,(只限于一级类目标题简单,二级类目需要另加操作)

第三种:写起来感觉稍微繁琐 需要用到两个钩子  并且 要用到不同的参数,也不会重新创建 销毁组件

用哪个方法还要看自己 没有一个方法比较简单并且优化好一些的,

以上是关于vue项目中解决路由缓存组件不重新请求数据问题的主要内容,如果未能解决你的问题,请参考以下文章

解决vue项目 点击相同菜单栏页面不刷新

关于vue后退不刷新,并缓存原有状态,前进刷新并请求新数据

vue页面缓存,keep-alive第一次无效的解决方法

7.Vue_____keep-alive(结合路由)

vue: 关于多路由公用模板,导致组件内数组缓存问题

谈谈你对 keep-alive 的了解?