Appearance
html
<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>
js
// 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;
html
<async-component :path='`components/${treeData.compPath}.vue`' :mode='mode' :jsonParams='model'
@change='handleChange' :key='treeData.id' style='margin-bottom: 10px'></async-component>