Vue MVVM模型原理
最近反思了下自己,觉得自己很急躁,学技术总是觉得能用就行了,其实这样很不好,总是这样,就永远只能当用轮子的人。好了,废话不多说,转入正题:
要理解MVVM的原理,首先要理解它是什么,怎么运作起来的:
以下这样图来自这位大佬的文章《Vue.js入门(一)--MVVM框架理解》
由图可见,MVVM模型需要靠Observer(监视者)、Compile(解析器)、Dep(Dependency,收集依赖)、Watcher(观察者)等来实现。
Observer()之所以能够监听数据变化,是因为它依靠了es5的Object.defineProperty(obj, prop, descriptor):
具体关于Object.defineProperty()的属性,可见MDN的Object.defineProperty()。
这个方法可以给对象添加或一个属性,并且返回这个对象,它有三个参数,前面两个obj、prop不多说了,重头戏是第三个参数descriptor,既描述对象,这个对象可以传configurable、enumerable、value...以及get、set
function Observer(obj, vm) {
Object.keys(obj).forEach(function(key) {
Object.defineProperty(obj, key, {
get: function() {
return obj[key];
},
set: function(newVal) {
if (newVal === obj[key]) return;
obj[key] = newVal;
}
});
});
}
这段代码的作用就是遍历obj的每个属性,加上get和set,读取obj属性的时候就会触发get,给obj属性赋值的时候就会触发set.
那Observer()怎么样才能在数据变更时及时通知到Dep,再有Dep去通知Watcher呢?看看Dep()代码:
1 /**
2 * 收集Watcher依赖并通知数据变更
3 */
4 function Dep () {
5 this.subs = []
6 }
7 Dep.prototype = {
8
9 // 添加订阅者
10 addSub: function(sub) {
11 this.subs.push(sub);
12 },
13 // 通知订阅者
14 notify: function() {
15 this.subs.forEach(function(sub) {
16 sub.update();
17 });
18 }
19 };
改写下Observer():
1 function observe (obj, vm) {
2 Object.keys(obj).forEach(function (key) {
3 defineReactive(vm, key, obj[key]);
4 });
5 }
6 function defineReactive (obj, key, val) {
7 var dep = new Dep();
8 Object.defineProperty(obj, key, {
9 get: function () {
10 if (Dep.target) dep.addSub(Dep.target);
11 return val
12 },
13 set: function (newVal) {
14 if (newVal === val) return
15 val = newVal;
16 dep.notify();
17 }
18 });
19 }
而Dep.target指的是Watcher:
1 function Watcher(vm, cb, expOrFn) {
2 // this为Watcher构造函数
3 Dep.target = this;
4 this.cb = cb
5 this.vm = vm
6 this.expOrFn = expOrFn
7 this.value = this.get()
8 this.update();
9 Dep.target = null;
10 }
11 Watcher.prototype = {
12 update: function () {
13 this.run()
14 },
15 run: function () {
16 const value = this.get()
17 if (value !== this.value) {
18 this.value = value
19 this.cb.call(this.vm)
20 }
21 },
22
23 // 获取属性值
24 get: function () {
25 this.value = this.vm[this.expOrFn];
26 }
27 }
由此可见:
Oberver()通过Object.defineProperty()通知Dep(),而Dep()这里收集了Watcher依赖,当Dep()里有个订阅者的数组,全都是Watcher,当Oberver触发了Dep原型上的方法notify()的时候,就会触发Watcher去update,更新数据,而view层将进行render(),从而更新视图。
Vue MVVM模型原理的更多相关文章
- 搞懂:MVVM模型以及VUE中的数据绑定数据劫持发布订阅模式
搞懂:MVVM模式和Vue中的MVVM模式 MVVM MVVM : model - view - viewmodel的缩写,说都能直接说出来 model:模型,view:视图,view-Model:视 ...
- Vue学习之--------el与data的两种写法、MVVM模型、数据代理(2022/7/5)
文章目录 1.el与data的两种写法 1.1.基础知识 1.2.代码实例 1.3.页面效果 2.MVVM模型 2.1. 基础知识 2.2 .代码实例 2.3.页面效果 3.数据代理 3.1. 基础知 ...
- Vue双向绑定原理,教你一步一步实现双向绑定
当今前端天下以 Angular.React.vue 三足鼎立的局面,你不选择一个阵营基本上无法立足于前端,甚至是两个或者三个阵营都要选择,大势所趋. 所以我们要时刻保持好奇心,拥抱变化,只有在不断的变 ...
- vue双向绑定原理及实现
vue双向绑定原理及实现 一.总结 一句话总结:vue中的双向绑定主要是通过发布者-订阅者模式来实现的 发布 订阅 1.单向绑定和双向绑定的区别是什么? model view 更新 单向绑定:mode ...
- Vue源码--解读vue响应式原理
原文链接:https://geniuspeng.github.io/2018/01/05/vue-reactivity/ Vue的官方说明里有深入响应式原理这一节.在此官方也提到过: 当你把一个普通的 ...
- 直播课(1)如何通过数据劫持实现Vue(mvvm)框架
19.6.28更新: 这篇博客比较完善:将每一部分都分装在单独的js文件中: 剖析Vue原理&实现双向绑定MVVM 半个月前看的直播课,现在才自己敲了一遍,罪过罪过 预览: 思路: 简单实现V ...
- MVC、MVP、MVVM模型
在学习vue.react的过程中,总能看到MVVM模型,那么MVVM究竟是什么,下面将我最近看到的资料以及自己的想法总结一下. 与MVVM相似的,还有MVC.MVP,先从MVC.MVP这两个入手,方面 ...
- word2vec模型原理与实现
word2vec是Google在2013年开源的一款将词表征为实数值向量的高效工具. gensim包提供了word2vec的python接口. word2vec采用了CBOW(Continuous B ...
- 【转】Select模型原理
Select模型原理利用select函数,判断套接字上是否存在数据,或者能否向一个套接字写入数据.目的是防止应用程序在套接字处于锁定模式时,调用recv(或send)从没有数据的套接字上接收数据,被迫 ...
随机推荐
- 面试 HTTP和HTML 浏览器
HTTP和HTML 浏览器 #说一下http和https #参考回答: https的SSL加密是在传输层实现的. (1)http和https的基本概念 http: 超文本传输协议,是互联网上应用最为广 ...
- SQL注入-DNS注入(二)
其实就是盲注的简化版本,不过这种方式确实简单,不需要写py脚本一点点去跑 参考文章: https://www.jianshu.com/p/c805209244c2 这 ...
- MySQL高可用(三)搭建主备同步实战
目标 掌握如何搭建一主一备的主备架构 实验环境 系统:Ubuntu 18.04.1 LTS MySQL版本:5.7.32 主库IP:192.168.200.120 备库IP:192.168.200.1 ...
- Asp.Net Core使用MongoDB
MongoDB 是一个基于分布式且面向文档存储的开源 NoSql数据库系统 MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的.它支持的数据结构 ...
- EF快速入门--直接修改(简要介绍ObjectContext处理机制)
原博文 http://www.cnblogs.com/fly_dragon/archive/2011/06/05/2073084.html ObjectContext的处理机制 ObjectConte ...
- VS批量添加多个文件
步骤 1.设置项目,显示所有文件.2.点击项目,右键在资源管理器中打开.3.将要导入的文件复制到对应的文件中去.4.在解决方案中就可以看到刚才添加的多个文件.5.在新加的文件夹上右键,包括在项目中.
- java 字符串String.intern()方法学习
在jdk1.6与jdk1.7中,String类中的intern()方法实现的原理是有一些差异的.1.在jdk1.6中,intern()方法是先查找字符串常量池是否含有当前字符串,如果没有,那么就在字符 ...
- jdbc编程学习(1)
一,背景 1996年,sun公司发布了第一版本的数据库连接(JDBC)API,使编程人员可以通过这个API接口连接到数据库,并使用结构化查询语言(SQL)完成对数据库的查找与更新.JDBC自此成为Ja ...
- 浅入kubernetes(1):Kubernetes 入门基础
目录 Kubernetes 入门基础 Introduction basic of kubernetes What Is Kubernetes? Components of Kubernetes Kub ...
- 【老孟Flutter】Stateful 组件的生命周期
老孟导读:关于生命周期的文章共有2篇,第一篇是介绍 Flutter 中Stateful 组件的生命周期. 博客地址:http://laomengit.com/blog/20201227/Statefu ...