[Vue 源码] v-model 逻辑分析

v-model

v-model 和前面分析过的 v-on 一样,都是 Vue 提供的指令,所以 v-model 的分析流程和 v-on 相似。围绕模板的编译、 render 函数的生成,到最后的真实节点的挂载。 v-model 无论什么使用场景,本质上都是一个语法糖。

基础使用

v-model 和表单脱离不了关系,之所以视图能影响数据,本质上这个视图是可交互的,因此表单是实现这一交互的前提。表单的使用以 <input> <textarea> <select> 为核心,来看下具体的使用方式

// 普通输入框
<input type="text" v-model="value1">
// 多行文本框
<textarea v-model="value2" cols="30" rows="10"></textarea>
// 单选框
<div class="group"><input type="radio" value="one" v-model="value3"> one<input type="radio" value="two" v-model="value3"> two
</div> 

先来回顾一下模版到真实节点的过程。

  • 1.模版解析成 AST
  • 2.AST 树生成可执行的 render 函数的生成
  • 3.render 函数转换成虚拟 DOM 对象
  • 4.根据虚拟 DOM 对象生成真实 DOM 节点

模版解析

通过前面的分析已经知道,模版编译阶段,会调用 const ast = parse(template.trim(), options) 生成 AST 树, 而对于 v-model 的处理, 集中在 processAttrs 函数上。

processAttrs 的处理过程中,对模版的属性处理分成两部分,一部分是对普通 html 标签属性的处理,一部分是对 vue 指令的处理。而对于 vue 指令的处理中,又对 v-on v-bind 进行了特殊的处理,其他的 Vue 指令都会执行 addDirective 过程进行处理。

function processAttrs (el) {const list = el.attrsListlet i, l, name, rawName, value, modifiers, syncGen, isDynamicfor (i = 0, l = list.length; i < l; i++) {name = rawName = list[i].namevalue = list[i].valueif (dirRE.test(name)) {// 对 Vue 指令的处理// mark element as dynamicel.hasBindings = true// modifiersmodifiers = parseModifiers(name.replace(dirRE, ''))if (bindRE.test(name)) { // v-bind // v-bind 指令处理 过程} else if (onRE.test(name)) { // v-on// v-on 指令处理过程} else { // normal directives// 对于非 v-bind v-on 的 vue 指令处理过程name = name.replace(dirRE, '')// parse argconst argMatch = name.match(argRE)let arg = argMatch && argMatch[1]isDynamic = falseif (arg) {name = name.slice(0, -(arg.length + 1))if (dynamicArgRE.test(arg)) {arg = arg.slice(1, -1)isDynamic = true}}addDirective(el, name, rawName, value, arg, isDynamic, modifiers, list[i])if (process.env.NODE_ENV !== 'production' && name === 'model') {checkForAliasModel(el, value)}}} else {// literal attribute// 普通 html 标签属性处理过程}}
} 

在对事件机制的分析过程中,我们知道, Vuev-on 指令的处理是为 AST 树添加 events 属性,类似的,普通指令会在 AST 树上添加 directives 属性。

export function addDirective (el: ASTElement,name: string,rawName: string,value: string,arg: 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值