Vue.observable
实例:Vue.observablevue
<body> <div id="root"> {{message}} <button @click="change">Change</button> </div> <script> const state = Vue.observable({ message: 'Vue 2.6' }) const mutation = { setMessage(value) { state.message = value } } new Vue({ el: '#root', computed: { message() { return state.message } }, methods: { change() { mutation.setMessage('Vue 3.0') } } }) </script> </body>
官方解释:react
Vue.observable(object) 是vue2.6版本新增的全局API,它能够让一个对象可响应。Vue 内部会用它来处理 data 函数返回的对象。
返回的对象能够直接用于渲染函数和计算属性内,而且会在发生改变时触发相应的更新。也能够做为最小化的跨组件状态存储器,用于简单的场景
git
在 Vue 2.x 中,被传入的对象会直接被 Vue.observable 改变;在 Vue 3.x 中,则会返回一个可响应的代理,而对源对象直接进行修改仍然是不可响应的。所以,为了向前兼容,官方推荐始终操做使用 Vue.observable 返回的对象,而不是传入源对象。vuex
通俗来讲,Vue.observable在简单场景下能够代替vuexapi
本示例中Vue.observable执行流程:数组
- 首先initGlobalAPI (vue.js:5406)
- 执行Vue.observable内容
// 2.6 explicit observable API Vue.observable = function (obj) { observe(obj); return obj };
- vue初始化
- 使用计算属性将state.message渲染到页面
- 点击按钮
- 执行change()
- 执行setMessage(),修改state.message的值
- 使用计算属性将新的state.message值渲染到页面
能够看出Vue.observable实际就是封装了observe:
markdown
- 首先判断是否包含__ob__这个属性
- 实例化一个Observer对象:
- 因为本实例中传入的不是数组,进入walk()
- 在walk中遍历key,并使用defineReactive$$1建立响应式对象
Walk through all properties and convert them into getter/setters. This method should only be called when value type is Object.
遍历全部属性并将它们转换为getter/setter。仅当值类型为Object时才应调用此方法。
ide
- 经过property.get进行取值,经过property.set进行赋值
- 接下来调用Object.defineProperty()给对象定义响应式属性(Object.defineProperty是vue.js实现「响应式系统」的关键之一)
- enumerable,属性是否可枚举,默认 false。
- configurable,属性是否能够被修改或者删除,默认 false。
- get,获取属性的方法。(进行依赖收集)(数据劫持)
- set,设置属性的方法。(进行响应式更新)
- dep.notify():经过dep.notify()对观察者watchers进行通知
- 而后state就成全局响应式对象了,
拓展:函数
- 深刻响应式原理 — Vue.js
- vue原理探索–响应式系统
- Vue setter/getter 是何原理?
- 深刻解析Vue依赖收集原理
- Vue 核心之数据劫持
- Vue源码解读之Dep,Observer和Watcher
思想来源:观察者模式 vs 发布订阅模式