Vue双向绑定原理(v-model)

本文深入探讨Vue的v-model双向绑定原理,从AST树解析、render函数生成、patch真实节点等方面阐述v-model如何实现数据和视图的同步。通过分析不同表单控件的事件绑定,揭示v-model在不同场景下的工作方式,并探讨组件中v-model的实现机制,展示其作为子父组件通信的语法糖的本质。
摘要由CSDN通过智能技术生成

之前有整理过Vue响应式原理,响应式主要的效果是数据改变了就会引起页面修改。关于v-model我们也不陌生,vue的双向绑定指令,页面修改会引起数据修改,数据修改页面也会跟着改变。我们直到数据->页面是由vue的响应式原理实现的,那么该怎么做到页面->数据的修改呢?

表单绑定

v-model一般我们是在表单元素上进行使用,因为视图能影响数据,本质上是这个视图需要可交互,因此表单是实现这一交互的前提。表单的使用是以<input><textarea><select>为核心。具体的使用细节这里就不一一细说了。

这里我们从模板解析开始分析,vuev-model做了什么操作。
这里我们来看一些绑定在input上的v-model都经历了什么。

// 普通输入框
<input type="text" v-model="value1">

AST树的解析

模版的编译阶段,会调用var ast = parse(template.trim(), options)生成AST树,parse函数的起他细节这里不展开分析,我们只说模板属性上的解析processAttrs函数。

vue模板属性有两部分组成,一部分是指令,另一部分是普通的html标签属性。对于指令,出去v-onv-bind,其他普通指令会执行addDirective过程。

// 处理模板属性
function processAttrs(el) {
   
  var list = el.attrsList;
  var i, l, name, rawName, value, modifiers, syncGen, isDynamic;
  for (i = 0, l = list.length; i < l; i++) {
   
    name = rawName = list[i].name; // v-on:click
    value = list[i].value; // doThis
    if (dirRE.test(name)) {
    // 1.针对指令的属性处理
      ···
      if (bindRE.test(name)) {
    // v-bind分支
        ···
      } else if(onRE.test(name)) {
    // v-on分支
        ···
      } else {
    // 除了v-bind,v-on之外的普通指令
        ···
        // 普通指令会在AST树上添加directives属性
        addDirective(el, name, rawName, value, arg, isDynamic, modifiers, list[i]);
        if (name === 'model') {
   
          checkForAliasModel(el, value);
        }
      }
    } else {
   
      // 2. 普通html标签属性
    }

  }
}

AST产生阶段对事件指令v-on的处理是为AST树添加events属性。类似的,普通指令会在AST树上添加directives属性,我们可以看一下addDirective函数

// 添加directives属性
function addDirective (el,name,rawName,value,arg,isDynamicArg,modifiers,range) {
   
    (el.directives || (el.directives = [])).push(rangeSetItem({
   
      name: name,
      rawName: rawName,
      value: value,
      arg: arg,
      isDynamicArg: isDynamicArg,
      modifiers: modifiers	// 模板中添加的修饰符,如:.lazy、.number、.trim
    }, range));
    el.plain = false;
  }

最终AST树上会多处一个属性对象

// AST
{
   
  directives: {
   
    {
   
      rawName: 'v-model',
      value: 'value',
      name: 'v-model',
      modifiers: undefined
    }
  }
}

render函数生成

render函数生成阶段,generate逻辑,其中genData会对模版的各个属性进行处理,最终返回拼接好的字符串模板,而对指令的处理会进入genDirectives函数

genDirectives函数中,会拿到之前AST树中的directives对象,并遍历解析指令对象,最终以'directives:['包裹的字符串返回。

// directives render字符串的生成
  function genDirectives (
  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值