vue响应式原理——发布订阅,数据劫持
订阅器模型
// 订阅器模型
const Dep = {
clientList: {},
// 订阅
listen(key, fn) {
(this.clientList[key] ??= []).push(fn)
},
// 发布
trigger() {
const key = Array.prototype.shift.call(arguments)
const fns = this.clientList[key]
if (!fns || fns.length === 0) return
for (let i = 0, fn; fn = fns[i++];) {
fn.apply(this, arguments)
}
}
}
Object.defineProperty 数据劫持
/**
* 数据劫持
* @param {object} val 传递的对象
* @param {object} val.data 被劫持的对象
* @param {string} val.tag 唯一的key
* @param {string} val.datakey 被监听对象的属性
* @param {string} val.selector 获取dom元素的选择器
*/
const dataHi = ({
data,
tag,
datakey,
selector
}) => {
let value = ''
const el = document.querySelector(selector)
// 订阅
Dep.listen(tag, (text) => {
el.innerHTML = text
})
Object.defineProperty(data, datakey, {
get() {
console.log('取值')
return value
},
set(val) {
console.log('写值')
value = val
// 发布
Dep.trigger(tag, val)
}
})
}
使用
- 然后改变 data.one 的值就可以对应的改变 dom 元素
const obj = {}
dataHi({
data: obj,
tag: 'view-1',
datakey: 'one',
selector: '.box-1'
})
本文来自博客园,作者:懒惰ing,转载请注明原文链接:https://www.cnblogs.com/landuo629/p/16696434.html