最近小组有个关于vue源码分析的分享会,提前准备一下…

前言:
我们都知道使用v-model可以实现数据的双向绑定,及实现数据的变化驱动dom的更新,dom的更新影响数据的变化。那么v-model是怎么实现这一原理的呢?接下来探索一下这部分的源码。

前期准备

①:vue2.5.2源码(用于阅读、查看关联等)
②:建立vue demo,创建包含v-model指令的实例(用于debugger)
以下为demo:

genDirectives

在模板的编译阶段, v-model跟其他指令一样,会被解析到 el.directives 中,之后会通过genDirectives方法处理这些指令,genDirectives方法位于src/compiler/codegen/index.js中:

我们去到之前建立的demo,找到demo中node_modules/vue/dist/vue.esm.js下的genDirectives方法,打上debugger,如图:

可以看到传进来的el是ast语法树,el.directives是el上的指令,如下:


回到genDirectives源码,循环指令时都执行了const gen: DirectiveFunction = state.directives[dir.name]这个方法,state.directives是什么?
当遍历到v-model的时候,dir.namemodel,对应的state.directives[dir.name]相当于state.directives[model]directives的定义位于src/platforms/web/compiler/directives/index.js 中:

本次分析的v-model,对应的也就是model方法,也就是其实!!gen(el, dir, state.warn)执行的是model方法,!!用于将返回值转为Boolean类型,model的定义位于index同目录下。

model


model方法根据传入的参数对tag的类型进行判断,调用不同的处理逻辑,本demo中tag的类型为input,所以会执行genDefaultModel方法,为了节约时间,就不去源码中找了,藏得比较深,直接在demo引用的单文件源码vue.esm.js中搜索genDefaultModel

genDefaultModel

发现定义如下,打上debugger,以便调试:

通过控制台查看变量信息,可以看到:

可以看到里边的genAssignmentCode(value, valueExpression)在此demo中相当于genAssignmentCode("msg", ""$event.target.value""),执行此方法后返回的是一个字符串:msg=$event.target.value,后来命中了needCompositionGuard,所以code变成了if($event.target.composing)return;msg=$event.target.valueif($event.target.composing)return;的作用是不记录用户未确定的输入,比如:

注释掉if(needCompositionGuard)的话用户没确定的也会展示,如图:

随后会依次执行以下两个方法:

addProp

先注释掉addHandler,避免对研究此方法产生影响。

可以看到此方法的功能为给el添加props,首先判断el上有没有props,如果没有的话创建props并赋值为一个空数组,随后拼接对象并推到props中,代码在此demo中相当于push{name: "value", value: "(msg)"},打印一下这番操作后的el,可以看到添加了propsel的结构如下:

这个方法其实是在input上动态绑定了value,此时,原本的<input v-model="msg">相当于变成了<input v-bind:value="msg">,随后继续执行addHandler

addHandler

以下仅包含关键代码,打上debugger以便查看数据。

控制台查看eldebuuger结果:

可以看到比执行addHandler之前,el上多了events,可以得知这个方法主要给el 添加了事件处理,在此demo中的话相当于在 input 上绑定了 input 事件。

总结:

也就是说,到此为止,原本的<input v-model="msg">相当于变成了<input v-bind:value="msg" v-on:input="msg=$event.target.value">,当用户输入的使用触发msg=$event.target.value进而更新msgmsg通过v-bind绑定到输入框的value上。
即,以下两份代码其实是一个意思。
第一份:

第二份

