Vue的构造函数分析

vm就是MVVM中的View Model
var vm = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
}) /*
相关于Vue的构造函数
*/
function Vue(options) {
// 将选项对象保存到vm
this.$options = options;
// 将data对象保存到vm和data变量中
var data = this._data = this.$options.data;
//将vm保存在me变量中
var me = this;
// 遍历data中所有属性
Object.keys(data).forEach(function (key) { // 属性名: name
// 对指定属性实现代理: 通过Object.defineProperty(obj,attr,{配置项, get:func, set:func})方法,将data中遍历的属性添加到vm实例中实现代理,使得原本 vm._data[attr]访问方式变为vm.attr
me._proxy(key);
}); // 对data进行监视,在observe中创建与当前属性对应的dep对象,当调用data中的属性值时,建立dep与watcher的关系;当更新data中的值时,通过dep.notify()方法通知当前dep对应的所有的watcher对界面数据进行更新
observe(data, this); // 创建一个用来编译模板的compile对象
this.$compile = new Compile(options.el || document.body, this)
}
  1. 数据绑定

    • 初始化显示: 页面(表达式/指令)能从data读取数据显示 (编译/解析)
    • 更新显示: 更新data中的属性数据==>页面更新

Dep和Watcher对象

Dep

与data中的属性一一对应

{ id: 0, subs[对应的Watcher实例对象数组] }

Watcher

与模板中一般指令(v-html、v-model、v-class...)/大括号表达式({{ }})一一对应

{
cb: 当对应的属性值发生了变化时, 自动调用该回调函数, 更新对应的节点,
vm: Vue实例对象,
exp: data属性表达式,例如:a.b.c,
depIds: 用于存储对应的dep对象 {0: d0, 1: d1, 2: d2},
value: 当前watcher中的属性值
}
  1. 什么时候一个dep中关联多个watcher?

    多个指令或表达式用到了当前同一个属性 {{name}} {{name}}
  2. 什么时候一个watcher中关联多个dep?

    多层表达式的watcher对应多个dep {{a.b.c}}

整体过程

Vue是通过数据劫持的方式来做数据绑定的,最核心的方法是通过Object.defineProperty()方法来实现对属性的劫持,达到监听数据变动的目的。以MVVM作为数据绑定的入口,整合Observer、Compile和Watcher三者,通过Observer来监听自己的model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭起Observer和Compile之间的通信桥梁,达到数据变化 -> 视图更新;视图交互变化(input) -> 数据model变更的双向绑定效果。

原理图如下:

Vue实例化一个对象的过程如下:

  1. mvvm入口函数,整合以下三者,创建一个实例后,遍历data中的所有属性实现数据代理,实现 vm.xxx 代替 vm._data.xxx
  2. 实现一个数据监听器Observer,利用Obeject.defineProperty()来监听数据对象的所有属性变动,并对应所有属性一一创建相应的dep对象,给dep对象添加订阅者(watcher);如Observer监测到有变动,set函数调用,触发Dep的notify()向对应的订阅者Watcher通知变化,Watcher调用update方法更新界面。
  3. 实现一个指令解析器Compile,主要做的事情是解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图,由于遍历解析的过程有多次操作dom节点,为提高性能和效率,会先将跟节点el转换成文档碎片fragment进行解析编译操作,解析完成,再将fragment添加回原来的真实dom节点中
  4. 实现一个Watcher

1、在自身实例化时往属性订阅器(dep)里面添加自己

2、自身必须有一个update()方法

3、待属性变动dep.notice()通知时,能调用自身的update()方法,并触发Compile中绑定的回调。

文章学习重要来源:https://segmentfault.com/a/1190000006599500

