后端程序员面试经常问到什么是vue的双向绑定?怎么实现的?
因为简历上写到了熟悉Vue,所以 emmm…
官方回答
采用数据劫持结合发布者-订阅者模式的方式,
通过Observe来监听数据变化,通过Compile来解析编译模版指令,利用watcher来架起通信桥梁。
虽然嘴上说的很专业,但是心里确很糊涂。
好吧,核心就是 Object.defineProperty. 定义对象的属性。以及定义其对象的规则。当我们设置这个属性的值时,就会默认执行 set 方法,当我们获取这个属性的值时,就会默认执行 get 方法。
var Person = {};
Object.defineProperty(Person,'name',{
writable: true,
configurable:true,
enumerable:true,
get:function(){
return name;
},
set:function(val){
name = val;
console.log('数据发生了改变')
}
});
思路 :在赋值触发set函数的时候进行数据劫持。
为什么说是理解版
因为我没做 watcher 和 compile,只是理解了核心的数据劫持。
大概说一下,Compile扫描每个节点的模版指令,初始化相应的Watcher。
Watcher收到属性的变化的通知以后,来更新视图。
function defineObserve(data, key, val) {
//data对象 key 属性名称 val 对应属性的值
//递归遍历所有子属性
Observe(val);
//设置数据拦截
Object.defineProperty(data, key, {
enumerable: true,
configurable: true,
//数据拦截
set: function (newVal) {
if(newVal==""||newVal==undefined){
val="暂无数据"
}
val = newVal;
console.log("数据发生了改变。新的值为:" + newVal)
document.getElementById("root").innerHTML = newVal;
},
get: function () {
return val;
}
});
}
function Observe(data) {
if (!data || typeof data != 'object') {
return;
}
Object.keys(data).forEach(function (key) {
//console.log(key)
defineObserve(data, key, data[key]);
});
}
var Data = {
Person: {
name: 'Vue-model',
age: 23
}
}
//绑定属性 => Person,name,age
Observe(Data);
document.getElementById("root").innerHTML = Data.Person.name;
//input oninput方法
function ChangeVal() {
Data.Person.name = document.getElementById('userVal').value;
}
<div id="root"></div>
</div>
<br>
<input oninput="ChangeVal()" type="text" placeholder="请输入" id="userVal" />
理解的不够深,如有不对的地方或错误的地方或有更好的写法请和告诉我哦~