1. createElement 方法
HTML 中常见的 DOM 操作是,修改 DOM 节点,访问 DOM 节点。除此之外,W3C 还发布了创建 DOM 节点、删除 DOM 节点的技术标准。createElement 方法,被用于创建一个 DOM 节点。createElement() 通常需要与 appendChild() 或 insertBefore() 方法配合使用。其中:
- appendChild() 方法,用来在指定的子节点列表末,插入新的节点。
- insertBefore() 方法,用来在指定的已有子节点之前,插入新的节点。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<div id="parentElement">
<span id="childElement">子节点</span>
</div>
<button onclick="myFunction()">点我新增子节点</button>
<script>
function myFunction(){
var btn = document.createElement("BUTTON");
var text = document.createTextNode("新增加的按钮");
btn.appendChild(text);
var exist_node = document.getElementById("childElement");
document.getElementById("parentElement").insertBefore(btn, exist_node);
//window.document.body.appendChild(btn);
};
</script>
</body>
</html>
|
2. Vue 自定义渲染
在 Vue 中有两种渲染页面的写法:
1
2
3
4
5
6
7
8
9
10
11
|
// 使用 template
new Vue({
template: '<div>{{ hi }}</div>'
})
// 使用 render 方法
new Vue({
render (h) {
return h('div', this.hi)
}
})
|
实际上,在 Vue 调用 mounted 方法时,会将 template 编译成 render 方法。使用 template
的渲染效率没有使用 render
效率高。Vue 的渲染与 W3C 的 createElement 方法功能上类似。Vue 中也有 createElement 方法。不同于 W3C 的 createElement 方法,Vue 中的 createElement 方法不是直接对 DOM 进行操作,而是操作 VNode。
3. Vue 中的 h 方法
Vue 中的 h 方法是 createElement 方法的缩写。首先分析一下,Vue 中是如何渲染的:Vue 中使用 _render
将一个实例渲染成 VNode。在 _render
中主要的处理逻辑是:
1
|
vnode = render.call(vm._renderProxy, vm.$createElement)
|
可以看到,Vue 将 vm.$createElement 传递给了 render 方法。而 createElement
方法又是对 _createElement
方法的封装。
1
2
3
4
5
6
7
|
_createElement (
context: Component,
tag?: string | Class<Component> | Function | Object,
data?: VNodeData,
children?: any,
normalizationType?: number
)
|
这里的 context 是 VNode 的上下文环境。这样就能理解 createElement 方法或者说 h 方法的参数列表了。
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
|
// @returns {VNode}
createElement(
// {String | Object | Function}
// 一个 HTML 标签字符串,组件选项对象,或者
// 解析上述任何一种的一个 async 异步方法,必要参数。
'div',
// {Object}
// 一个包含模板相关属性的数据对象
// 这样,您可以在 template 中使用这些属性。可选参数。
{
// (详情见下一节)
},
// {String | Array}
// 子节点 (VNodes),由 `createElement()` 构建而成,
// 或使用字符串来生成“文本节点”。可选参数。
[
'先写一些文字',
createElement('h1', '一则头条'),
createElement(MyComponent, {
props: {
someProp: 'foobar'
}
})
]
)
|
4. 参考
- https://cn.vuejs.org/v2/guide/render-function.html
- https://ustbhuangyi.github.io/vue-analysis/