Vue的双向绑定原理的更多相关文章

  1. vue的双向绑定原理及实现

    前言 使用vue也好有一段时间了,虽然对其双向绑定原理也有了解个大概,但也没好好探究下其原理实现,所以这次特意花了几晚时间查阅资料和阅读相关源码,自己也实现一个简单版vue的双向绑定版本,先上个成果图 ...

  2. vue数据双向绑定原理

    vue的数据双向绑定的小例子: .html <!DOCTYPE html> <html> <head> <meta charset=utf-> < ...

  3. vue的双向绑定原理解析(vue项目重构二)

    现在的前端框架 如果没有个数据的双向/单向绑定,都不好意思说是一个新的框架,至于为什么需要这个功能,从jq或者原生js开始做项目的前端工作者,应该是深有体会. 以下也是个人对vue的双向绑定原理的一些 ...

  4. vue的双向绑定原理浅析与简单实现

    很久之前看过vue的一些原理,对其中的双向绑定原理也有一定程度上的了解,只是最近才在项目上使用vue,这才决定好好了解下vue的实现原理,因此这里对vue的双向绑定原理进行浅析,并做一个简单的实现. ...

  5. 西安电话面试:谈谈Vue数据双向绑定原理,看看你的回答能打几分

    最近我参加了一次来自西安的电话面试(第二轮,技术面),是大厂还是小作坊我在这里按下不表,先来说说这次电面给我留下印象较深的几道面试题,这次先来谈谈Vue的数据双向绑定原理. 情景再现: 当我手机铃声响 ...

  6. Vue数据双向绑定原理及简单实现

    嘿,Goodgirl and GoodBoy,点进来了就看完点个赞再go. Vue这个框架就不简单介绍了,它最大的特性就是数据的双向绑定以及虚拟dom.核心就是用数据来驱动视图层的改变.先看一段代码. ...

  7. Vue之双向绑定原理动手记

    Vue.js的核心功能有两个:一是响应式的数据绑定系统,二是组件系统.本文是通过学习他人的文章,从而理解了双向绑定原理,从而在自己理解的基础上,自己动手实现数据的双向绑定. 目前几种主流的mvc(vm ...

  8. Vue.js双向绑定原理

    Vue.js最核心的功能有两个,一个是响应式的数据绑定系统,另一个是组件系统.本文仅仅探究双向绑定是怎样实现的.先讲涉及的知识点,再用简化的代码实现一个简单的hello world示例. 一.访问器属 ...

  9. 探讨vue的双向绑定原理及实现

    1.vue的实现原理 vue的双向绑定是由数据劫持结合发布者-订阅者模式实现的,那么什么是数据劫持?vue是如何进行数据劫持的?说白了就是通过Object.defineProperty()来劫持对象属 ...

  10. 【Vue】vue的双向绑定原理及实现

    vue数据双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现的,那么vue是如果进行数据劫持的,我们可以先来看一下通过控制台输出一个定义在vue初始化数据上的对象是个什么东西. 代码: var ...

随机推荐

  1. Codeforces Round #628 (Div. 2) 题解

    人闲桂花落,夜静春山空. 月出惊山鸟,时鸣春涧中.--王维 A. EhAb AnD gCd You are given a positive integer x. Find any such 2 po ...

  2. oracle获取表字段及表注释的相关操作

    一.获取表字段: select * from user_tab_columns where Table_Name='用户表' user_tab_columns 为当前用户的columns,除此之外还有 ...

  3. js 函数对象的继承 inherit 带 插件完整解析版[helpers.js]

    前言:         本人纯小白一个,有很多地方理解的没有各位大牛那么透彻,如有错误,请各位大牛指出斧正!小弟感激不尽.         本篇文章为您分析一下原生JS的对象继承方法 需求分析: 1. ...

  4. 浅析 JS 中的作用域链

    作用域链的形成 在 JS 中每个函数都有自己的执行环境,而每个执行环境都有一个与之对应的变量对象.例如: var a = 2 function fn () { var a = 1 console.lo ...

  5. Salesforce吹嘘无代码开发,不用费脑子的人工智能

    Salesforce在星期四举办的Dreamforce '16大会上,开发人员主题演讲可谓面面俱到--听众被舞台包围了,而不是远远地坐在观众席. 这是符合该公司在六月份第一次的开发者大会Trailhe ...

  6. 树上倍增法求LCA

    我们找的是任意两个结点的最近公共祖先, 那么我们可以考虑这么两种种情况: 1.两结点的深度相同. 2.两结点深度不同. 第一步都要转化为情况1,这种可处理的情况. 先不考虑其他, 我们思考这么一个问题 ...

  7. F. Cards and Joy

    F. Cards and Joy 题目大意: 给你n个人,每一个人恰好选k张牌. 第一行是 n 和 k 第二行有n*k个数,代表有n*k张牌,每张牌上的数字 第三行有n个数,代表第i个人喜欢的数字 第 ...

  8. java线程池原理解析

    五一假期大雄看了一本<java并发编程艺术>,了解了线程池的基本工作流程,竟然发现线程池工作原理和互联网公司运作模式十分相似. 线程池处理流程 原理解析 互联网公司与线程池的关系 这里用一 ...

  9. Coursera课程笔记----计算导论与C语言基础----Week 7

    C语言中的数据成分(Week7) 内存 把内存想象成长带,带子上有许多方格,每个方格有8位(8bit) 2^10 = 1024 1B = 8 b 1KB = 1024Byte MB.GB.TB.PB- ...

  10. Coursera课程笔记----计算导论与C语言基础----Week 5

    从现实问题到计算机程序(Week 5) 总结回顾 计算机只能按照程序去执行,不可能自己"想出"一个解决问题的方法 面对一个问题,你必须自己找到解决方案,才有可能做出相应的程序 所以 ...