Open lbwa opened 6 years ago
MVVM
👉 MVVM架构模式
👉 Repo: vue-reactive
Model
ViewModel
Vue.js
View
this.$data[key] === this[key]
Vue.js 现阶段使用 Object.defineProperty(Reflect.defineProperty 将逐步取代之) 实现数据代理。
Object.defineProperty
Reflect.defineProperty
// src/core/instance/state.js const baseDescription = { enumerable: true, configurable: true, get: function () {}, set: function () {} } function defineProxy (target, sourceKey, key) { baseDescription.get = function proxyGetter () { return this[sourceKey][key] } baseDescription.set = function proxySetter (value) { this[sourceKey][key] = value } Reflect.defineProperty(target, key, baseDescription) } // 简单实现数据代理 const vm = { data: { name: 'John Wick', num: 20 } } const keys = Object.keys(vm.data) const len = keys.length for (let i = 0; i < len; i++) { defineProxy(vm, 'data', key[i]) // vm: { data: {...}, name: 'John Wick', num: 20 } }
同时,ES2015 中新增的 Proxy 方法同样可以实现数据代理,在 Vue.js 3 中 Proxy 可能代替 Object.defineProperty
Proxy
// 示例 1 const target = { keys: { name: 'I am a original object.' } } const handle = { get (target, key) { return key in target.keys? target.keys[key] : console.error(`There is no '${key}' in `, target.keys) } } // 通过 Proxy 实例来读取被代理的对象的键值 const proxy = new Proxy(target, handle) proxy.name // 'I am a original object.' // 示例 2 const target = { keys: { name: 'I am a original object' }, // getter 函数必须在 target 的对象内设置,而非在 receiver 设置 get name() { return this.keys.name } } /** * 1. receiver 仅起到提供 键值 的作用,不在其中设置 getter 或 setter。当遇到 * target 内有 getter 函数时,将 receiver 提供给 target 中的 getter 函数 */ const receiver = { keys: { name: 'I am a super object' } } Reflect.get(target, 'name', receiver) // "I am a super object" // 示例 3 const target = { keys: { name: 'I am a original object' }, // getter 函数必须在 target 的对象内设置,而非在 receiver 设置 get name() { return this.name } } // receiver 仅起到提供 键值 的作用,不在其中设置 getter 或 setter const receiver = { name: 'I am a super object' } const handle = { // 此处若传入第三个参数,那么第三个参数将表示当前的 proxy 实例 get (target, key) { return Reflect.get(target, key, receiver) // 相当于 target.keys[key] 作用 } } const proxy = new Proxy(target, handle) proxy.name // 'I am a super object'
MVVM
框架的个人见解👉 MVVM架构模式
响应式原理以及数据双向绑定
👉 Repo: vue-reactive
Model
经由ViewModel
(Vue.js
) 绑定View
;监听View
变化以通过ViewModel
更新Model
。数据代理实现
this.$data[key] === this[key]
成立。Vue.js
现阶段使用Object.defineProperty
(Reflect.defineProperty
将逐步取代之) 实现数据代理。同时,ES2015 中新增的
Proxy
方法同样可以实现数据代理,在 Vue.js 3 中 Proxy 可能代替Object.defineProperty