一.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响应式原理及发布订阅模式和观察者模式的更多相关文章

  1. 浅谈Vue响应式(数组变异方法)

    很多初使用Vue的同学会发现,在改变数组的值的时候,值确实是改变了,但是视图却无动于衷,果然是因为数组太高冷了吗? 查看官方文档才发现,不是女神太高冷,而是你没用对方法. 看来想让女神自己动,关键得用 ...

  2. Vue源码--解读vue响应式原理

    原文链接:https://geniuspeng.github.io/2018/01/05/vue-reactivity/ Vue的官方说明里有深入响应式原理这一节.在此官方也提到过: 当你把一个普通的 ...

  3. 详解Vue响应式原理

    摘要: 搞懂Vue响应式原理! 作者:浪里行舟 原文:深入浅出Vue响应式原理 Fundebug经授权转载,版权归原作者所有. 前言 Vue 最独特的特性之一,是其非侵入性的响应式系统.数据模型仅仅是 ...

  4. vue响应式原理,去掉优化,只看核心

    Vue响应式原理 作为写业务的码农,几乎不必知道原理.但是当你去找工作的时候,可是需要造原子弹的,什么都得知道一些才行.所以找工作之前可以先复习下,只要是关于vue的,必定会问响应式原理. 核心: / ...

  5. 深入Vue响应式原理

    深入Vue.js响应式原理 一.创建一个Vue应用 new Vue({ data() { return { name: 'yjh', }; }, router, store, render: h =& ...

  6. 浅析Vue响应式原理(三)

    Vue响应式原理之defineReactive defineReactive 不论如何,最终响应式数据都要通过defineReactive来实现,实际要借助ES5新增的Object.definePro ...

  7. 深入解析vue响应式原理

    摘要:本文主要通过结合vue官方文档及源码,对vue响应式原理进行深入分析. 1.定义 作为vue最独特的特性,响应式可以说是vue的灵魂了,表面上看就是数据发生变化后,对应的界面会重新渲染,那么响应 ...

  8. 深度解析 Vue 响应式原理

    深度解析 Vue 响应式原理 该文章内容节选自团队的开源项目 InterviewMap.项目目前内容包含了 JS.网络.浏览器相关.性能优化.安全.框架.Git.数据结构.算法等内容,无论是基础还是进 ...

  9. vue响应式原理解析

    # Vue响应式原理解析 首先定义了四个核心的js文件 - 1. observer.js 观察者函数,用来设置data的get和set函数,并且把watcher存放在dep中 - 2. watcher ...

随机推荐

  1. NoSql非关系型数据库之MongoDB应用(一):安装MongoDB服务

    业精于勤,荒于嬉:行成于思,毁于随. 一.MongoDB服务下载安装(windows环境安装) 1.进入官网:https://www.mongodb.com/,点击右上角的 Try Free  , 2 ...

  2. C# DataGridView单元格画斜线

    功能要求:不符合条件的单元格使用斜线形式表现出来. 1.定义两个变量,一个是存储单元格位置的数组,一个是Graphics 变量 Graphics gdi; List<DataGridViewCe ...

  3. AcWing 220. 最大公约数

    给定整数N,求1<=x,y<=N且GCD(x,y)为素数的数对(x,y)有多少对. GCD(x,y)即求x,y的最大公约数. #include<bits/stdc++.h> u ...

  4. 暑假自学java第十天

    1,声明数组:声明一维数组的格式有两种 一:数组元素类型 数组名字 [ ]:例如: float score [ ]; 二:数组元素类型 [ ] 数组名字: 例如: float [ ]  score; ...

  5. springboot整合拦截器如何让其不拦截默认的访问路径

    1.注册自定义拦截器2.拦截器3.控制器4.其它说明:我想做控制拦截登陆,将所有的请求拦截下来判断如果当前的session里没有用户名则跳转到登陆页面.问题是目前可以拦截所有请求了,但第一次进入登陆页 ...

  6. vim下出现^M怎么解决

    将window下的文本文件上传到linux上,在读取数据文件时,在每一行数据后会出现^M字符.   为什么会出现这种情况呢: 因为windows.linux.os系统的换行符标准不同: 先了解下概念, ...

  7. 16 shell select in 循环

    select in 是 Shell 独有的一种循环,适用于与终端(Terminal)进行交互,在其他编程语言中是没有的. 用法 说明 脚本 select var in val_listdo    st ...

  8. easyswoole实现线上更新代码

    众所周知,easyswoole作为常驻内存的框架,修改代码并不能直接生效,而是需要重启服务,那么,当你的easyswoole项目上线之后,该如何保证旧请求的同时去更新代码呢? nginx reload ...

  9. php curl处理get和post请求

    CURL 是一个利用URL语法规定来传输文件和数据的工具,支持很多协议,如HTTP.FTP.TELNET等.最爽的是,PHP也支持 CURL 库.使用PHP的CURL 库可以简单和有效地去抓网页.你只 ...

  10. Jsp自定义标签,配置tld文件

    Program:Jsp自定义标签,.tld文件的配置 1 <?xml version="1.0" encoding="UTF-8" ?> 2 3 & ...