遇到问题的场景:需要把当前组件完全还原成初始化状态,不要页面全部刷新。当前问题的产生原因,是由于同一页面加载多个相同的子组件,造成多个父子组件间的操作,比如:增加、修改、删除等影响几个页面,需要刷新父页面来更新所有初始化数据

其他办法:

使用vue-router重新定向到当前页面,页面不刷新
使用window-reload(),页面全部刷新,用户体验太差

解决方法:

使用v-if provide inject和this.$nextTick()【版本限制 vue2.2.0】

原理:

使用v-if控制router-view的显示或隐藏(v-if会把事件监听器和自组件适当的销毁或者重建)
使用provide / inject组合解决自组件层级比较深的问题
使用this.$nextTick()实现页面异步刷新

provide / inject

就是父组件中使用provide提供变量(对象或者是一个函数),在子组件中通过inject来注入变量
不管层级有多深,并在起上下游关系成立的时间始终生效

this.$nextTick()

当dom发生变化,更新后执行的回调

实际代码:

在父组件里,声明reload方法,然后通过provide把reload方法注入,使用bol值控制router-view隐藏(销毁),再通过this.$nextTick()在dom更新之后利用bol控制router-view重新加载,实现页面刷新的效果

<template>
  <div class="hpage">
    <reply_word v-if="reply_word_if"></reply_word>
  </div>
</template>

<script>
  // 省略组件引入代码
  export default {
    provide() {
      return {
        reload: this.reload
      }
    },
    data() {
      return {
        reply_word_if: true
      }
    },
    methods: {
      async reload() {
        this.reply_word_if = false
        await this.$nextTick()
        this.reply_word_if = true
      }
    }
  }
</script>

在子组件里面
使用inject注入App.vue提供的reload依赖,然后在需要的地方直接调用this.reload()方法即可

export default {
    inject: ['reload'],
    methods: {
      async reload() {
        this.reply_word_if = false
        await this.$nextTick()
        this.reply_word_if = true
      },
      handleClick(tab, event) {
      }
    }
  }

Vue提倡数据驱动dom,但是存在特殊情况,如果有更好的解决方法,请多多指教!

标签: vue