如何解决vue在相同页面中跳转路由,页面内容不更新的问题

2,735 阅读2分钟

问题:当几个页面渲染在同一个路由下,依靠id来改变页面时,页面地址改变了但是页面并没有变(视图没有更新)

问题解析: 虽然地址改变了,但是页面只会创建一次,不会再次去发送请求,setup只会执行一次,导致页面不会刷新

解决方法一:

给路由出口增加 key属性

<RouterView :key="$router.fullPath">

key的作用:判断虚拟dom是否要销毁重建的依据

公式:

render函数(数据) ===> 虚拟dom

render函数1(数据) ===> 虚拟dom1

render函数2(数据) ===> 虚拟dom2

vue会比较虚拟dom1 和 虚拟dom2的区别(diff算法),决定是否要更新页面(更新哪一部分)

key在diff算法工作时,用来比对虚拟dom1 虚拟dom2是都相同,

如果key相同,不更新

如果key不同,就一定要更新

优点:简单粗暴;

缺点:类似v-if销毁重建组件,会有一定的性能损耗;

解决方法二:

通过watch监听路由中id的变化,重新发送请求,因为页面创建时也要发送请求,加上第三个参数immediate:true ,立即执行即可

setup(){
  watch(()=>route.params.id,(newVal)=>{
    // 发送需要的请求
  },{immediate:true})
}

优点:没有销毁重建,从更底层的方式(侦听响应式数据的变化)去切入重发请求

缺点:代码量较多

解决方法三:

使用钩子函数 onBeforeRouteUpdate (只会在路由更改的时候执行)

首次创建的时候依旧要发送一次请求

注意:这里有一个坑点,在这个钩子函数中发送请求时要用它参数中的值去发送请求,(to.params.id)
若还是用之前的参数发请求,它会以上一次的参数发送请求,导致请求错乱
onBeforeRouteUpdate((to)=>{
  // 发送需要的请求
})

详细代码如下:

import { ref, onMounted } from 'vue'
import {useRoute, onBeforeRouteUpdate} from 'vue-router

setup(){
    const route = useRoute()
    const cate = ref({})
    const loadCategoryList = (id) => {
      // 获取当前数据
      findTopCategory(id).then(data => {
        cate.value = data.result
      })
    }
    // 页面创建时执行(直接从路由中获取id)
    onMounted(() => {
      loadCategoryList(route.params.id)
    })
    // 在路由跳转之后更新之前自动执行
    // beforeEach((to,from,next)=>{})
    onBeforeRouteUpdate((to) => {
      // to指代的是目标路由对象 to拿到最新的路由参数id
      // 使用最新id获取数据
      loadCategoryList(to.params.id)
    })

    return { cate }
}

优点:没有销毁重建,逻辑较为直观 缺点:代码量较多

vue2解决方法与上述相同