跳转同一路由但是参数不同,组件不刷新的问题

2,524 阅读2分钟

一、发现问题

当我在完成模仿网易云项目中的MV模块时, 不同的MV都是用到MV详情组件,只是根据不同MV的id,路由不同,组件中渲染的内容不同而已。

当我在一个MV的详情页面,通过里面的相关推荐去到另一个MV中时。

正常来讲应该是当前我的路由是/mv/details?id=123456,点击另一个MV则路由变为/mv/details?id=654321,此时页面应该要刷新,页面内容从id为123456的MV变成关于id为654321MV的内容。

但是呢,只有路由改变没有组件数据没有更新,还是旧的MV信息。

二、原因

vue官网详细解释说明使用同一路由携带不同参数,本质上是重用相同的组件实例,默认在跳转路由时会采用缓存策略,并不会刷新当前路由组件,因此不会调用组件的生命周期挂钩。

三、解决问题

由于我这个渲染MV详情的组件是一个子组件,所以一开始我查解决方法的时候使用的是。

provide和inject结合使用,利用v-if原理重载路由

通过v-if 对进行摧毁和重建,强行使页面进行重新渲染

1、父组件

<template>
    <div>
    	<router-view v-if="isRouterAlive" ></router-view>
    </div>    
</template>
<script>
export default{
 //父组件暴露出来的一些方法属性之类
  provide () {
	return {
           //把父组件的reload方法暴露出来
      		reload: this.reload
     }
    },
   data(){
        return{
            isRouterAlive: true
        }
    },
    methods:{
        //这是要暴露给子组件的方法,用来刷新子组件
         reload () {
      		this.isRouterAlive = false
             this.$nextTick(() => (this.isRouterAlive = true))
    	}   
    }
}
</script>

2、子组件

//接收父组件暴露出来的reload方法
inject: ['reload'],
methods:{
    ...
    //这是从当前mv去其他mv调用的函数,传递了要去mv的id,这样才能定义路由嘛
    toOtherMV(id){
         this.$router.push(`/mv/detail?id=${id}`)
     //在刷新一下组件
        this.reload()
	}
}

是不是很完美?你以为这就完事了嘛?

这样确实可以解决上面的问题,但是呢,当你点击左上角返回箭头从id为654321的MV详情回来id为123456的MV时候,组件还是不会刷新。只能说上面只是完成了前进的部分。

那么后退该怎么办呢?

简单,在子组件中监听路由的变化当路由变化则刷新组件,在toOtherMV函数中只要修改路由就好了。

子组件

watch: {
    // 监听路由变化
    $route (to, from) {
      // 组件刷新
      this.reload()
    }
 },
//接收父组件暴露出来的reload方法
inject: ['reload'],
methods:{
    ...
    //这是从当前mv去其他mv调用的函数,传递了要去mv的id,这样才能定义路由嘛
    toOtherMV(id){
         this.$router.push(`/mv/detail?id=${id}`)
	}
}

当当当!这样就解决了,跳转同一路由但是参数不同,组件不刷新的问题!