页面渲染了一个 id 为 videoPlayerId 的div盒子,代码自定义了一个名为CustomComponent 的组件,现在需要在vue3中,通过纯 js 的方式将组件 CustomComponent 插入 videoPlayerId 的div中,作为其子节点。
CustomComponent 组件
<template>
<div>我是CustomComponent,接收到的参数是{{params}}</div>
<button @click="clickButton"></button>
</template>
<script setup>
const props = defineProps({
params: {
type: String,
default: ''
}
//监听按钮被点击
const clickButton = () => {
emits('clickButton')
}
const emits = defineEmits(['clickButton'])
})
</script>
待插入节点的页面代码
<template>
<div id="videoPlayerId"></div>
</template>
<script setup>
//将自定义组件插入div
const insertNode = () => {
const container = document.getElementById('videoPlayerId')
//创建一个文档碎片节点,插入它的所有子孙节点
const fragment = document.createDocumentFragment()
//创建自定义组件的应用对象,并挂在到文档碎片节点上
const pop = createApp(CustomComponent, {
params: "动态写入的参数",
//绑定的监听函数要在前面加 on,标识监听
onClickButton: () => clickButton(),
}).mount(fragment)
container.append(pop.$el)
}
onMounted(() => {
insertNode()
})
</script>
在真实且完整的业务场景中,videoPlayerId 的 div 会在点击按钮后,被别的地方动态清空,并写入新的代码,所以 CustomComponent 需要在 videoPlayerId 每次被刷新后都重新写入。
createApp + mount
相当于将 CustomComponent 创建为Dom,取其 $el 中的 dom 渲染到页面上,可以完美实现上述场景。
render
相当于将 CustomComponent 创建为 VDom,在 videoPlayerId 被刷新后不会重新渲染,因此只有在页面初始化时,才能成功将 CustomComponent 插入 videoPlayerId,videoPlayerI 被刷新后,render 不会被重新执行。