Vue解析总纲
上一节:防Vue系列-01:怎么将带{{}}真实dom的数据转成带数据dom
改成Vue的形式
//正则,用来匹配{{}}
let r = /\{\{(.+?)\}\}/g;
/**
*@params template:DOM
*@params data:Object
*/
function compiler(template, data) {
let childNodes = template.childNodes; //取出root下的子节点
// 遍历子节点
for (let index = 0; index < childNodes.length; index++) {
let type = childNodes[index].nodeType; //获取子节点的类型
//type === 3 文本节点
if (type === 3) {
//文本节点 判断 是否有{{}}
let txt = childNodes[index].nodeValue; //只有文本节点才有
text = txt.replace(r, (_, g) => {
let key = g.trim(); //两边去空格 key = 'name'
return data[key];
});
//文本赋值
childNodes[index].nodeValue = text;
}
//type === 1 元素节点
else if (type === 1) {
//如果是元素,要判断其子节点是否要插值,递归
compiler(childNodes[index], data);
}
}
}
- 我们将上一篇文章中的编译compiler函数先放过来,下面来创建Vue构造函数
function Vue(options) {
// 内部数据使用_ 开头 ,只读数据$开头
this._data = options.data;
this._el = options.el;
//准备工作(模板)
this.$el = this._templateNode = document.querySelector(this._el);
this._parent = this._templateNode.parentNode;
//渲染工作
this.render();
}
// 入口函数 将数据和dom元素进行结合,展示到页面上
Vue.prototype.render = function () {
//编译
this.compiler();
};
//编译 将数据和模版dom 结合数据
Vue.prototype.compiler = function () {
temDode = this._templateNode.cloneNode(true);
compiler(temDode, this._data); //带有数据的dom
this.updata(temDode);//更新dom
};
// 更新dom 到页面
Vue.prototype.updata = function (temDode) {
this._parent.replaceChild(temDode, this.$el);
};
// 创建Vue的实例
const vm = new Vue({
el: "#root",
data: {
name: "小陈",
},
});