第二次跳转到同一页面中 页面不刷新

情景再现:

第二次跳转到同一页面中 页面不刷新

数据刷新 但是页面不渲染

在这里插入图片描述


代码:

info-catalog页面
<template>
  <div class="info-catalogue-index">
    <div class="left-catalogue">
      <el-tree :data="catalogData" :props="catalogProps" accordion @node-click="handleNodeClick"></el-tree>
    </div>
    <div class="right-news">
      <keep-alive>
        <router-view></router-view>
      </keep-alive>
    </div>
  </div>
</template>
    // 节点被点击时的回调
    handleNodeClick (val, node, el){
      console.log('handleNodeClick-id', node.data.treeId)
      this.$router.push({
        path:'/news',
        query:{
          treeId: node.data.treeId
        }
      })
    }
news页面
<template>
  <div class="news">{{treeId}}</div>
</template>
  created (){
    console.log('query-id-c', this.$route.query.treeId)
    this.treeId = this.$route.query.treeId
  }

原因:

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

解决方法:
参考来源

方法一:监听路由变化,当有变化时刷新页面(验证过的)

 watch:{
    // 监听route变化 query改变时 更新id
    $route (to, from){
      if(this.$route.query.treeId!==this.treeId){
        this.init()
      }
    }
  }
 methods:{
    init (){
      console.log('query-id-c', this.$route.query.treeId)
      this.treeId= this.$route.query.treeId
    }
 }

注意:

1.该方案可以在监听方法中完成希望在vue生命周期初始化过程中的业务逻辑,加载相关的数据;可以实现页面重新
加载数据效果,但是滚动条并未重置,因此需要对滚动条进行重置处理;

2.当页面刷新后,此时会认为路由并未发生改变,虽然此时watch中的$route或者beforeRouteUpdate 路由监听均
视作无变化,但是会正常执行生命周期,因此不存在刷新出错的问题;

方法二:给路由添加唯一key

如果想强制刷新,可以在根路由上为其分配一个唯一key。采用$route.fullpath作为其唯一key。这样vue
就回认为内部路由每个都是不同的路由,在跳转时便会强制刷新组件
// layout.vue
<template>
  <div class="mk-container">
    <!-- <mk-header class="mk_nav_header"></mk-header> -->
    <keep-alive>
      <router-view class="mk_nav_content" v-if="$route.meta.keepAlive" :key="$route.fullPath"></router-view>
    </keep-alive>
    <router-view class="mk_nav_content" v-if="!$route.meta.keepAlive" :key="$route.fullPath"></router-view>
    <!-- <mk-footer class="mk_nav_footer"></mk-footer> -->
  </div>
</template>

//test.vue

methods: {
    /**
     * @description: 同路由携带不同参数跳转
     * @param {type}
     * @return:
     */
    sameRouteSkip() {
      this.$router.push({
        path: "/mk_gsui",
        query: {
          id: Math.ceil(Math.random()*100)
        }
      });
    },
}

方法三: provide和inject结合使用-利用v-if原理重载路由

思路 : 通过v-if 对进行摧毁和重建,强行使页面进行重新渲染,感谢大佬的分享的方法,哈哈!
// app.vue
<template>
  <div id="app" v-if="routerAlive">
    <router-view></router-view>
  </div>
</template>
<script>
export default {
  name: "App",
  data() {
    return {
      routerAlive: true
    };
  },
  provide() {
    return {
      routerRefresh: this.routerRefresh
    };
  },
  created() {},
  methods: {
    /**
     * @description: 路由销毁重建(解决跳转同一路由不刷新问题)
     * @param {type} 
     * @return: 
     */
    routerRefresh() {
      this.routerAlive = false;
      this.$nextTick(() => {
        this.routerAlive = true;
      });
    }
  }
};
</script>

//payOrderList.vue

export default {
  // import引入的组件需要注入到对象中才能使用
  components: {},
  inject: ["routerRefresh"], //在子组件中注入在父组件中创建的属性
  data() {
    // 这里存放数据
    return {
      activeTab: 0,
      payStatus: 0,
      list: []
    };
  },
  //使用beforeRouteUpdate 导航位置监听路由变化;对路由销毁重建
  beforeRouteUpdate(to, from, next) {
    this.routerRefresh(); //路由销毁重建方法
    next();
  },
  // 生命周期 - 创建完成(可以访问当前this实例)
  created() {
    this.$nextTick(() => {
      this.onRefresh("init");
    });
  },
  // 方法集合
  methods: {
    /**
     * @description: 跳到交费查询界面
     * @param {type}
     * @return:
     */
    goPaiedRecord() {
      this.$router.push({
        path: "/payOrderList",
        query: {
          payStatus: 1
        }
      });
    },
  }
};

使用beforeRouteUpdate 导航位置监听路由变化,使用从父组件注入的方法进行路由的销毁重建,完美解决这个问题!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值