<template>
  <keep-alive v-if="keepAlive">
    <component
      @change='handleChange'
      :is="currentView"
      v-bind="$attrs"
      v-on="$listeners"/>
  </keep-alive>
  <component
    v-else
    @change='handleChange'
    :is="currentView"
    v-bind="$attrs"
    v-on="$listeners"/>
</template>
<script>
import factory from './factory';
export default {
  name: 'AsyncComponent',
  inheritAttrs: false,
  props: {
    path: {
      type: String,
      required: true,
      default: () => null,
    },
    keepAlive: {
      type: Boolean,
      default: true
    },
    delay: {
      type: Number,
      default: 20,
    },
    timeout: {
      type: Number,
      default: 2000
    }
  },
  data() {
    return {
      currentView: this.load
    };
  },
  methods: {
    load() {
      this.currentView = resolve => factory(this.path, this.delay, this.timeout)
    },
    handleChange(data){
      // 统一通过change事件进行回传
      this.$emit('change', data)
    }
  },
  watch: {
    path(){
      this.load();
    }
  }
};
</script>
// Error和Loading随意自定义即可
import Error from './Error';
import Loading from './Loading';

const factory = (path, delay, timeout) => ({
  component: import(`@/${path}`),
  loading: Loading,
  error: Error,
  delay,
  timeout,
});
export default factory;
<async-component :path='`components/${treeData.compPath}.vue`' :mode='mode' :jsonParams='model'
                       @change='handleChange' :key='treeData.id' style='margin-bottom: 10px'></async-component>

# To Be Continued!😎

Last Updated: 3/23/2022, 12:00:13 PM