接着上节:我们其实是借助vm这个视图层的中间人来联动实现了V-MODEL下面我们来看看具体是如何做到的
1.拿到模板querySelector 只要拿到元素就拿到模板了
2.拿到数据data computed....
3.数据模板结合得到html元素
4.放到页面中
整个替换
图片.png
手写仿照
let tmpNode = document.querySelector("#app"); //元素得到模板得到
拿到模板
图片.png
拿到数据
图片.png
如何放置?当我们html复杂的嵌套时解决办法递归 or 队列(深度优先,广度优先)
<div id="app">
<h3>{{name}}</h3>
<div>
<span>
<h4>{{name}}--{{msg}}</h4>
</span>
</div>
</div>
这里我们先来一些测试
图片.png
我们需要匹配txt拿到{{...}}双括号里的值,这里双括号是两个,所以我们需要匹配两次,这个正则的意思是,.+要匹配多个字符串,?是贪婪的意思截止到下一个花括号开头停止
我们在箭头函数穿的值,也就是它匹配几次的返回结果,这里显然是两次,并且返回了我们预期的值
undefined之所以是这个值,是因为没有返回值
图片.png
这就有值了
这里注意的是我们需要圆括号里的东西
注意:我们的正则/{{(.+?)}}/g 花括号里的只有一个圆括号,这里表示一组,又因为前面有值的缘故我们需要返回值需要两个参数
图片.png
let tmpNode = document.querySelector("#app"); //元素得到模板得到
let data = {
//数据
name: "imycode",
massage: "这是一个伟大的尝试"
};
let rk = /\{\{(.+?)\}\}/g;
// .+ 任意的字符 ? 取贪婪
//如何放到模板当中(??)
function compiler(template, data) {
//template now is DOM
// 在vue中是字符串 -> AST 抽象语法树 ->Vnode ->DOM
let childNodes = template.childNodes;
for (let i = 0; i < childNodes.length; i++) {
//取出子元素 文本节点和元素节点
let type = childNodes[i].nodeType; //节点类型1=>元素 3=>文本
if (type === 3) {
//文本节点{{}}
let txt = childNodes[i].nodeValue; //存储的文本
// console.log(" tag " + txt);
txt = txt.replace(rk, function(_, g) {
//replace使用正则匹配一次函数就会被调用一次
//函数第0个参数表示匹配到的内容,函数的第n个参数表示第n组
console.log(g);
let key = g.trim(); //有可能两边有东西
let value = data[key];
//将{{ xxx }} 用value替换
return value;
});
childNodes[i].nodeValue = txt;
} else if (type === 1) {
//元素节点有没有子元素
compiler(childNodes[i], data);
}
}
}
compiler(tmpNode, data);
网友评论