目录
1.回顾学过的知识
- 响应式:监听 data 属性 getter setter(包括数组)
- 模板编译:模板到 render 函数,再到 vnode
- vdom:patch(elem, vnode) 和 patch(vnode, newVnode)
2.组件渲染/更新过程
- 初次渲染过程
- 更新过程
- 异步渲染
2.1初次渲染过程
- 解析模板为 render 函数(或在开发环境已完成,如:vue-loader)
- 触发响应式,监听 data 属性 getter setter
- 执行 render 函数,生成 vnode,patch(elem, vnode)
执行 render 函数会触发 getter
<p>{
{ message }}</p>
<script>
export default {
data() {
return {
message: 'hello', // 会触发 getter
city: '北京' // 不会触发 getter,因为模板没用到,即和视图没关系,改变时,也不会触发setter
}
}
}
</script>
2.2更新过程
- 修改 data,触发 setter(此前在 getter 中已被监听)
- 重新执行 render 函数,生成 newVnode
- patch(vnode, newVnode)
2.3异步渲染
- 回顾 $nextTick
- 汇总 data 的修改,一次性更新视图
- 减少 DOM 操作次数,提高性能
<script>
export default {
name: 'app',
data() {
return {
list: ['a', 'b', 'c']
}
},
methods: {
addItem() {
this.list.push(`${Date.now()}`)
this.list.push(`${Date.now()}`)
this.list.push(`${Date.now()}`)
// 1. 异步渲染,$nextTick 待 DOM 渲染完再回调
// 2. 页面渲染时会将 data 的修改做整合,多次 data 修改只会渲染一次
this.$nextTick(() => {
// 获取 DOM 元素
const ulElem = this.$refs.ul1
// eslint-disable-next-line
console.log( ulElem.childNodes.length )
})
}
}
}
</script>
3.总结
- 渲染和响应式的关系
- 渲染和模板编译的关系
- 渲染和 vdom 的关系