实现数据绑定的做法有大致如下几种:

  • 发布者-订阅者模式(backbone.js)

  • 脏值检查(angular.js)

  • 数据劫持(vue.js)

发布者-订阅者模式: 一般通过sub, pub的方式实现数据和视图的绑定监听,更新数据方式通常做法是 vm.set('property', value),这里有篇文章讲的比较详细,有兴趣可点这里

这种方式现在毕竟太low了,我们更希望通过 vm.property = value这种方式更新数据,同时自动更新视图,于是有了下面两种方式

脏值检查: angular.js 是通过脏值检测的方式比对数据是否有变更,来决定是否更新视图,最简单的方式就是通过 setInterval() 定时轮询检测数据变动,当然Google不会这么low,angular只有在指定的事件触发时进入脏值检测,大致如下:

  • DOM事件,譬如用户输入文本,点击按钮等。( ng-click )
  • XHR响应事件 ( $http )
  • 浏览器Location变更事件 ( $location )
  • Timer事件( interval )
  • 执行 apply()

响应式

在 init 的时候 通过 Object.defineProperty 对数据属性进行了绑定,它使得当被设置的对象被读取的时候会执行 getter 函数,而在当被赋值的时候会执行 setter 函数。

数据劫持

vue.js 则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。

Object.defineProperty

/*obj: 目标对象prop: 需要操作的目标对象的属性名descriptor: 描述符return value 传入对象
*/
Object.defineProperty(obj, prop, descriptor)
复制代码

descriptor的一些属性,简单介绍几个属性,具体可以参考 MDN 文档。

  • enumerable,属性是否可枚举,默认 false。
  • configurable,属性是否可以被修改或者删除,默认 false。
  • get,获取属性的方法。
  • set,设置属性的方法。

observer(可观察的)


function cb (val) {/* 渲染视图 */console.log("视图更新啦~");
}function defineReactive (obj, key, val) {Object.defineProperty(obj, key, {enumerable: true,       /* 属性可枚举 */configurable: true,     /* 属性可被修改或删除 */get: function reactiveGetter () {return val;         /* 实际上会依赖收集,下一小节会讲 */},set: function reactiveSetter (newVal) {if (newVal === val) return;cb(newVal);}});
}
复制代码

订阅者 Dep

订阅者 Dep ,它的主要作用是用来存放 Watcher 观察者对象。

观察者 Watcher

class Watcher {constructor () {/* 在new一个Watcher对象时将该对象赋值给Dep.target,在get中会用到 */Dep.target = this;}/* 更新视图的方法 */update () {console.log("视图更新啦~");}
}Dep.target = null;
复制代码

依赖收集

当被渲染的时候,因为会读取所需对象的值,所以会触发 getter 函数进行「依赖收集」,「依赖收集」的目的是将观察者 Watcher 对象存放到当前闭包中的订阅者 Dep 的 subs 中。

在修改对象的值的时候,会触发对应的 setter, setter 通知之前「依赖收集」得到的 Dep 中的每一个 Watcher,告诉它们自己的值改变了,需要重新渲染视图。这时候这些 Watcher 就会开始调用 update 来更新视图,当然这中间还有一个 patch 的过程以及使用队列来异步更新的策略。

  • 用 addSub 方法可以在目前的 Dep 对象中增加一个 Watcher 的订阅操作;
  • 用 notify 方法通知目前 Dep 对象的 subs 中的所有 Watcher 对象触发更新操作。

更新视图

在修改一个对象值的时候,会通过 setter -> Watcher -> update 的流程来修改对应的视图。

MVVM

MVVM作为数据绑定的入口,整合Observer、Compile和Watcher三者,通过Observer来监听自己的model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭起Observer和Compile之间的通信桥梁,达到数据变化 -> 视图更新;视图交互变化(input) -> 数据model变更的双向绑定效果。

源码实现详解地址

vue mvvm

