接下来的几篇文章焦点放到Vue
的指令处理上,我们知道Vue
内置了一些指令,比如常用的v-for
、v-if
等。这篇文章会先从整体上讲述对指令的处理,不会涉及具体指令的细节。
parse
阶段
依然是从parse
阶段开始,在src/compiler/parser/index.js
中,会调用各个指令的processXXX
:
1 | // 处理v-pre指令, 如<span v-pre>{{ this will not be compiled }}</span> |
processElement
函数处理 ref
、slot
、is
、自定义指令以及其他所有普通属性:
1 | export function processElement(element: ASTElement, options: CompilerOptions) { |
processAttrs
处理element
上的所有其他属性,包括自定义指令和普通属性:
1 | function processAttrs(el) { |
对于自定义指令是通过addDirective
处理并放到el.directives
:
1 | export function addDirective(el: ASTElement, name: string, rawName: string, value: string, arg: ?string, modifiers: ?ASTModifiers) { |
以上就是parse
阶段对指令的处理了,处理完后并在ast
上添加各种属性。
generate
阶段生成render
字符串
在这个阶段的genData
中会处理parse
阶段放到ast
上的各种指令属性:
1 | export function genData(el: ASTElement, state: CodegenState): string { |
我们的自定义指令在最开始就被genDirectives
处理:
1 | /** |
以上就是在generate
阶段对于指令的处理,处理完后会将各种属性放到data
对象上,这个对象在render
生成vnode
时会被放到vnode.data
上。
patch
阶段处理vnode.data
在patch
的invokeCreateHooks
中调用cbs
上各种子module
的钩子来处理vnode.data
上的数据:
1 | function invokeCreateHooks(vnode, insertedVnodeQueue) { |
其中对于自定义组件的处理是在directives
这个钩子中,代码位于src/core/vdom/modules/directives.js
:
1 | export default { |
_update
就是调用自定义组件上的各个选项函数,如bind
、update
、inserted
等。
以上就是指令处理的概述,接下来的几篇文章会针对各个指令详细描述。