编译阶段之parse
template
ast
- parse阶段
- 在generate阶段有对el属性进行添加值的
流程
总结
1.在闭合标签后执行closeElement,然后执行processElement执行processAttrs。
2.processAttrs获取到el.attrsList,遍历判断name是否是指令,是的话获取修饰符通过对象返回出来。
3.判断name不为Bind不为on进入else逻辑,首先去掉v-标签,然后调用addDirective向el中添加directives属性。
4.如果name不是指令,调用addAttr向el中添加attrs属性。
编译阶段之generate
流程
总结
1.执行到generate阶段,执行genElement,执行genData,接着执行genDirectives函数。
2.接着执行genDirectives,首先获取到el.directives,遍历el.directives,然后获取平台定义的model函数,执行model函数。
3.model函数根据tag和type执行不同的解析逻辑,对于非表单元素的tag和type执行的是genComponentModel函数。
4.genComponentModell函数首先定义了回调事件表达式valueExpression = 'v'。
5.接着通过genAssignmentCode返回code,最终设置el的model属性。
6.genDirectives执行完毕,genData继续往下执行,这时el.model存在,根据el.model的值拼接data。
render & patch
流程
总结
子组件编译阶段之parse
流程
总结
1.在闭合标签后执行closeElement,然后执行processElement执行processAttrs。
2.processAttrs获取到el.attrsList,遍历判断name是否是指令,是的话获取修饰符通过对象返回出来。
3.判断name为v-bind指令,然后调用addProp向el中添加props属性。
4.判断name为v-on指令,然后调用addHandler向el中添加events属性。
子组件编译阶段之generate
流程
总结
1.执行到generate阶段,执行genElement,执行genData。
2.存在el.props,执行genProps,拼接data domProps属性。
3.存在el.events,执行genHandlers,首先根据标识确认输出nativeOn还是on属性名。接着遍历传入的el.events或者el.nativeEvents,然后通过执行genHandler获取到handlerCode,接着和事件名name拼接起来,最后再和之前确认的属性名进行拼接。
子组件patch
流程
总结
1.首先patch开始时会创建cbs对象和hooks,遍历Hooks为cbs添加hook属性为数组,接着继续遍历modules把modules定义相同hooks丢进数组中。最终返回cbs对象。
2.对于create除了按顺序执行存在data属性会调用invokeCreateHooks之外,在创建组件初始化完成时调用initComponent也会调用invokeCreateHooks。
3.invokeCreateHooks就是遍历调用cbs.create的函数,也就是执行updateDirectives,updateDOMListeners等钩子函数,传入空vnode和vnode。
4.updateDOMListeners获取到vnode.data.on对象和获取vnode.elm节点,执行updateListeners,遍历on对象,cur=createFnInvoker返回的函数,把回调赋值给了invoker.fns,此函数是执行回调用的,然后调用add也就是调用addEventListener给节点添加事件和此函数,案例中这里我们就为节点添加上了Input事件函数。
总结
总
给子组件的input添加了input事件,输入框输入后执行input事件,input事件触发了emit的input事件,那么他就去找组件实例上的_event.事件名,找到就执行触发回调。案例中的回调内容就是把msg设置为input输入的e.target.value。这样就完成了父子的通讯。
分
如果子组件不是input框,只是一个按钮事件。如下:
我们通过按钮点击触发emit的input事件一样把把msg设置为传出去的值。
分
接着就可以想到用语法糖去标识。如下:
总
对于自定义model是这样用的:
⼦组件修改了接收的 prop 名以及派发的事件名,然⽽这⼀切⽗组件作为调⽤⽅是不⽤关⼼的,这样做的好处是我们可以把 value 这个 prop 作为其它的⽤途。