vue 项目中不同路由且同一组件识别

当页面切换到同一个路由但不同参数的地址时,组件的生命周期钩子不会重新触发。

这是因为vue-router会识别出两个路由使用的是同一个组件从而进行复用,并不会重新创建组件,因此组件的生命周期钩子自然也不会触发。

组件本质是一个映射关系,所以先销毁再重建一个相同的组件会存在很大程度的性能浪费,复用组件才是正确的选择。但是这也意味着组件的生命周期钩子不会再被调用。


有三个方法来解决这个问题:

  • 路由导航守卫beforeRouteUpdate

vue-router提供了导航守卫beforeRouteUpdate,该守卫在当前路由改变且组件被复用时调用,所以可以在组件内定义组件导航守卫来解决这个问题。在vue-router2.2之后的版本可以使用。

export default{
   data(){
       return {}
  },
   beforeRouteUpdate(to,from,next){
        console.log(to,from,next)
        if(to.fullPath != from.fullPath){
            next()
            // 对路由变化作出响应
            // this.changeUser()
        }
    },
    methods:{}  
}
  • 观察$route对象的变化

通过watch可以监听到路由对象发生的变化,从而对路由变化作出响应。例如:

watch: {
    '$route' (to, from) {
        // 对路由变化作出响应
        
    }
}

这种方式也可以解决上述问题,但代价是组件内多了一个watch,这会带来依赖追踪的内存开销。
如果最终选择使用watch解决这个问题,那么在某些场景下推荐在组件里只观察自己需要的query,这样有利于减少不必要的请求。

watch: {
    '$route.query.id' () {},
    '$route.query.page' () {}
}
  • 为router-view组件添加属性key

这种做法非常取巧,非常“暴力”,但非常有效。它本质上是利用虚拟DOM在渲染时通过key来对比两个节点是否相同的原理。通过给router-view组件设置key,可以使每次切换路由时的key都不一样,让虚拟DOM认为router-view组件是一个新节点,从而销毁组件,然后再重新创建新组件。即使是相同的组件,但是如果url变了,key就变了,Vue.js就会重新创建这个组件。

因为组件是新创建的,所以组件内的生命周期会重复触发。实例如下:

这种方式的坏处很明显,每次切换路由时组件都会被销毁并且重新创建,非常浪费性能。其优点更明显,简单粗暴,改动小。为router-view组件设置了key之后,立即就可以看到问题被解决了。

文章内容摘抄自《深入浅出Vue.js》

你可能感兴趣的:(vue.js,前端)