一,前言
上篇,主要介绍了数组数据变化的观测情况,涉及以下几个点:
- 实现了数组数据变化被劫持后,已重写原型方法的具体逻辑;
- 数组各种数据变化时的观测情况分析;
目前为止,数据劫持的各种情况就全部分析完了
本篇,Vue的数据渲染流程
二,如何渲染
1,代码回顾
数据初始化完成后,将开始进行视图渲染
export function initMixin(Vue) {
Vue.prototype._init = function (options) {
const vm = this;
vm.$options = options;
initState(vm);
if (vm.$options.el) {
// todo...
}
}
}
el 为 dom 挂载处,如:
<div id=app>{{message}}</div>
2,问题分析
Vue 不会直接操作字符串,可以想象一下:
- 从字符串中解析出指令,以及进行值更新是比较困难的
- 再考虑到节点复用的场景,更是无法通过对比字符串来完成
3,Vue 视图渲染
vue 支持 template 和 jsx:
- 日常开发中,大部分会采用 template 完成模板的编写,因为 template 即简单又方便;
- 而相比 template来讲,jsx 则加更灵活。写法上也显得稍微复杂一些;
三,渲染流程分析
1,流程分析
Vue 需要对 template 进行解析,从而将 template 模板语法转变为 javascript 语法;
而这个转化的过程,就需要用到 ast 语法树(可描述 css、js、html 等语法)
使用 ast 语法树来对 html 的语法结构进行描述,根据 ast 树形结构将代码重组为 js 语法
即后续对 html 模板的操作,就都可以通过 js 来完成,而不必考虑解析字符串了
2,Vue 模板编译原理
- 将 template 模板编译为 render 函数
- 通过 rander 函数再返回虚拟 dom
- 再通过 diff 算法比对虚拟 dom
流程:template模板 -> render 函数 -> 虚拟dom -> diff 算法
四,简单分析
https://template-explorer.vuejs.org/
- div 模板:最终被编译成为一个 render 方法,即 render 函数;
- _c 函数:相当于 createElement,创建div,内部包含属性 id ,值为 app;
- _v 函数:创建文本,即将_s(msg)创建为一个文本;
- _s 函数:相当于 JSON.stringify,如果吗模板参数msg为对象,通过 _s 使其转为 string
五,Vue 数据渲染的核心流程
1,初次渲染时
- template 模板被编译为 ast 语法树;
- 通过 ast 语法树生成 render 函数;
- 通过 render 函数返回 vnode 虚拟节点;
- 使用 vnode 虚拟节点生成真实 dom 并进行渲染;
2,视图更新时
- 调用 render 函数生成新的 vnode 虚拟节点;
- 通过 diff 算法对新老 vnode 虚拟节点进行对比;
- 根据虚拟节点比对结果,更新真实 dom;
六,结尾
本篇,主要介绍了 vue 数据渲染核心流程
下一篇,template 模板生成 ast 语法树