美文网首页前端开发那些事儿程序员
vue中渲染流程分析、归纳及总结

vue中渲染流程分析、归纳及总结

作者: 雪燃归来 | 来源:发表于2020-06-18 09:35 被阅读0次

       在零星碎片地学了vue中渲染流程的一些知识后,有必要对vue整个渲染流程做一次梳理,确保知识的连贯性。
       vue中的渲染流程主要有下面三个阶段。

       1、响应式:监听data属性getter setter
       2、模版编译:模版到 render函数,再到vnode
       3、vnode:初次渲染视图vnodepatch(elem,vnode)和更新视图patch(vnode,newVnode)

       首先我们来看一张图,通过这张图,我们来看一下vue中渲染流程的主要步骤。

完整流程图
       1、执行Component Render Function方法,生成Virtual DOM Tree.
       2、执行第一步的同时触发data中的getter
       3、收集依赖(Collect as Dependency)。在模板中使用了哪个变量,就把那个变量观察起来(Watcher),没有用到变量,不会被收集。
       4、如果通过data中的setter修改了data中的数据,就需要查看一下watcher中是否将这个变量观察起来。如果之前已经观察起来,就会触发re-render,重新生成Component Render Function,重新生成vdom(当然此过程会进行diff算法)。
       对整个流程梳理完成后,我们从每个阶段入手,逐个阶段的去理解这一渲染流程。

一、渲染流程分析

1、响应式:监听data属性getter setter

       这部分主要是对模版中用到的变量添加监听。我在文章《vue中响应式数据状态原理分析》中有过非常详细的分析以及实现,你可以点击文中链接进行学习。

2、模版编译:模版到 render函数,再到vnode

       模板不是html,有指令、插值、JS表达式,能够实现判断、循环。html是标签语言,只有JS才能实现判断、循环(图灵完备性)。因此,模版一定要转化成某种JS代码,即编译模版。模版编译为render函数,执行render函数返回vnode
       在学习这段内容的时候,要掌握with语法,我们简单的复习一下with的用法吧。

with 语法
1、改变{}内自由变量的查找规则,当作obj属性来查找。
2、如果找不到匹配的obj属性,就会报错。
3、with要慎用,它打破了作用域规则,易读性变差。

with 语法
       我们可以借助vue-template-compiler这个第三方库来体验一下,模版编译的过程。具体流程如下:
       1、安装环境
npm init -y
npm install vue-template-compiler

       2、编写测试文件(index.js)

const compiler = require('vue-template-compiler')
// 插值
const template = `<p>{{message}}</p>`
// 编译
const res = compiler.compile(template)
console.log(res.render)

       3、运行测试文件,获取render函数

node index.js

       运行的结果如下:

with(this){return _c('p',[_v(_s(message))])}

       是不是很熟悉,用到了我们前面学到的with语法。this就是vm示例,const vm = new Vue({}),_c,就是我们熟悉的createElement,对照vue源码定义的快捷方法,我们可以知道_v_s方法的含义,即创建文本节点和调用toString方法。

unction installRenderHelpers (target) {
    target._o = markOnce;
    target._n = toNumber;
    target._s = toString;
    target._l = renderList;
    target._t = renderSlot;
    target._q = looseEqual;
    target._i = looseIndexOf;
    target._m = renderStatic;
    target._f = resolveFilter;
    target._k = checkKeyCodes;
    target._b = bindObjectProps;
    target._v = createTextVNode;
    target._e = createEmptyVNode;
    target._u = resolveScopedSlots;
    target._g = bindObjectListeners;
    target._d = bindDynamicKeys;
    target._p = prependModifier;
  }

       这里我只是做了简单的插值模版,至于模版的其他用法,你可以自行尝试,主要的重点就是要理解render函数的生成原理以及内容。

3、收集依赖(Collect as Dependency)。在模板中使用了哪个变量,就把那个变量观察起来(Watcher)

       这部分主要实现了从vdom转化为真实DOMvnode新旧节点的对比的操作。我在之前的文章《虚拟DOM(Virtual DOM)中动态更新视图的diff算法》中有过仔细的讲解,你可以点击链接进行查看。

二、数据更改触发的渲染流程分析

1、初次渲染过程

       1、解析模版为render函数(或在开发环境已完成,vue-loader)。
       2、触发响应式,监听 data属性 getter setter
       3、执行render函数,生成vnodepatch(elem.vnode)

执行render函数会触发getter,但是模版中没有用到的变量不会触发getter

2、更新过程

       1、修改data,触发setter(此前在getter中已被监听)
       2、重新执行render函数,生成newVnode
       3、patch(vnode,newVnode)更新视图

       至此,文章结束,感谢您的阅读!

相关文章

网友评论

    本文标题:vue中渲染流程分析、归纳及总结

    本文链接:https://www.haomeiwen.com/subject/ndsyxktx.html