通过发布订阅者模式+数据劫持来实现。
发布订阅者模式:
三要数:容器、订阅、发布
代码演示:
// 订阅者容器 let Dep = { //容器 rongqi: {}, //订阅函数 dingyue: function (key, fn) { if (!this.rongqi[key]) { this.rongqi[key] = [] // 如果不存在,构建容器 } this.rongqi[key].push(fn) //添加内容 }, //发布函数 fabu: function () { //取第一个实参 例如(11,21)取11 把类数组转为数组(arguments是类数组) let keys = Array.prototype.shift.call(arguments); //拿到当前的这一项 fns = this.rongqi[keys]; if (!fns || fns.length === 0) { return false; } for (let i = 0; i < fns.length; i++) { //调用fns里面的所有方法 fns[i].apply(this, arguments); } } }
数据劫持:
//数据劫持
/*
data -->要劫持的数据
tag -->具体的目标元素
datakey -->目标元素的key
selector -->选择器
*/
let dataHi = function ({ data, tag, datakey, selector }) {
let value = ''
el = document.querySelector(selector);
Object.defineProperty(data, datakey, {
get: function () {
console.log("取值")
return value
},
set: function (val) {
console.log("设置值");
value = val
//发布
Dep.fabu(tag,val)
}
})
//订阅
Dep.dingyue(tag,function(text){
el.innerHTML = text
})
}
页面实现:
<body> <div> 订阅者试图-1:<span class="box-1"></span> 订阅者试图-2:<span class="box-2"></span> </div> <script src="./index.js"></script> <script> let obj = {} dataHi({ data:obj, tag:"view-1", datakey:'one', selector:'.box-1' }) dataHi({ data:obj, tag:"view-2", datakey:'two', selector:'.box-2' }) obj.one = "aa" obj.two = "bb" </script> </body>