今天突然遇到一个需求,需要在vue中动态注册组件,具体需要实现什么效果呢?
- 根据某个参数 动态的注册组件,注意,是注册组件哦,不是vue内部预设的这种
<component :is='xxx' />
我们知道,在vue内部,有动态组件,动态组件会异步加载,在需要用到这个组件的时候才会去加载这个组件,就像这样利用箭头函数加上import:
component: () => import("../views/Home.vue")
但是有些时候我们并不知道到底需不需要注册这个组件,因为当前需要加载的组件可能是在不同的文件夹下,由不同的人开发的,如果把所有的这些需要异步加载的组件全部用上面这种异步加载的方式来引入的话,就会特别臃肿,而且路径也非常混乱
这时候,我们只需要写一个公共组件,这个组件接收以下参数:
1.当前需要加载的组件的名字
2.当前需要加载的组件的路径
并且我们还要做好异常捕获 这样在当前所需注册的动态组件路径不对时 不会出现报错
话不多说 上代码!
<template>
<div>
<div v-if="hasComponent">
<component :is="name + type" v-bind="$attrs" />
</div>
</div>
</div>
</template>
<script>
export default {
props: {
type: {
type: String,
required: true
},
componentName: {
type: String,
required: true
}
},
methods: {
hasComponent(name) {
let status = true
try {
const component =
require(`../../${this.componentName}/plugin/${name}/${name}${this.type}.vue`).default
this.$options.components[name + this.type] = component
} catch (err) {
status = false
}
return status
}
}
}
</script>
\
上述这段代码用到了require,这个方法会被webpack处理,它会返回引入文件,因为再vue2中的组件都是以export default的形式导出的,所以我们在require后还要加一个.default
这里注意 一定要用try catch包起来,这样当引入失败时不会影响接下来的任务
这里的this.$options可以把它理解为vue组件中export default导出的这个对象,这个对象的.component就是我们在组件中注册子组件的地方,在上面的代码中,我们把动态引入的组件注册到component对象中,我们在异步组件(component :is='xxx')中就可以使用这个组件了