浅谈vue响应式原理及发布订阅模式和观察者模式
一.Vue响应式原理
首先要了解几个概念:
数据响应式:数据模型仅仅是普通的Javascript对象,而我们修改数据时,视图会进行更新,避免了繁琐的DOM操作,提高开发效率。
双向绑定:数据改变,视图改变,数据也随之改变,我们可以使用v-model在表单上创建双向数据绑定。
数据驱动是Vue最独特的特性之一:开发过程中仅需要关注数据本身,不需要关心数据是如何渲染到视图。
vue2.X中的响应式原理是基于defineProperty,兼容IE8以上版本,核心原理代码如下:
let data={
msg:'hello',
count:10
}
let vm={}
proxyData(data)
function proxyData(data){
Object.keys(data).forEach(key=>{
Object.defineProperty(vm,key,{
enumerable:true,
configurable:true,
writeable:true,
//获取值的时候执行
get(){
console.log('get:',key,data[key])
return data[key]
},
//设置值的时候执行
set(newValue){
data[key]=newValue
console.log('set:',key,newValue)
document.querySelector('#app').textContent=data[key]
}
})
})
}
vm.msg //获取(get方法) hello
vm.msg='hello World' //设置新属性值并渲染到页面(set方法)
vm.msg //hello World
vue3.X中的响应式原理是基于Proxy,直接监听对象,而非属性,ES6中新增,IE不支持,性能由浏览器优化,性能比defineProperty要好,代码的话相比较defineProperty要简洁一些,对于多个属性的值不需要进行循环遍历处理。
let data={
msg:'hello',
count:0
} //模拟 Vue 实例
let vm=new Proxy(data,{
//执行代理行为的函数
//当访问 vm 的成员会执行
get(target,key){
console.log('get,key:',key,target[key])
return target[key]
},
set(target,key,newValue){
console.log('set,key:',key,newValue)
if(target[key] === newValue){
return
}
target[key]=newValue
document.querySelector("#app").textContent=target[key]
}
})
//测试
vm.msg='Hello World'
console.log(vm.msg)
二.发布订阅模式和观察者模式
1.发布/订阅模式
这个概念有些抽象,下面举个例子说明下,家长比较关心孩子成绩,天天问孩子成绩出来没,假设可以到孩子所在班级去订阅孩子成绩,一旦考试成绩出来,相当于触发了一个事件,最后有班级的老师以短信的形式通知给家长,
不需要天天问孩子成绩出来没,家长就是事件的订阅者,老师是事件的发布者,孩子所在的班级可以假想成一个事件的中心。vue中的自定义事件都是基于发布/订阅模式的。下面模拟下发布订阅模式的运行机制:
//事件触发器
class EventEmitter(){
constructor(){
// 初始化对象{ 'click':[fn1,fn2],'change':[fn] }
this.subs=Object.create(null)
}
//注册事件
$on(eventType,handler){
this.subs[eventType] = this.subs[eventType] || []
this.subs[eventType].push(handler)
}
//触发事件
$emit(eventType){
if(this.subs[eventType]){
this.subs[eventType].forEach(handler => {
handler()
})
}
}
}
//测试 let em =new EventEmitter() em.$on('click',()=>{
console.log('click1')
})
em.$on('click',()=>{
console.log('click2')
})
em.$emit('click') //打印结果 click1,click2
二.观察者模式
观察者模式和订阅模式的区别是没有事件中心,只有发布者和订阅者,并且发布者需要知道订阅者的存在.
概念:
观察者 --Watcher
update():当事件发生时,具体要做的事情。
发布者 --Dep
subs数组:存储所有的观察者
addSub():添加观察者
notify():当事件发生,调用所有观察者的update()方法
//发布者-目标
class Dep{
constructor() {
//记录所有的订阅者
this.subs=[]
}
//添加订阅者
addsub(sub){
if(sub && sub.update){
this.subs.push(sub)
}
}
//发布通知
notify(){
this.subs.forEach(sub=>{
sub.update()
})
}
}
//订阅者-观察者
class Watcher{
update(){
console.log('update')
}
}
//测试
let dep=new Dep()
let watcher=new Watcher()
dep.addsub(watcher)
dep.notify() //打印结果 update
总结:
观察者模式是由具体目标调度,比如当事件触发,Dep就会去调用观察者的方法,所以观察者的订阅者和发布者之间是存在依赖的。
发布订阅模式由统一调度中心调用,因此发布者和订阅者不需要知道对方的存在。
浅谈vue响应式原理及发布订阅模式和观察者模式的更多相关文章
- 浅谈Vue响应式(数组变异方法)
很多初使用Vue的同学会发现,在改变数组的值的时候,值确实是改变了,但是视图却无动于衷,果然是因为数组太高冷了吗? 查看官方文档才发现,不是女神太高冷,而是你没用对方法. 看来想让女神自己动,关键得用 ...
- Vue源码--解读vue响应式原理
原文链接:https://geniuspeng.github.io/2018/01/05/vue-reactivity/ Vue的官方说明里有深入响应式原理这一节.在此官方也提到过: 当你把一个普通的 ...
- 详解Vue响应式原理
摘要: 搞懂Vue响应式原理! 作者:浪里行舟 原文:深入浅出Vue响应式原理 Fundebug经授权转载,版权归原作者所有. 前言 Vue 最独特的特性之一,是其非侵入性的响应式系统.数据模型仅仅是 ...
- vue响应式原理,去掉优化,只看核心
Vue响应式原理 作为写业务的码农,几乎不必知道原理.但是当你去找工作的时候,可是需要造原子弹的,什么都得知道一些才行.所以找工作之前可以先复习下,只要是关于vue的,必定会问响应式原理. 核心: / ...
- 深入Vue响应式原理
深入Vue.js响应式原理 一.创建一个Vue应用 new Vue({ data() { return { name: 'yjh', }; }, router, store, render: h =& ...
- 浅析Vue响应式原理(三)
Vue响应式原理之defineReactive defineReactive 不论如何,最终响应式数据都要通过defineReactive来实现,实际要借助ES5新增的Object.definePro ...
- 深入解析vue响应式原理
摘要:本文主要通过结合vue官方文档及源码,对vue响应式原理进行深入分析. 1.定义 作为vue最独特的特性,响应式可以说是vue的灵魂了,表面上看就是数据发生变化后,对应的界面会重新渲染,那么响应 ...
- 深度解析 Vue 响应式原理
深度解析 Vue 响应式原理 该文章内容节选自团队的开源项目 InterviewMap.项目目前内容包含了 JS.网络.浏览器相关.性能优化.安全.框架.Git.数据结构.算法等内容,无论是基础还是进 ...
- vue响应式原理解析
# Vue响应式原理解析 首先定义了四个核心的js文件 - 1. observer.js 观察者函数,用来设置data的get和set函数,并且把watcher存放在dep中 - 2. watcher ...
随机推荐
- 聊聊 Feign 的实现原理
What is Feign? Feign 是⼀个 HTTP 请求的轻量级客户端框架.通过 接口 + 注解的方式发起 HTTP 请求调用,面向接口编程,而不是像 Java 中通过封装 HTTP 请求报文 ...
- 『无为则无心』Python序列 — 18、Python列表概念及常用操作API
目录 1.列表的概念 (1)列表的定义 (2)列表的应用场景 (3)列表的定义格式 2.列表的常用操作 (1)列表的查找 1)通过下标查找 2)通过方法查找 3)判断是否存在 (2)列表的增加 @1. ...
- 99、centos下安装teamviewer
99.1.teamviewer简介: TeamViewer是一个能在任何防火墙和NAT代理的后台用于远程控制的应用程序,桌面共享和文件传输的简单且快速的解决方案. 为了连接到另一台计算机,只需要在两台 ...
- 6、基本数据类型(list)
6.1.列表: 1.li = [1, 12, 9, "age", ["孙子涵", ["19", 10], "张涵予"], ...
- 跟我一起学Go系列:Go gRPC 安全认证机制-SSL/TLS认证
Go gRPC 系列: 跟我一起学Go系列:gRPC 拦截器使用 跟我一起学Go系列:gRPC 入门必备 第一篇入门说过 gRPC 底层是基于 HTTP/2 协议的,HTTP 本身不带任何加密传输功能 ...
- C# datagridview 这是滚动条位置
1.datagridview 设置 表格内容铺满,内容自动换行 dataGridView1.DefaultCellStyle.WrapMode = DataGridViewTriState.True; ...
- AcWing 244. 谜一样的牛
有n头奶牛,已知它们的身高为 1~n 且各不相同,但不知道每头奶牛的具体身高. 现在这n头奶牛站成一列,已知第i头牛前面有a头牛比它低,求每头奶牛的身高. #include<bits/stdc+ ...
- 资源:CentOS下载地址资源
新版本系统镜像下载(当前最新是CentOS 7.4版本) CentOS官网 官网地址 http://isoredirect.centos.org/centos/7.4.1708/isos/x86_64 ...
- Parrot os 安装vmtools
1.更新源(这步个人觉得官方源还可以,没网上说的那么慢) vim /etc/apt/sources.list.d/parrot.list linux命令 ,按i进入修改模式,修改结束,之后先按esc, ...
- Linux | 压缩与解压详解
tar tar 命令用于对文件进行打包压缩或解压,格式: tar [选项][文件] tar命令的参数及其作用 参数 作用 -c 创建压缩文件 -x 解开压缩文件 -t 查看压缩包内有哪些文件 -z 用 ...