一、封装数据劫持+渲染页面
基本思想:将一个普通的数据劫持的代码封装为函数,并将原始对象里的键值对写入到页面,而我使用的方法是使用到了实际项目中,也就是框架中的模式去封装的。
下面代码以及每一句的注释都在代码里面了。执行结果可以自己将代码复制到自己的运行其运行。
基本代码:
<!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>
<-- html标签部分 -->
<div id="app">
<h1> {{name}} </h1>
<h1> {{age}} </h1>
<h1> {{sex}} </h1>
</div>
<script>
/*
数据验证与数据劫持部分
1.验证标签以及传入的实参是否不为空
2.对数据进行劫持的代码
*/
// 数据验证
// 封装一个验证数据的函数
function Observer(options){
// 数据验证部分
// 如果root属性为空 就创建一个错误抛出
if(options.root === undefined) throw new Error('您没有传递root属性,请重新传递');
// 如果data数据为空 就创建一个错误抛出
if(options.data === undefined) throw new Error('您没有传递data属性,请重新传递');
// 如果div标签(#app)为空 就创建一个错误抛出
const rootHTML = document.querySelector(options.root);
if(rootHTML == null) throw new Error('您没有正确传递root属性,请重新传递');
// 如果data属性传入的值不是一个对象 就创建一个错误抛出
if(options.root == Object) throw new Error('您传入的data属性的属性值不是一个对象,请重新传递');
// 数据劫持部分
// 创建一个空对象 用来存储劫持后的数据
const _data = {};
// 存储一份原始数据内容
let newDataStr = rootHTML.innerHTML;
// 循环遍历原始数组里面的所有data值
for(let k in options.data){
// 数据劫持
// 第一个参数: _data是劫持数据语法中的第一个属性 第一个属性写存储劫持数据的空对象_data
// 第二个参数:k是循环遍历实参中的所有数据 也就是劫持的数据
// 第三个参数:是劫持的的代码体
Object defineProperty(_data , k , {
// 获取options中的键名
get(){
return options.data[k];
},
// 修改或者设置里面的数据 也就是劫持后的
set(val){
options.data[k] = val;
},
})
}
// 最后返回劫持后的对象
return _data;
}
// 渲染页面
function rander(root , _data , newDataStr){
// 先定义一个正则 用来获取里面的字符串内容
let reg = /{{*\w+*}}/g;
// 获取里面的所有字符串内容 并以数组的形式存储
const res = rootHtmlStr.match(reg);
// 通过循环遍历截获到的数组
res.forEach(item => {
// console.log(item);
// 拿到花括号的文本 因为这是对象中的key
const key = reg.exec(rootHtmlStr)[1];
// console.log(key);
// 将原本花括号与内部文本 全部替换为对象中实际的值
rootHtmlStr = rootHtmlStr.replace(/{{*(\w+)*}}/, _data[key]);
console.log(rootHtmlStr);
});
// 重新将修改完毕的字符串 渲染到页面
root.innerHTML = rootHtmlStr;
}
</script>
<script>
/*
调用函数 并传入实参
*/
let o1 = new Observer(
root:"#app",
data:{
name:'张三',
age:18,
sex:'男',
}
)
console.log(o1);
</script>
</body>
</html>