虚拟dom-在js中动态创建销毁组件

代码例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import { createVNode, render } from 'vue';
import LableInput from './LableInput.vue';

const div = document.createElement('div')
div.setAttribute('id', 'LableInput')
//用来判断是否渲染组件,比如重复渲染
let flag=false;
//定义响应式数据,用来动态更新同一个组件dom的信息,也就是说外界调用这个函数时候,reactive定义的数据发生了改变,
//组件可以实验commputed或者watch来监听这个数据,绑定在显示dom上,从而实现动态更新数据
//也可以动态更新dom的位置,这里传入xy就是对应组件的position的xy位置
//dom绑定一个:style='position'即可,position使用计算属性,关联值就是传入的props的xy
const data=reactive({
x:1,
y:1,
num:0
})
export default (pos = [200, 200], value = '10',unit) => {
return new Promise((resolve) => {
const cb = (data) => {
flag=false//触发这个函数说明组件可以销毁了
resolve(data)
render(null, div)
};

const parent = document.getElementById('content');
parent.appendChild(div);

data.x=pos[0]
data.y=pos[1]
data.num=value

if(!status){
cb(false)
return
}

if( !flag && status ){
const v_node = createVNode(LableInput, {
pos: pos,
unit,
getDataCallback: cb,
});
render(v_node, div);
flag=true;
}
})
}

原理

在 Vue.js 中以编程方式创建和渲染一个组件,并且通过 Promise 机制处理组件的数据回调 。

  1. 创建容器元素:
1
2
const div = document.createElement('div')
div.setAttribute('id', 'LableInput')

这部分代码创建了一个 div 元素,并为它设置了 id 为 LableInput。这个元素将用来挂载我们的 Vue 组件。

  1. 导出一个函数:
1
2
export default (pos = [200, 200], value = '10') => {
return new Promise((resolve) => {}

这个函数默认接受两个参数 pos(位置)和 value(初始值),并返回一个 Promise,以便异步处理组件的结果。

  1. 定义回调函数:
1
2
3
4
const cb = (data) => {
resolve(data)
render(null, div)
};

定义了一个回调函数 cb,它接受数据 data 并执行 resolve(data) 来完成 Promise。同时,它调用 render(null, div) 来卸载组件,从而清理 DOM。

  1. 将容器添加到 DOM 中:
1
2
const parent = document.getElementById('content');
parent.appendChild(div);

找到一个父容器(这里假设 id 为 content),并将之前创建的 div 元素添加到该容器中。

  1. 创建并渲染虚拟节点:
1
2
3
4
5
6
const v_node = createVNode(LableInput, {
pos: pos,
value,
getDataCallback: cb,
});
render(v_node, div);

使用 createVNode 创建一个虚拟节点 v_node,并传入需要的属性和回调函数。然后调用 render 将虚拟节点渲染到 div 容器中。

意义

  1. 动态创建组件: 通过编程方式,可以在任何需要的地方动态创建组件,而不是依赖于模板中的静态定义。这对于需要根据用户操作或外部条件动态展示组件的场景非常有用。
  2. 组件与业务逻辑分离: 使用回调函数和 Promise,可以很好地将组件的内部逻辑与外部业务逻辑分离开来。组件完成任务后,通过回调函数传递数据,不需要直接操作外部状态。
  3. 自动清理: 在回调函数中卸载组件,确保组件在使用完成后被清理,避免内存泄漏和不必要的 DOM 元素。
  4. 参数灵活性: 函数参数提供了默认值,可以灵活地调整组件的初始状态和行为,而不需要在每次调用时都指定所有参数。
  5. 异步处理: 返回 Promise 使得函数调用可以使用 async/await 语法,从而简化异步处理流程,使代码更简洁易读。

综上所述,这段代码展示了一种优雅的组件创建和管理方式,适用于需要动态展示和交互的复杂应用场景。