简单实现Vue中的插值替换(一)
这篇博客,我们简简单单的实现一下Vue中插值替换的功能。
当然,功能肯定是简化简化再简化的了,只有这样才能称为——简简单单 0^0。
正片开始:
要点解释:0v0
-
首先我们要知道什么插值替换,这个想必学过Vue的都知道,这里就简单说一下:
<body> <div id="root"> <p>{{name}} - {{message}}</p> <p>{{name}}</p> <p>{{message}}</p> </div> </body>
这段 HTML 代码中,{{}} 双大括号语法就是插值语法。
插值替换:就是把双大括号包括的变量替换成我们定义的真正的值。
-
我们都知道在Vue中,代码是这样的:
<body> <div id="root"> <p>{{name}} - {{message}}</p> </div> </body> <script src="../xxxx/vue.js"></script> <script> let app = new Vue({ el:'#root', data(){ return { name: 'Youwillsun', message: '这是我的博客' } } }) </script>
运行这段代码,vue就会把我们写的
{{name}} {{mesage}}
替换成Youwillsun - 这是我的博客
这段我们定义的文字。这次我们就是简单的实现这个功能。
-
思路分析:0v0
-
定义一个对象,这是我们的数据源,类比 Vue 中的 data 。
let data = { name: 'Youwillsun', message: '这是我的博客' };
-
定义一个模板,这是里面是被替换的内容,其实就是 dom。
<div id="root"> <p>{{name}} - {{message}}</p> <p>{{name}}</p> <p>{{message}}</p> </div>
-
获取dom元素,然后找到里面写插值表达式的地方【ps:找插值表达值也就找 {{}} ,这里使用一下正则表达式匹配】
let regx = /\{\{(.+?)\}\}/g; // 正则表达式匹配双花括号 let tmpNode = document.querySelector('#root');// 获取dom
找到了之后用数据源里的数据替换,使用 replace 替换就好了。
-
把处理好的dom替换原来的dom,这样就完成了。
注意:Vue 里不是这么干的,我们只是为了简单实现插值替换的功能,所以才会把整个DOM进行替换。
代码实现:0v0
<!-- dom -->
<body>
<div id="root">
<p>{{name}} - {{message}}</p>
<p>{{name}}</p>
<p>{{message}}</p>
</div>
</body>
<!-- js -->
<script>
console.log(root);
let regx = /\{\{(.+?)\}\}/g; // 正则表达式匹配双花括号
let tmpNode = document.querySelector('#root');
let data = {
name: 'Youwillsun',
message: '这是我的博客'
};
// 定义编译函数,用来处理dom元素
function complier(template, data) {
// 获取子节点
let childNodes = template.childNodes;
// 遍历子节点
for (let i = 0; i < childNodes.length; i++) {
// 根据子节点类型,来确定此节点是文本节点,还是元素节点[3代表文本节点,1代表元素节点]
let type = childNodes[i].nodeType;
if (type === 3) {
// 获取文本节点的值
let txt = childNodes[i].nodeValue;
// 利用replace,结合正则表达式,来对插值进行替换
txt = txt.replace(regx, function (_, g) {
let key = g.trim();
let value = data[key];
return value;
});
childNodes[i].nodeValue = txt;
} else if (type === 1) {
// 如果是元素节点 递归调用
complier(childNodes[i], data);
}
}
}
let generateNode = tmpNode.cloneNode(true);
complier(generateNode, data);
// 替换原来的dom模板
root.parentNode.replaceChild(generateNode, root);
console.log(root);
</script>
代码解释:0v0
-
首先看代码中的
console.log(root)
有些人就懵了,root 是什么?root 就是 dom元素中 div 的 id
,这点有兴趣的人可以尝试一下,我们在 js 中可以直接输出 dom 定义某个 id 值的模板。 -
接着就是定义的编译函数了,注释写的很清楚了,我挑解释一下:
-
第一个点:
nodeType
是什么?nodeType 顾名思义就是节点的类型:
- 元素节点:可以简单的理解成,此节点还有子节点。
- 文本节点:可以简单的理解成,此节点没有子节点了,这个节点是填充文本的,是我们编写内容的地方。
具体了解,可一看这个网址:HTML DOM nodeType 属性
-
第二个点:
replace
函数replace() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串 。
具体了解可以看:replace用法解释
-
-
可以看到我用了一个 cloneNode 先克隆了一下模版,然后把克隆的模板交给 complier 进行处理的
- 这也是稍稍向Vue靠拢一下,毕竟任何时候,我们都不能拿到什么就都直接处理
- 一般情况下,都要考虑是否要进行备份,这里也是一样的,先对原模板进行备份。
-
然后利用replaceChild函数,传入要替换的 dom 和 被替换的 dom。
到这里就结束了,这就简单实现了Vue中的插值替换。
下一篇:简单实现Vue中的插值替换(二)