vue 原理简单实现相关推荐

  1. element 往node里面增加属性值_【Vue原理】Compile - 源码版 之 Parse 属性解析

    写文章不容易,点个赞呗兄弟 专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧 研究基于 Vue版本 [2.5.17] 如果你觉得排版难 ...

  2. 初始化触发点击事件_【Vue原理】Event - 源码版 之 自定义事件

    专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧 研究基于 Vue版本[2.5.17] Vue 的自定义事件很简单,就是使用 观察者模 ...

  3. vue 启动时卡死_十分钟浅入Vue 原理

    vue原理 引用 众所周知vue是一个MVVM 渐进式框架,MVVM是vue的设计模式,在vue框架中数据会自动驱动视图. 1.MVVM设计模式 ​ 解释 View是视图,就是DOM:对应视图也就是H ...

  4. vue 数值 拼接字符串_【Vue原理】Compile - 白话版

    写文章不容易,点个赞呗兄弟 专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧 研究基于 Vue版本 [2.5.17] 如果你觉得排版难 ...

  5. v-model双向绑定原理_【Vue原理】VModel 白话版

    ↑点击上方 "神仙朱" 一起研究Vue源码吧 专注 Vue 源码分享,为了方便大家理解,分为了白话版和 源码版,白话版让大家可以轻松理解工作原理,源码版让大家更清楚内部操作和 Vu ...

  6. data的值 如何初始化vue_【Vue 原理】Vue 是如何代理 data、methods 和 props 的?

    前言 Vue 有一个非常有趣的功能,就是我们所有传进去的 data .methods 或者 props,都会挂载到 Vue 实例上, 我们可以通过 this.xxx 的简单做法来进行访问.那么,这到底 ...

  7. 【Vue原理】Diff - 源码版 之 Diff 流程

    写文章不容易,点个赞呗兄弟 专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧 研究基于 Vue版本 [2.5.17] 如果你觉得排版难 ...

  8. Vue 原理解析(五)之 虚拟Dom 到真实Dom的转换过程

    上一篇 vue 原理解析(四): 虚拟Dom 是怎么生成的 再有一颗树形结构的Javascript对象后, 我们需要做的就是讲这棵树跟真实Dom树形成映射关系.我们先回顾之前的mountComponn ...

  9. 掌握这些Vue原理,就能月薪30K?

    点击上方蓝色字关注我们~ 不会vue的前端工作者不是合格的web工程师!在2019年接近尾声的时候,尤雨溪宣布 Vue 3.0的源码开放了,想要在2020年跳槽的程序员们,现在可以着手准备了.去BAT ...

最新文章

  1. TypeScript class 的访问控制
  2. linux 安装mongodb 64,在CentOS 6.x 64bit上安装MongoDB 3.2社区版
  3. 处理Redis里的数据
  4. 开发者必看:iOS应用审核的通关秘籍
  5. 静态数据成员与静态成员函数
  6. oracle 传递table,将对象类型表从java传递到oracle 8i(Pass table of object type from java to oracle 8i)...
  7. spring-boot-devtools在Idea中热部署方法
  8. C#交错数组与多维数组区别
  9. 中国平板显示产业运行状况及前景规划建议报告2022-2027年版
  10. ps4正在连接ea服务器,ps4极品飞车19连不上ea服务器 | 手游网游页游攻略大全
  11. Java 中获取Exception的详细信息
  12. Ubuntu更换阿里软件安装源(vim方式)
  13. openfire 开发QQ群、微信群等固定群插件
  14. 人工智能--打飞机游戏
  15. 微信公众号推文发布方法(内涵详细步骤)
  16. c++【吃鸡坑人版8.0】免费复制
  17. ai智能时代 设计师的出路_适用于网页设计师的人工智能工具
  18. CH3-面向对象上 (4个案例实现)
  19. 解决eclipse中overlaps the location of another project: 'xxxx'
  20. 中国运动控制器市场深度调查及战略研究报告(2022版)

热门文章

  1. 抖音爬虫路上的填坑之路
  2. php连接kafka集群,Kafka集群环境配置
  3. AttributeError: module 'tensorflow_core.estimator' has no attribute 'inputs'
  4. TypeScript基础入门 - 接口 - 继承接口
  5. Subversion Native Library Not Available
  6. 与动态执行的C# 代码进行通讯
  7. 程序员,告诉他们被打断的真实代价
  8. 以sysdba身份登录oracle报ORA-1031权限不足错误之完美分析
  9. node.js入门 - 2.创建一个简单聊天室
  10. MSSQL2000+asp.net+论坛安装过程