Vue源码剖析-虚拟DOM
课程回顾
- 虚拟DOM库-Snabbdom
- Vue.js响应式原理模拟实现
- Vue.js源码-响应式原理
虚拟DOM概念回顾
什么是虚拟DOM
- 虚拟DOM(Virtual DOM)是使用JavaScript对象描述真实的DOM
- Vue.js中的虚拟DOM借鉴Snabbdom,并添加了Vue.js的特性
- 例如:指令和组件机制
为什么要使用虚拟DOM
- 避免直接操作DOM,提高开发效率
- 作为一个中间层可以跨平台(服务端渲染)
- 虚拟DOM不一定可以提高性能
- 首次渲染的时候会增加开销
- 复杂视图情况下提升渲染性能
代码演示
- Vue中的h函数,相对于snanbbdom中的h函数,支持传入插槽和组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="app">
<p ref="P1">{
{
msg}}</p>
</div>
<!-- 完整版本 -->
<script src="../../dist/vue.js"></script>
<script>
const vm = new Vue({
el: "#app",
render(h) {
const vnode = h("h1", {
attrs: {
id: "title" } }, this.msg);
console.log(vnode);
return vnode;
},
data: {
msg: "Hello Vue",
},
});
</script>
</body>
</html>
h函数用法
- vm.$creteElement(tag,data,children,normalizeChildren)
- tag:标签名或组件名称
- data:描述tag,可以设置DOM的属性或者标签的属性
- children:tag中的文本内容或者子节点
h函数的返回结果-vnode
- Vnode的核心属性
- tag
- data
- children
- text
- elm :记录vnode转换成的真实dom
- key: 复用当前的元素
整体分析过程
VNode的创建过程-createElement-上
- render函数内部的h函数就是createElement,有两种情况
- 把template模板转换成render函数时,render函数内部会使用_c
- 当直接写的render函数(不是template转变过来的),render函数内部使用$createElement
// 当把template模板转换成render函数时,render函数内部会使用_c
vm._c = (a, b, c, d) => createElement(vm, a, b, c, d, false)
// normalization is always applied for the public version, used in
// user-written render functions.
// 当直接写的render函数(不是template转变过来的),render函数内部使用$createElement
vm.$createElement = (a, b, c, d) => createElement(vm, a, b, c, d, true)
createElement函数的作用是处理参数,,因为我们调用h参数的时候既可以传递两个参数,也可以传递三个参数,而真正创建Vnode是在_createElement函数中完成
// createElement函数的作用是处理参数,,因为我们调用h参数的时候既可以传递两个参数,也可以传递三个参数
// 而真正创建Vnode是在_createElement函数中完成
export function createElement (
context: Component, // vm实例
tag: any, // 标签
data: any,