解决昨天遗留的层级访问与代码整理
<!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>
<div id="root">
<p>{{name.firstName}}</p>
</div>
<script>
// // 解决层级问题 如何 使用 xx.xx.xx去访问某一个对象的属性
function getValueByPath(obj, path) {
let paths = path.split(".") // ef [xx,yy,zz]
// let res = null;
// res = paths[0];
// res = paths[1];
// res = paths[2];
let res = obj;
let prop;
// 数组的shift方法就是删除数组的第一个元素 并返回第一个元素的值
while (prop = paths.shift()) {
res = res[prop]
}
return res;
}
let rkuohao = /\{\{(.+?)\}\}/g;
function compiler(template, data) {
// 遍历他下面的子节点
let childrenNodes = template.childNodes;
for (let i = 0; i < childrenNodes.length; i++) {
//循环 判断是否是元素节点 还是文本节点 1是元素节点 3是文本节点 元素节点的nodeValue是没有意义的 文本节点的nodeName是没有意义的
let type = childrenNodes[i].nodeType;
if (type === 3) {
// 文本节点就去判断里面有没有 {{}}
let txt = childrenNodes[i].nodeValue;// 获取文本节点里面的值
// 有没有 {{}}
txt = txt.replace(rkuohao, function (_, g) {
let path = g.trim();
let value = getValueByPath(data, path);
return value;
})
// 注意现在txt与DOM没有关系 需要重新加回去
childrenNodes[i].nodeValue = txt;
} else if (type === 1) {
// 元素节点的话就去判断他有没有有子元素 查看子元素是否有插值语法 用到了递归
compiler(childrenNodes[i], data)
}
}
}
// 构造函数
function LikeVue(options) {
// 习惯私有的数据用下划线开头,$开头的一般都是只读数据(Vue中也是这样)
this._data = options.data;
this._el = options.el;
// 准备工作 (准备模板)
this._tempalteDOM = document.querySelector(this._el);
// 拿到它的父级元素 后面会用到节点操作
this._parentNode = this._tempalteDOM.parentNode;
// 渲染工作
this.render();
}
// render函数的作用就是将模板与数据结合得到HTML渲染到页面
LikeVue.prototype.render = function () {
this.compiler();
};
// 将模板与数据结合得到真正的 DOM元素
LikeVue.prototype.compiler = function () {
let realHTMLDOM = this._tempalteDOM.cloneNode(true);
compiler(realHTMLDOM, this._data);
this.update(realHTMLDOM)
};
// 将DOM元素追加到页面
LikeVue.prototype.update = function (real) {
// 在Vue中使用的是 虚拟DOM 而不是使用repalceChild 使用虚拟DOM会提高性能
this._parentNode.replaceChild(real, document.querySelector("#root"))
}
let app = new LikeVue({
el: "#root",
data: {
name: {
firstName: "study Hard"
}
}
})
</script>
</body>
</html>
使用函数科里化实现层级访问你函数的实现
<!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>
<script>
// 解决层级问题 如何 使用 xx.xx.xx去访问某一个对象的属性
let eg = {
a: {
b: {
c: {
d: "healer"
}
}
}
}
function getValueByPath(obj, path) {
let paths = path.split(".") // ef [xx,yy,zz]
// let res = null;
// res = paths[0];
// res = paths[1];
// res = paths[2];
let res = obj;
let prop;
// 数组的shift方法就是删除数组的第一个元素 并返回第一个元素的值
while (prop = paths.shift()) {
res = res[prop]
}
return res;
}
let res = getValueByPath(eg, "a.b.c.d")
console.log(res);
//函数柯里化实现层级问题
function createGetValyeByPath(path) {
let paths = path.split(".") // ef [xx,yy,zz]
return function (obj) {
let res = obj;
let prop;
// 数组的shift方法就是删除数组的第一个元素 并返回第一个元素的值
while (prop = paths.shift()) {
res = res[prop]
}
return res;
}
}
let getValue = createGetValyeByPath("a.b.c.d")
console.log("new--", getValue(eg))
</script>
</body>
</html>
昨天的地址链接:手写简单的数据驱动
如有不对,还请各位大佬斧正。感谢指教。