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)从没有数据的套接字上接收数据,被迫 ...
随机推荐
- OpenShift添加应用健康检查功能
什么是健康检查? 对于部署成功的应用来说,通过访问接口.执行特定命令等方式判断应用是否存活.正常的方式称为健康检查. 在 OpenShift 或 Kubernetes 中,健康检查都有两个探针,分别是 ...
- 未雨绸缪,数据保护之NBU介质备份
摘要:华为GaussDB目前已支持NBU介质的备份与恢复,本文主要描述了华为GaussDB数据库和NetBackup对接进行备份.恢复的配置方法与性能调优方法. 一.简介 企业要想避开自然灾难和站点中 ...
- 谷歌学术: but your computer or network may be sending automated queries. To protect our users, we can't process your request right now. See Google Help for more information.
原因是屏蔽了日本和新加坡的服务器,切换服务器为其他地方即可
- Eureka系列(九)Eureka自我保护机制
因为本篇简文并不是自己总结的,而是当了下搬运工,所以直接直接附上原作者博客链接. 参考链接: 1.SpringCloud Eureka自我保护机制 2.Spring Cloud Eurek ...
- 工具-Git与GitHub-GitHub使用(99.5.3)
@ 目录 1.在github中添加公钥 2.克隆项目 3.在本地工作区新建分支,修改文件并提交 4.推送到远程仓库 5.从远程分支上拉取代码 关于作者 1.在github中添加公钥 首次使用git必须 ...
- GitHub 上的大佬们打完招呼,会聊些什么?
你好 GitHub!每一位开源爱好者的好朋友「HelloGitHub」 大家好,今儿 HG 有幸邀请到:Lanking 一位亚马逊 AI 软件工程师.开源爱好者和贡献者.他是亚马逊开源的 Java 深 ...
- python爬虫爬取安居客并进行简单数据分析
本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理 爬取过程一.指定爬取数据二.设置请求头防止反爬三.分析页面并且与网页源码进行比对四.分析页面整理数据 ...
- 最速下降法--MATLAB程序
function x = fxsteep(f,e,a,b)x1 = a;x2 = b;Q = fxhesson(f,x1,x2);x0 = [x1,x2]';temp = [x0];fx1 = dif ...
- kafka rebalance解决方案 -incremental cooperative协议和static membership功能
apache kafka的重平衡(rebalance),一直以来都为人诟病.因为重平衡过程会触发stop-the-world(STW),此时对应topic的资源都会处于不可用的状态.小规模的集群还好, ...
- MVC中Bundle的使用
BundleConfig配置 (1)StyleBundle中的参数,即为cshtml中需要调用的虚拟路径名称. (2)Include包含路径,可以包含一个或多个css或js文件.即包含一组文件. pu ...