一、Observable 是什么

Observable 翻译过来我们可以理解成可观察的

我们先来看一下其在Vue中的定义

Vue.observable,让一个对象变成响应式数据。Vue 内部会用它来处理 data 函数返回的对象

返回的对象可以直接用于渲染函数和计算属性内,并且会在发生变更时触发相应的更新。也可以作为最小化的跨组件状态存储器

Vue.observable({ count : 1})

其作用等同于

new vue({ count : 1})

Vue 2.x 中,被传入的对象会直接被 Vue.observable 变更,它和被返回的对象是同一个对象

Vue 3.x 中,则会返回一个可响应的代理,而对源对象直接进行变更仍然是不可响应的

二、使用场景

在非父子组件通信时,可以使用通常的bus或者使用vuex,但是实现的功能不是太复杂,而使用上面两个又有点繁琐。这时,observable就是一个很好的选择

创建一个js文件

// 引入vue
import Vue from 'vue
// 创建state对象,使用observable让state对象可响应
export let state = Vue.observable({name: '张三','age': 38
})
// 创建对应的方法
export let mutations = {changeName(name) {state.name = name},setAge(age) {state.age = age}
}

.vue文件中直接使用即可

<template><div>姓名:{{ name }}年龄:{{ age }}<button @click="changeName('李四')">改变姓名</button><button @click="setAge(18)">改变年龄</button></div>
</template>
import { state, mutations } from '@/store
export default {// 在计算属性中拿到值computed: {name() {return state.name},age() {return state.age}},// 调用mutations里面的方法,更新数据methods: {changeName: mutations.changeName,setAge: mutations.setAge}
}

三、原理分析

源码位置:src\core\observer\index.js

export function observe (value: any, asRootData: ?boolean): Observer | void {if (!isObject(value) || value instanceof VNode) {return}let ob: Observer | void// 判断是否存在__ob__响应式属性if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {ob = value.__ob__} else if (shouldObserve &&!isServerRendering() &&(Array.isArray(value) || isPlainObject(value)) &&Object.isExtensible(value) &&!value._isVue) {// 实例化Observer响应式对象ob = new Observer(value)}if (asRootData && ob) {ob.vmCount++}return ob
}

Observer

export class Observer {value: any;dep: Dep;vmCount: number; // number of vms that have this object as root $dataconstructor (value: any) {this.value = valuethis.dep = new Dep()this.vmCount = 0def(value, '__ob__', this)if (Array.isArray(value)) {if (hasProto) {protoAugment(value, arrayMethods)} else {copyAugment(value, arrayMethods, arrayKeys)}this.observeArray(value)} else {// 实例化对象是一个对象,进入walk方法this.walk(value)}
}

walk函数

walk (obj: Object) {const keys = Object.keys(obj)// 遍历key,通过defineReactive创建响应式对象for (let i = 0; i < keys.length; i++) {defineReactive(obj, keys[i])}
}

defineReactive方法

export function defineReactive (obj: Object,key: string,val: any,customSetter?: ?Function,shallow?: boolean
) {const dep = new Dep()const property = Object.getOwnPropertyDescriptor(obj, key)if (property && property.configurable === false) {return}// cater for pre-defined getter/settersconst getter = property && property.getconst setter = property && property.setif ((!getter || setter) && arguments.length === 2) {val = obj[key]}let childOb = !shallow && observe(val)// 接下来调用Object.defineProperty()给对象定义响应式属性Object.defineProperty(obj, key, {enumerable: true,configurable: true,get: function reactiveGetter () {const value = getter ? getter.call(obj) : valif (Dep.target) {dep.depend()if (childOb) {childOb.dep.depend()if (Array.isArray(value)) {dependArray(value)}}}return value},set: function reactiveSetter (newVal) {const value = getter ? getter.call(obj) : val/* eslint-disable no-self-compare */if (newVal === value || (newVal !== newVal && value !== value)) {return}/* eslint-enable no-self-compare */if (process.env.NODE_ENV !== 'production' && customSetter) {customSetter()}// #7981: for accessor properties without setterif (getter && !setter) returnif (setter) {setter.call(obj, newVal)} else {val = newVal}childOb = !shallow && observe(newVal)// 对观察者watchers进行通知,state就成了全局响应式对象dep.notify()}})
}

参考文献

  • https://blog.csdn.net/qq_32682301/article/details/105419673

  • https://wbbyouzi.com/archives/343

  • https://vue3js.cn/docs/zh

面试官VUE系列总进度:16/33

面试官:SPA(单页应用)首屏加载速度慢怎么解决?

面试官:Vue中组件和插件有什么区别?

面试官:为什么data属性是一个函数而不是一个对象?

面试官:Vue中给对象添加新属性界面不刷新?

面试官:Vue实例挂载的过程中发生了什么?

面试官:Vue中的$nextTick怎么理解?

面试官:说说你对vue的mixin的理解,有哪些应用场景?

面试官:说说你对slot的理解?slot使用场景有哪些?

篇副有限,扫下方二维码查看往期

