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

67 篇文章 7 订阅
25 篇文章 2 订阅

目录

场景:

 解决方案① key

 浅谈 key的作用

 解决方案② watch

 解决方案 ③ 路由钩子

总结


场景:

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

当点击标题时只有我们通过<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都会发生过去,

解决方案有很多种 找出路由的规律

在监听的时候 判断一下路由中的matched 数组[1]中 的path 是否为当前要请求的路径 如果是 再去发请求 ,此时matched中的路径正式定义路由时的路径

    watch(() => { return route.params.id }, () => {
      if (route.matched[1].path === '/category/:id') {
        console.log('一级类目变化')
        getData()
      }
    }, { immediate: true })

 解决方案 ③ 路由钩子

   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监听的书写格式  就可以实现,只是重新请求数据 没有创建销毁 不损耗性能,(只限于一级类目标题简单,二级类目需要另加操作)

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

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

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值