前言
目前工作还是以 Vue2
为主,今早有人提问 如何动态挂载组件?
话说很久很久以前就实现过,今天再详细的整理一下此问题!
开始
动态组件如下,是个简单的例子:
- 但请注意这里给了个
id="test2"
; - 可传入
props
参数name
;
// 文件名 AComponents.vue
<template><h1 id="test2">这是 A 组件.{{name}}</h1>
</template>
<script>
export default {props: {name: {type: String,default: ''}}
}
</script>
重点来了:
- 方法
addNode
创建节点; - 方法
extendComponent
挂载组件,使用 全局 API Vue.extend 和 实例方法vm.$mount ; - 方法
destoryComponent
销毁组件,注意是寻找id
为test2
,因为test
已被替换;
<template><div class="extend-main"><button @click="addNode">创建节点</button><button @click="extendComponent">挂载组件</button><button @click="destoryComponent">销毁组件</button></div>
</template>
<script>
import Vue from 'vue'
import AComponents from './../components/AComponents.vue'
export default {methods: {// 创建节点addNode() {// body 最后创建一个 id 为 test 节点const divEl = document.createElement('div');divEl.id = 'test';document.body.appendChild(divEl);},// 挂载组件extendComponent() {// 使用基础 Vue 构造器,创建一个“子类”const AComponentsEx = Vue.extend(AComponents);// 创建实例,并挂载到指定 id 上const aComponents = new AComponentsEx().$mount('#test');// 可传入 props 值aComponents.$props.name = '这是一个测试!';},// 销毁组件destoryComponent() {// 注意此时没有 id 为 test 的节点,已被 id test2 替换const testEl = document.getElementById('test2');document.body.removeChild(testEl); }}
}
</script>
效果
点击按钮 创建节点,body 新增 div。
点击按钮 挂载组件,新组件已替换。
点击按钮 销毁组件,div 被删除。
最后
2024年
是 Vue3
的时代!上述的挂载组件,Vue2
和 Vue3
是有差异的:
Vue2
被渲染的内容会替换我们要挂载的目标元素;Vue3
被渲染的应用会作为子元素插入,从而替换目标元素的 innerHTML。- 详见《Vue 3 迁移指南 - Mount API 的变化》