如何在Vue中实现单个组件的动态重新加载?

单个组件动态重新加载,指的是让某个已经渲染的组件,自动销毁然后开始一个新的生命周期。

组件动态重载

大部分情况下,一个需求会很多种实现方法,而接下来要说明的方法,也是众多解决方法之一。

1. 业务场景

到目前为止,遇到过两个需要实现这种功能的需求:

1. 后台管理系统中,对页面的功能区域(导航栏、侧边栏之外的区域)进行局部刷新

简单一点的功能页面,或许只需要重新加载接口,触发一下数据更新就够了,但是某些复杂的页面通过更新数据来重载状态,是远不如重新渲染组件来的方便的。

2. 让一个弹出式的Canvas画布,在依赖的图片源改变时重置,图片未改变时保持不变。

首先这个Canvas组件是通过v-if来实现弹出和关闭的,图片源不变的情况下,关闭再弹出组件是没有变化的,图片源改变的情况下,弹出的组件是初始状态。

2. 代码

通过外部传入的值进行刷新,指定的props改变时重载:

<script>
// 假设 AiPlusComponent 是你要使用的 ai-plus 组件
import AiCanvasPlus from '../canvas/plus.vue';

/* 组件 */
let component = null;
let name = null;

export default {
  name: 'keep',
  props: {
    name: {
      type: String,
      required: true
    }
  },
  render(h) {

    /* 不加载缓存 */
    if (this.name !== name && component) {
      if (component.componentInstance) {
        component.componentInstance.$destroy();
      }
      component = null;
    }

    /* 保存name */
    name = this.name;

    if (!component) {
      component = h(AiCanvasPlus, {
        key: this.name
      });
      component.data.keepAlive = true
      return component;
    } else {
      return component;
    }
  }
};
</script>

子组件内部触发,触发自定义事件时自动重载:

<script>
// 假设 AiPlusComponent 是你要使用的 ai-plus 组件
import AiCanvasPlus from '../canvas/plus.vue';

/* 组件 */
let component = null;
let name = null;

export default {
  name: 'keep',
  data() {
    return {
      name: 'ai'
    }
  },
  render(h) {

    /* 不加载缓存 */
    if (this.name !== name && component) {
      if (component.componentInstance) {
        component.componentInstance.$destroy();
      }
      component = null;
    }

    /* 保存name */
    name = this.name;

    if (!component) {
      component = h(AiCanvasPlus, {
        key: this.name,
        onReload(name) {
          this.name = name;
        }
      });
      component.data.keepAlive = true
      return component;
    } else {
      return component;
    }
  }
};
</script>