一.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. 案例 | 腾讯广告 AMS 的容器化之路

    作者 张煜,15年加入腾讯并从事腾讯广告维护工作.20年开始引导腾讯广告技术团队接入公司的TKEx-teg,从业务的日常痛点并结合腾讯云原生特性来完善腾讯广告自有的容器化解决方案 项目背景 腾讯广告承 ...

  2. 95、配置ntp服务器

    95.1.ntp简介: ntp服务使用的是udp的123端口,如果开启了防火墙要记得放开这个端口: NTP(Network Time Protocol,网络时间协议)是用来使网络中的各个计算机时间同步 ...

  3. CSS水平居中与垂直居中的方法

    一.水平居中 1.行内元素水平居中 在父元素里添加text-align:center即可.代码如下: <style> .container-1 { height: 50px; border ...

  4. Linux:Ubuntu银河麒麟防火墙操作

    查看防火墙状态 #防火墙状态 sudo ufw status inactive状态是防火墙 关闭 状态 active状态是防火墙 开启 状态 开启防火墙 #开启防火墙 sudo ufw enable ...

  5. <c:out>标签不能正确输出value中的值

    问题: 我打算在jsp中输出request中的值,它的key为username, <c:out value="${requestScope.username}"/> 但 ...

  6. postgresql分组后获取第一条数据

    -- 根据编号分组取第一条数据 select * from table t where t.no=(select max(no) from table t1 where t1.no=t.no) -- ...

  7. 『心善渊』Selenium3.0基础 — 30、UI自动化测试之POM设计模式

    目录 (一)POM模式介绍 1.什么是POM介绍 2.为什么要使用POM模式 3.POM的优势 4.POM模式封装思路 (1)POM模式将页面分成三层 (2)POM模式的核心要素(重点) (3)总结 ...

  8. python使用笔记11--时间模块

    1.时间模块常用方法 1 import time,datetime 2 #格式化好的时间2020-05-16 18:30:52 3 #时间戳1589616753 从unix元年(计算机发明的时间)到现 ...

  9. Linux下面向TCP连接的C++ Socket编程实例

    Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.即Socket提供了操作上述特殊文件的接口,使用这些接口可以实现网络编程. Socket通信流程图 TCP(Transmis ...

  10. python得到当前版本号

    import sys print(sys.winver) 3.7 # 导入sys模块的argv,winver成员,并为其指定别名v.wv from sys import argv as v, winv ...