背景
在vue中,通过v-model可实现数据和UI的双向绑定,即:当数据改变时,UI自动刷新;当UI改变时,数据自动更改。直接上代码,下面是JS版双向绑定简单实现:
代码
<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="div1">
<input type="text" v-my-model="name"><br>
姓名:{{name}}<br>
年龄:{{age}}
</div>
</body>
</body>
<script>
console.log('test.html');
//获取dom节点
let el=document.getElementById('div1');
let template=el.innerHTML;
//需要被保护和监听的数据
let _data = {
name: 'blue',
age: '18'
};
//创建代理对象 当_data数据被改变或读取时,可被监听到. Proxy 传两个参数 参数1 被保护监听的数据 参数2 一个JSON对象,里面有两个基础方法get set.
let data = new Proxy(_data, {
/**
* 改变数据
* @param {指被保护监听的数据_data} obj
* @param {JSON对象key} key
* @param {新的值} value
* @param {代理对象实例} receiver
*/
set(obj, key, value, receiver){
console.log('数据被改变:', obj, key, value, receiver);
obj[key] = value;
//在这里监听到数据变动后,可以做一些其他事情,比如UI的重新渲染等.
//...todo
render();
},
/**
* 获取数据
* @param {指被保护监听的数据_data} obj
* @param {JSON对象key} key
* @param {代理对象实例} receiver
* @returns
*/
get(obj, key, receiver){
console.log('数据被拿取:', obj, key, receiver);
return obj[key];
},
});
//首次渲染
render();
//UI刷新/渲染
function render(){
//渲染
el.innerHTML=template.replace(/\{\{\w+\}\}/g, str=>{
str=str.substring(2, str.length-2);
return _data[str];
});
//找所有的v-my-model
Array.from(el.getElementsByTagName('input'))
.filter(ele=>ele.getAttribute('v-my-model'))
.forEach(input=>{
let name=input.getAttribute('v-my-model');
input.value=_data[name];
input.oninput=function (){
data[name]=this.value;
};
});
}
console.log('拿取数据:', data.name);
data.age = 20;
</script>
</html>
备注:html文件运行后,可直接按F12,在控制台中运行:data.age++改变数据,可看到界面上的UI自动刷新。
核心思想
通过ES6中的proxy对象,实现对数据的变化监听,进而刷新界面UI,即:数据驱动。通过对输入框等界面UI回调事件的监听,实现数据的改变,即:数据刷新。
至此,完毕。