接下来的几篇文章焦点放到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等。
以上就是指令处理的概述,接下来的几篇文章会针对各个指令详细描述。