浅谈Vue的双向数据绑定原理
Vue常见数据绑定的方法:
<body>
<div id="app">
<div id="msg">{{msg}}</div>
<input type="text" name="" id="" v-model = 'msg'>
<!-- v-model 是一个指令,用于双向数据绑定 -->
</div>
<script src="../js/vue.js"></script>
<script>
new Vue({
el : '#app',
data :{
msg : 'hello tianqin'
}
})
</script>
</body>
核心:数据代理 + 发布与订阅
来自Vue文档:
当把一个普通的JavaScript对象传给Vue实例的data选项,Vue将遍历此对象所有的属性,使用Object.defineProperty把这些属性全部转为getter/setter(数据劫持/数据映射)。在属性被访问和修改时通知变化。每个组件实例都有相应的 watcher 实例对象,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的 setter 被调用时,会通知 watcher 重新计算,从而致使它关联的组件得以更新。
Object.defineProperty(obj,prop,descriptor)核心方法:
obj
要定义属性的对象。
prop
要定义或修改的属性的名称 。
descriptor
要定义选项。
接下来用原生的js实现一下
<body>
<div id="msg"></div>
<input type="text" id="ipt" oninput="changeVal(this)"> 句柄的方式绑定一个事件
<script>
// 1 : 定义一个源数据
var data = {
msg : 'hello tianqin'
};
// 4 : 定义一个watcher 数据劫持
var obj = {}
Object.defineProperty(obj,'msg',{
get(){
// 获取msg的值
return data.msg
},
set(datas){
// 设定msg的值 ,更新页面(渲染)
data.msg = datas;
document.getElementById('msg').innerHTML = datas;
return true ;
}
})
//2 : 将数据显示到页面中,也就是渲染
document.getElementById('msg').innerHTML = obj.msg;
document.getElementById('ipt').value = obj.msg;
//3 : change
function changeVal(ele) {
// 获取改变之后更新的值
const iptVal = ele.value
obj.msg = iptVal;
}
</script>
</body>