-
1、页面–>数据模型层:
原理:给元素添加事件监听完成 例如给input标签添加input事件来改变value值。
-
2、数据模型层–>页面:
原理:通过数据劫持和发布订阅实现 数据劫持:拦截数据的变化,常用方案:Object.defineProperty和Proxy Vue2.0 用的是Object.defineProperty Vue3.0 用的是Proxy
//数据劫持
<script type="text/javascript">
var book =[]
Object.defineProperty(book,'name',{
//外部给name赋值的时候执行
set:function(value){
name=value
console.log('set你买了一本书'+value)
},
//外部获取name值的时候执行
get:function(){
console.log('get你的书来啦'+name)
return '<<'+name+'>>'
}
})
book.name="Vue权威指南" //set 这里是赋值,所以会先触发set方法,打印:set你买了一本书Vue权威指南
console.log(book.name) //这里是获取值,所以会先触发get方法 打印:你的书来啦Vue权威指南
book.name="Vue权威指南2"//set 这里是赋值,所以会先触发set方法,打印:set你买了一本书Vue权威指南2
console.log(book.name,'2222') //这里是获取值,所以会先触发get方法 打印:你的书来啦Vue权威指南2
</script>
打印信息:
发布订阅示例:
刚刚我们已经实现了数据劫持,那么下面我们要实现的是当数据改变时,要让页面更新。
<body>
<input type="" name="" id="inputA" value="" />+
<input type="" name="" id="inputB" value="" />
<button type="button" id="btn">=</button>
<input type="" name="" id="inputC" value="" />
</body>
我们输入两个数字,让第三个输入框显示两个数之和。输入框A、B它们的数据流向是页面到数据模型
层,那么可以通过监听输入框的onInput事件来更改数据。
那么InputC则可以通过Object.defineProperty的set方法,当valueC被赋值时候,触发刷新
代码如下:
<body>
<input type="" name="" id="inputA" value="" />+
<input type="" name="" id="inputB" value="" />
<button type="button" id="btn">=</button>
<input type="" name="" id="inputC" value="" />
</body>
<script type="text/javascript">
var data={
valueC:''
}
//发布订阅
//订阅器构造函数
function DingYueQi(){
this.watchers=[]
}
DingYueQi.prototype.addWatcher=function(watcher){
this.watchers.push(watcher)
}
DingYueQi.prototype.notifyWatcher=function(value){
this.watchers.forEach(item=>{
item.update(value)
})
}
//观察者构造函数
function Watchers(target){
this.InputC=target
}
Watchers.prototype.update=function(value){
this.InputC.value=value
}
//创建一个观察者
var InputC=new Watchers(document.getElementById('inputC'))
//创建一个订阅器
var myDingYue=new DingYueQi()
myDingYue.addWatcher(InputC)
//数据劫持(这里只演示valueC)
Object.defineProperty(data,'valueC',{
set:function(value){
valueC=value
console.log('set')
myDingYue.notifyWatcher(value)
},
get:function(){
return valueC
}
})
var inputA=document.getElementById('inputA')
var inputB=document.getElementById('inputB')
var btn=document.getElementById('btn')
btn.addEventListener('click',()=>{
console.log(inputA.value,inputB.value,'544')
data.valueC=inputA.value*1.0+inputB.value*1.0
console.log(data.valueC,'44')
})
</script>