Vue模板是怎么在浏览器中运行的

首先直接把模板丢到浏览器中肯定是不能运行的,模板只是为了方便开发者进行开发。Vue 会通过编译器将模板通过几个阶段最终编译为 render 函数,然后通过执行 render 函数生成 Virtual DOM 最终映射为真实 DOM。

这个编译过程其中又分为三个阶段,分别为:

  1. 将模板解析为 AST
  2. 优化 AST
  3. 将 AST 转换为 render 函数

在第一个阶段中,最主要的事情还是通过各种各样的正则表达式去匹配模板中的内容,然后将内容提取出来做各种逻辑操作,接下来会生成一个最基本的 AST 对象

{
    
    
	// 类型
	type: 1,
	// 标签
	tag,
	// 属性列表
	attrsList: attrs,
	// 属性映射
	attrsMap: makeAttrsMap(attrs),
	// 父节点
	parent,
	// 子节点
	children: []
}

然后会根据这个最基本的 AST 对象中的属性,进一步扩展 AST。
当然在这一阶段中,还会进行其他的一些判断逻辑。比如说对比前后开闭标签是否一致,判断根组件是否只存在一个,判断是否符合 HTML5 Content Model 规范等等问题。

接下来就是优化 AST 的阶段。在当前版本下,Vue 进行的优化内容其实还是不多的。只是对节点进行了静态内容提取,也就是将永远不会变动的节点提取了出来,实现复用 Virtual DOM,跳过对比算法的功能。在下一个大版本中,Vue 会在优化 AST 的阶段继续发力,实现更多的优化功能,尽可能的在编译阶段压榨更多的性能,比如说提取静态的属性等等优化行为。
最后一个阶段就是通过 AST 生成 render 函数了。其实这一阶段虽然分支有很多,但是最主要的目的就是遍历整个 AST,根据不同的条件生成不同的代码罢了。

NextTick 原理分析

nextTick 可以让我们在下次 DOM 更新循环结束之后执行延迟回调,用于获得更新后的 DOM。
Vue实现响应式并不是数据发生变化之后DOM立即变化,而是异步执行DOM更新的。

  1. vue是异步执行dom更新的,一旦观察到数据变化,vue就会开启一个队列,然后把在同一事件循环当中观察到数据变化的watcher推送进这个队列,如果这个watcher被触发多次,只会被推送到队列一次,这种缓冲行为可以有效的去掉重复数据造成的不必要的计算和dom操作,这样可以提高渲染效率。
  2. 如果要获取更新后的dom元素,可以使用vue内置的$nextTick方法,参数是一个函数。它的作用类似setTimeout,进行执行异步的操作。

异步执行的运行机制是什么样的?阮一峰老师是这样总结的:

(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的第三步。

主线程不断执行任务、获取任务、执行任务……的过程叫做事件循环

vue异步更新的原理:

1.修改 Vue 中的 Data 时,就会触发所有和这个 Data 相关的 Watcher 进行更新。
2.首先,会将所有的 Watcher 加入队列 Queue。
3.然后,调用 nextTick 方法,执行异步任务。
4.在异步任务的回调中,对 Queue 中的 Watcher 进行排序,然后执行对应的 DOM 更新。

猜你喜欢

转载自blog.csdn.net/Beth__hui/article/details/114086493
今日推荐