vue源码解读--optimize

目录导航

本节示例代码如下

vue源码解读--optimize_第1张图片

经过之前分析,每一个ast元素节点都有一个type,1为元素节点、2为表达式节点、3为文本节点。调用optimize函数,入参为:ast节点

vue源码解读--optimize_第2张图片

    调用genStaticKeysCached,这其实是执行cache的返回值,即cachedFn函数

vue源码解读--optimize_第3张图片

                其入参为genStaticKeys

vue源码解读--optimize_第4张图片

               因此,genStaticKeysCached拿到的是cacheFn函数,并在调用时执行genStaticKeys,故拿到的值实际上是makeMap的返回值,入参实际上是我们在生成ast节点时打的标记。该函数将返回一个匿名函数

vue源码解读--optimize_第5张图片

              故genStaticKeysCached拿到的是一个匿名函数,该匿名函数将用来判断是否具有某个key

    同理,isPlatformReservedTag也是返回一个匿名函数,用于判断是否是保留的标签

    调用markStatic,传入ast树

vue源码解读--optimize_第6张图片

                调用isStatic判断是否是静态节点

vue源码解读--optimize_第7张图片
(可以看到,当type为2时说明元素上有表达式,是可变的;3是纯文本节点;另外如果节点上有if、for、hasBindings标记时说明也是可变的;并且不能是自定义组件)

                显然对于当前main标签而言,满足条件,故将node.static标记为true

                main为元素节点,type为1,故进入判断,执行到框红的位置,对其子节点进行遍历,即对ul和li进行遍历,递归的执行第一步和第二步,那么对于ul而言,当第一次执行到该处时将获取到li元素并对其调用markStatic,当li执行到该处后,拿到其子节点{v}并再一次markStatic,本次其type为2,故node.static=false。代码向下执行到框绿的位置,将其父节点标记为false,那么在回溯的过程中,整个main元素的static都为false

(故markStatic是深度遍历的过程,原则就是只要子节点有一个是动态的。那么整个节点都是动态的)

    调用markStaticRoots

vue源码解读--optimize_第8张图片

                可以看到,该函数只对元素节点做处理,我们的main、ul、li、br、div均为元素节点

                上一步我们已经将其标记为false,故本次会直接走到else,将staticRoot标记为false

                接着对自节点进行处理,并尝试将其标记为true。显然与ul同级的br和div将被标记staticRoot为true

    (故markStaticRoots实际上做进一步标记,这样在生成代码的过程中就不需要再次比对)

你可能感兴趣的:(vue源码解读--optimize)