面试官:说说对observable的理解相关推荐

  1. 京东面试官:你是怎么理解 MySQL 的优化原理的?

    说起MySQL的查询优化,相信大家收藏了一堆奇技淫巧:不能使用 SELECT*.不使用NULL字段.合理创建索引.为字段选择合适的数据类型..... 你是否真的理解这些优化技巧?是否理解其背后的工作原 ...

  2. 面试官问我JVM内存结构,我真的是

    面试官:今天来聊聊JVM的内存结构吧? 候选者:嗯,好的 候选者:前几次面试的时候也提到了:class文件会被类加载器装载至JVM中,并且JVM会负责程序「运行时」的「内存管理」 候选者:而JVM的内 ...

  3. 字节跳动资深面试官亲述:java进阶篇

    准备好套路 **①自我介绍:**千万不能筐瓢,一定要牢记,自然流畅地介绍自己的学习经历.工作经历.项目经历.个人优势等等: **②抽象概念:**当面试官问你是如何理解多线程的时候,你要知道从定义.来源 ...

  4. 跟Java面试官对线的一天!唬住就要50K,唬不住就要5K

    个人面经 前言 JVM篇 计网篇 Java基础篇 多线程篇 Spring框架篇 MyBatis框架篇 MySQL篇 Redis篇 分布式.微服务篇 小结 前言 不积跬步无以至千里,不积小流无以成江海 ...

  5. 程序员面试,面试官更注重代码量、项目经验还是操作系统、数据结构这种基础课程?...

    作者 张小方 如需转载,请联系原作者授权. 我去年12月份从上一家公司离职,一直到今年3月份,基本上都在面试中度过来的. 先交代下背景:坐标上海,做技术开发,我本人求职的职位是linux服务器开发,最 ...

  6. 代码量?项目经验?面试官你到底要看程序员哪一点

    张小方|高性能服务器开发 我去年 12 月份从上一家公司离职,一直到今年 3 月份,基本上都在面试中度过来的. 先交代下背景:坐标上海,做技术开发,我本人求职的职位是linux服务器开发,最倾向的职位 ...

  7. 程序员面试,面试官更注重代码量、项目经验还是操作系统、数据结构这种基础课程?

    作者 张小方 我去年12月份从上一家公司离职,一直到今年3月份,基本上都在面试中度过来的. 先交代下背景:坐标上海,做技术开发,我本人求职的职位是linux服务器开发,最倾向的职位是服务器开发主程或技 ...

  8. 后处理程序文件大小的变量_【每日一题】(17题)面试官问:JS中事件流,事件处理程序,事件对象的理解?...

    关注「松宝写代码」,精选好文,每日一题 作者:saucxs | songEagle 2020,实「鼠」不易 2021,「牛」转乾坤 风劲潮涌当扬帆,任重道远须奋蹄! 一.前言 2020.12.23 立 ...

  9. 岗位理解_当面试官问求职者对应聘岗位的理解情况

    虽然求职是看的是岗责是否匹配自己的经历和能力,但是很多面试官还是会问这样的问题.对于求职者来说,对岗位的理解其实就是把岗位职责背一遍,但是面试官既然问了,就要说出一些其他内容来.想回答好这个问题,就要 ...

最新文章

  1. Java集合:HashMap源码剖析
  2. scala 样例类(case class) + 模式匹配代码示例
  3. Ubuntu系统下bash和dash的区别(修改默认sh为bash)
  4. [vue-element] ElementUI表格组件如何实现动态表头?
  5. 算法- 分治算法(实现汉诺塔)
  6. 论文浅尝 | DSKReG:基于关系GNN的推荐知识图谱可微抽样
  7. mysql工作中遇到的问题_MySQL工作中遇到的问题记录
  8. FreeEIM 2.0 beta 发布
  9. vSphere Web Client使用指南之安装配置
  10. mysql导出数据库视频教程_Navicat怎样导入导出sql文件?(图文步骤+视频教程)...
  11. 网易云音乐云盘存歌曲加歌词
  12. 企业打造营销型网站的7条黄金法则
  13. PMS(PackageManagerService)原理简单介绍,启动过程源码简单解析
  14. 赛尔号7月17日服务器维护,赛尔号07月17日更新攻略汇总 环城之光圣芒降临
  15. c++学习书籍推荐《C++程序设计语言(特别版)》下载
  16. php外语文献有哪些,外语论文参考文献
  17. torchaudio音频基础知识学习
  18. put: File COPYING could be replicated to 0 nodes instead of minReplication.There are 0 datanodes解决方案
  19. SQL 实验项目3_1-数据更新
  20. Es新规范-总结(Es5-Es10)

热门文章

  1. vue使用vue2-verify实现前端验证码(滑动,拼图,数字,选字验证)
  2. 月圆之夜-天赋系统策划案(完稿时间2021/6/15)
  3. Day03_HTML课堂笔记
  4. 详细解析漏洞4个boom !必读!
  5. python程序设计第三十讲_十佳教师 | Python程序设计+数据库技术+独特的授课方式+幽默风趣……=这位计算机教师!...
  6. php开发数独,php解数独 - AA星梦无痕AA的个人空间 - OSCHINA - 中文开源技术交流社区...
  7. touchstart, touchmove, touchend, mousedown, mousemove, mouseup, 手机端和pc端点击及触摸事件
  8. 6 密码学和对称密匙算法
  9. macos复制粘贴快捷键_如何在macOS上粘贴文本而不进行格式化
  10. 微软发布Windows10手机预览版 支持六款Lumia