问: 如何实现响应式
答: 发布订阅模式 + 双向数据绑定
响应式的代码(index.js):
// 订阅模型器
let Dep = {
clientList: {},
// 添加订阅者
listen: function(key, fn) { // key可以看作唯一的ID fn不同的种类
// if(!this.clientList[key]) {
// this.clientList[key] = []
// }
// this.clientList[key].push(fn)
// 上面的注释代码可以用下面的短路表达式一行写出
(this.clientList[key] || (this.clientList[key] = [])).push(fn)
}
// 推送方法
trigger: function() {
let key = Array.prototype.shift.call(arguments)
let fns = this.clientList[key];
if(!fns || fns.length === 0) {
return false;
}
for(let i = 0, fn; fn = fns[i++];) {
fn.apply(this, arguments) // this是指向当前这个人 arguments是附带的参数
}
}
}
// 数据劫持
let dataHijack = function({data, tag, datakey, selector}) {
let value = ""
let el = document.querySelector(selector);
Object.defineProperty(data, datakey, { // obj是侦听的对象 username是侦听的属性
get: function() {
console.log("取值")
return value
},
set: function(val) {
console.log("设置值")
value = val
// 数据变化了
Dep.trigger(tag, val)
}
})
// 添加订阅者
Dep.listen(teg, function(text){
el.innerHTML = text;
})
}
使用
html:
<div id="app">
订阅视图-1:<span class="box-1">1111</span>
订阅视图-2:<span class="box-2">2222</span>
</div>
script:
// 引入响应代码
<script src="./index.js"></script>
<script>
let dataObj = {}
dataHijack({
data: dataObj, // 数据源
tag: "view-1", // 目标对象 可以自己随便取名
datakey: 'one', // 这个也是自己随便取名 但是不能重复 必须是唯一的值
selector: '.box-1', // 这个是类名
})
dataHijack({
data: dataObj,
tag: "view-2",
datakey: 'two',
selector: '.box-2'
})
dataObj.one = "迪迦"
dataObj.two = "泰罗"
</script>
页面:
设置数据的时候响应式变化: