Vue.observable源码解读(by实例)

Vue.observable

官方文档:https://cn.vuejs.org/v2/api/#Vue-observablehtml

实例: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就成全局响应式对象了,

拓展:函数

思想来源:观察者模式 vs 发布订阅模式

发布了22 篇原创文章 · 获赞 20 · 访问量 2万+
相关文章
相关标签/搜索