Vue响应式底层原理
1、核心逻辑
发布订阅模式 + 数据劫持
2、代码实现
2.1、发布订阅
/**
* 发布订阅器
*/
let Dep = {
//容器:保存所有订阅者的列表
clientList: {},
//订阅方法
listen: function(key, fn){
(this.clientList[key] || (this.clientList[key] = [])).push(fn);
},
//发布方法
trrigger: function(){
//获取key
let key = Array.prototype.shift.call(arguments);
//获取方法
let fns = this.clientList[key];
if(!fns || fns.length === 0){
return false;
}else{
for(let i = 0; i < fns.length; i++){
let fn = fns[i];
fn.apply(this, arguments);
}
}
}
}
2.2、数据劫持
/**
* 数据劫持
*/
let dataHijack = function({data, key, tag, selector}){
//数据信息
let value = "";
let element = document.querySelector(selector);
//数据劫持
Object.defineProperty(data, key, {
get(){
console.log("获取值");
return value;
},
set(newVal){
value = newVal;
console.log("设置值");
//发布方法
Dep.trrigger(tag, newVal);
return value;
}
});
//订阅方法
Dep.listen(tag, function(text){
element.innerHTML = text;
});
}
2.3、HTML页面使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<div>订阅视图1:<span class="box-1"></span></div>
<div>订阅视图2:<span class="box-2"></span></div>
</div>
</body>
<script type="text/javascript" src="./index.js"></script>
<script>
//数据信息
var obj = {};
//订阅第一个
dataHijack({
data: obj,
key: "one",
tag: "view-1",
selector: ".box-1"
});
//订阅第二个
dataHijack({
data: obj,
key: "two",
tag: "view-2",
selector: ".box-2"
});
</script>
</html>
2.4、验证
3、注意
需要先订阅在发布才能生效