[Vue源码分析] v-model实现原理相关推荐

  1. [Vue源码分析]自定义事件原理及事件总线的实现

    最近小组有个关于vue源码分析的分享会,提前准备一下- 前言: 我们都知道Vue中父组件可以通过 props 向下传数据给子组件:子组件可以通过向$emit触发一个事件,在父组件中执行回调函数,从而实 ...

  2. vue源码分析系列二:$mount()和new Watcher()的执行过程

    续vue源码分析系列一:new Vue的初始化过程 在initMixin()里面调用了$mount() if (vm.$options.el) {vm.$mount(vm.$options.el);/ ...

  3. [Vue源码分析] 模板的编译

    最近小组有个关于vue源码分析的分享会,提前准备一下- 前言: Vue有两个版本:Runtime + Compiler . Runtime only ,前者是包含编译代码的版本,后者不包含编译代码,编 ...

  4. SSM源码分析之Spring05-DI实现原理(基于Annotation 注入)

    目录导航 前言 注解的引入 AnnotationConfigApplicationContext 对注解Bean初始化 AnnotationConfigApplicationContext注册注解Be ...

  5. 10年大厂程序员是如何高效学习使用redis的丨redis源码分析丨redis存储原理

    10年大厂程序员是怎么学习使用redis的 1. redis存储原理分析 2. redis源码学习分享 3. redis跳表和B+树详细对比分析 视频讲解如下,点击观看: 10年大厂程序员是如何高效学 ...

  6. Vue源码分析——第三章

    Vue源码分析--第一章 Vue源码分析--第二章 // only used in dev mode//检测 val必需是数字function checkDuration(val, name, vno ...

  7. Vue源码分析--Vue.component

    Vue源码分析–Vue.component 我将非 Vue.component 的部分去掉了 export function initAssetRegisters (Vue: GlobalAPI) { ...

  8. vuex 源码分析_深入Vuex原理(上)

    原标题:深入Vuex原理(上) 孔维国,2016年加入去哪儿网技术团队.目前在大住宿事业部/增值业务研发中心,参与开发了TMC.CRM.QTA.Auth等项目,负责node框架nomi的设计以及开发. ...

  9. 大前端-Vue源码分析

    Vue源码解析-响应式原理 以下内容来自 拉勾教育大前端训练营 笔者在学习过程中对笔记进行的一个整理 心得体会 嘿嘿嘿~~~ 首先说说拉勾教育大前端训练营的课程视频吧,课程的质量是真的很好哦,并且已经 ...

最新文章

  1. VC下提前注入进程的一些方法1——远线程不带参数
  2. NumPy迎来重大版本更新
  3. 【原创】关于部门月会(二)
  4. 动手实现一个 localcache - 设计篇
  5. php字符串search,js获取location.search每个查询字符串的值
  6. mysql 5.7 密码过期_mysql5.7 密码过期了怎么办
  7. windows server 文件资源管理服务器为指定的ftp用户开启磁盘配额
  8. 计算机专业考试知识点,2016计算机专业知识:精选知识点练习(126)
  9. AI独角兽云从科技:用人机协同战略,跨AI工程的楚河汉界
  10. java batik_使用BATIK解析SVG生成PNG图片
  11. Windows10从 微软商店 安装 linux(ubuntu)
  12. win7休眠不断网的设置方法
  13. Linux系统管理、系统安全命令概述
  14. 【数学】微积分的大用处
  15. 观李永乐《皇帝的新衣》后感以及红蓝眼悖论解题思路
  16. 声网发布极速直播、低码高清 首创轻互动直播,节省50%带宽成本
  17. 为什么转置一个512x512的矩阵,会比513x513的矩阵慢很多?
  18. pr使用视频素材技巧
  19. Unit2 附加问句
  20. ubuntu 14.04 搜狗拼音安装

热门文章

  1. Kerberos认证代码分析Can't get Kerberos realm
  2. 052、overlay如何实现跨主机通信?(2019-03-19 周二)
  3. Ruby离线安装gem依赖
  4. 《Linux From Scratch》第三部分:构建LFS系统 第六章:安装基本的系统软件- 6.69. Vim-7.4...
  5. 历经32载,域名仍是少年,更何况不足2岁的.xin?
  6. 170316.道格拉斯-普克算法
  7. linux shell 特定变量参数说明
  8. KlayGE 4.0中Deferred Rendering的改进(四):GI的神话
  9. Drupal 引入JS文件的几种方式
  10. Go语言 Yaml编码和解码