抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

Mr.wang

Time flies and people come and go

vue3.0的实践记录

vue3.0正式版发布(2020-09-18)

diff算法改变

在需要动态绑定的dom元素上绑定静态标记,渲染层只会比较绑定了静态标记点dom节点

1
2
3
4
5
6
7
8
9
10
11
<div id="app">{{ msg }}</div>
===========================
function render() {
with(this) {
return _c('div', {
attrs: {
"id": "app"
}
}, [_v(_s(msg))])
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
<div>Hello World!</div>
<div>{{msg}}</div>
===============================
import { createVNode as _createVNode, toDisplayString as _toDisplayString, Fragment as _Fragment, openBlock as _openBlock, createBlock as _createBlock } from "vue"

export function render(_ctx, _cache, $props, $setup, $data, $options) {
return (_openBlock(), _createBlock(_Fragment, null, [
_createVNode("div", null, "Hello World!"),
_createVNode("div", null, _toDisplayString(_ctx.msg), 1 /* TEXT */)
], 64 /* STABLE_FRAGMENT */))
}

// Check the console for the AST

flag标记值

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
const enum PatchFlags {
// 插值生成的动态文本节点
TEXT = 1,
// 动态class绑定
CLASS = 1 << 1,
// 动态绑定style,需要注意一点,如果绑定的是静态object,即object不会动态变化
// 将同样被当作静态属性来处理,静态属性声明会被提升到render函数体的最前端
// 减少不必要的属性创建开销
// e.g. style="color: red" and :style="{ color: 'red' }" both get hoisted as
// const style = { color: 'red' }
// render() { return e('div', { style }) }
STYLE = 1 << 2,
// dom元素包含除class、style之外的动态属性,或者组件包含动态属性(可以是class、style)
// 动态属性在编译阶段被收集到dynamicProps中,运行时做diff操作时会只对比动态属性的变化
// 省略对其他无关属性的diff(删除的属性无需关心)
PROPS = 1 << 3,
// 包含动态变化的keys,需要对属性做全量diff,该标志位和
// CLASS、STYLE、PROPS是互斥的,不会同时存在,有FULL_PROPS
// 上面提到的三个标志位会失效
FULL_PROPS = 1 << 4,
// 服务端渲染相关
HYDRATE_EVENTS = 1 << 5,
// 稳定的fragment类型,其children不会变化,元素次序固定,
// 如`<div v-for="item in 10">{{ item }}</div>`生成的fragment
STABLE_FRAGMENT = 1 << 6,
// fragment的children全部或部分节点标记key
KEYED_FRAGMENT = 1 << 7,
// fragment的children节点均未标记key
UNKEYED_FRAGMENT = 1 << 8,
// 不需要做props的patch,比如节点包含ref或者指令 ( onVnodeXXX hooks ) ,
// 但是节点会被当作动态节点收集到对应block的dynamicChildren中
NEED_PATCH = 1 << 9,
// 插槽相关
DYNAMIC_SLOTS = 1 << 10,
// 静态节点,由于被提升到render函数体最顶部,因此节点一旦声明就会维持在内存里
// re-render时就不需要再重复创建节点了,同时diff时会跳过静态节点,因为内容不发生任何变化
HOISTED = -1,
// 特殊处理,具体作用可看源码注释
BAIL = -2
}

评论