基于 Object.defineProperty 通过 setter/getter 方法来监听数据的变化。 getter 进行依赖收集,setter 在数据变更的时候通知订阅者,递归调用监听对象的所有属性。
缺点:
function defineReactive(obj, key, value) {
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get() {
console.log('get', obj, key, value)
return value
},
set(newVal) {
observe(newVal)
if (newVal !== value) {
console.log('set', obj, key, newVal)
value = newVal
}
}
})
}
function observe(obj) {
if (!obj || typeof obj !== 'object') {
return
}
Object.keys(obj).forEach(key => {
const value = obj[key]
observe(value)
defineReactive(obj, key, obj[key])
})
}
const data = { a: { b: 1 } }
observe(data)
data.a.b = 2
优点:
const handler = {
get(target, key) {
if (typeof target[key] == 'object' && target[key] !== null) {
return new Proxy(target[key], handler)
}
console.log('set', key)
return Reflect.get(target, key)
},
set(target, key, value) {
if (key === 'length') return true
console.log('set', value)
return Reflect.set(target, key, value)
}
}
const data = { a: { b: 1 } }
const proxy = new Proxy(data, handler)
proxy.a.b = 2
两个关键类:
流程:
vuex 中的 store 本质就是没有 template 的 vue 组件
在打包之前,有两者的入口文件:
在打包之后,有两个 bundle 文件:
同构渲染:同一份代码,服务端先渲染生成 HTML(Dehydrate),客户端拿到代码后运行 JS ,进行客户端激活(Client-Side Hydration,CSH)的过程。