Vue运行时如何动态局部注册多个组件而非全局注册
运行时Vue组件局部注册实现方案
问题根源
你当前使用的Vue.component()是Vue提供的全局组件注册API,调用后注册的组件会在全站所有Vue实例中可用,必然造成全局命名空间污染。
Vue 2中组件的局部注册配置存储在实例的$options.components对象下,只需要将动态加载的组件注入到当前Display组件实例的这个配置对象中,就能实现组件仅在当前组件及其子树范围内可用的局部注册效果,不会产生全局污染。
修改后代码
直接调整Display.vue的逻辑即可,移除全局注册相关代码:
<template> <div> <component v-if="currentComponent" :is="currentComponent"></component> </div> </template> <script> export default { data() { return { currentComponent: null, } }, methods: { load(e) { // 遍历传入的组件,全部注入当前实例的局部组件配置 for (const key in e.components) { this.$options.components[key] = e.components[key]; } this.$nextTick(() => { this.currentComponent = e.components.container; // 若极端场景下提示组件未找到,可打开下面这行强制刷新 // this.$forceUpdate() }); }, }, created() { document.body.addEventListener('component-ready', this.load, false); }, beforeDestroy() { // 组件销毁时移除事件监听,避免内存泄漏 document.body.removeEventListener('component-ready', this.load, false); } } </script>
事件派发的代码不需要做任何修改,保持原有写法即可。
方案说明
- 全程不需要调用全局
Vue.component()方法,也不需要保留Vue的引入,不会产生全局注册的副作用 - 动态注册的组件作用域严格限制在当前Display组件实例及其下属子组件树内,组件树外的其他组件无法访问到这些动态组件
- 支持动态组件之间的互相引用:比如container组件内部模板使用header、body、footer组件时,Vue的组件解析逻辑会沿着父实例链查找已注册的局部组件,不会出现组件找不到的报错
- 新增了销毁阶段的事件监听移除逻辑,避免组件销毁后事件回调仍执行造成的内存泄漏问题
内容的提问来源于stack exchange,提问作者EaBengaluru
相关产品推荐
相关产品推荐

