/* 正则 */
let regular = /\{\{(.+?)}\}/g;
function compile(template, data) {
//查找模板下的所有子元素
let childNodes = template.childNodes;
for (let i = 0; i < childNodes.length; i++) {
//查找子元素节点类型 1=== 元素 3===文本
let type = childNodes[i].nodeType
//判断 3 文本
if (type === 3) {
//文本子节点的值
let textContent = childNodes[i].nodeValue // {{xxxxxxx}}
//进行替换
let text = textContent.replace(regular, (_, g) => {
let path = g.trim() // name age love
let value = valueBypath(data, path) //赋值
return value
})
//dom和值关联
childNodes[i].nodeValue = text
} else if (type === 1) {
//如果type 是 1
compile(childNodes[i], data)
}
}
}
//xxx.xxx.xxx 格式
function valueBypath(obj, path) {
let paths = path.split(".")
let res = obj
let props
while (props = paths.shift()) {
res = res[props]
}
return res
}
class ssjVue {
constructor(options) {
/* 挂在元素 */
this._data = options.data
this._el = options.el
this.$el = this._templateDom = document.querySelector(this._el)
/* 因为ithis.$el会被替换 设置其上级元素 */
this._parent = this._templateDom.parentNode;
/* 渲染 html */
this.render()
}
/* 渲染 */
render() {
this.compiler();
}
/* 编译 */
compiler() {
let realHtomlDom = this._templateDom.cloneNode(true)
compile(realHtomlDom, this._data);
this.update(realHtomlDom)
}
/* 更新 */
update(real) {
this._parent.replaceChild(real,docunment,querySelector(`${this._el}`))
}
}
/* 虚拟dom */
class Vnode {
/*
tag:标签名字 div
data:数据 class id title 等
value:文本节点
type 1 div 3 文本 p 。。。。
*/
constructor(tag, data, value, type) {
this.tag = tag && tag.toLowerCase();
this.data = data
this.value = value
this.type = type
this.children = []
}
appendChild(vnode) {
this.children.push(vnode)
}
}
/*
使用递归 来遍历 DOM 元素 生成 dom
*/
function getVnode(node) {
let nodeType = node.nodeType
let _vnode = null
switch (nodeType) {
case 1:
//元素
let nodeName = node.nodeName
let attrs = node.attributes
let _attrObj = {}
for (let i = 0; i < attrs.length; i++) { //attrs[i] 属性节点(nodeType == 2 )
_attrObj[attrs[i].nodeName] = attrs[i].nodeValue
}
_vnode = new Vnode(nodeName, _attrObj, undefined, nodeType)
//考虑node的子元素
let childrenNodes = node.childNodes;
for (let i = 0; i < childrenNodes.length; i++) {
_vnode.appendChild(getVnode(childrenNodes[i])) //递归
}
break;
case 3:
//文本
_vnode = new Vnode(undefined, undefined, node.nodeValue, nodeType)
break
}
return _vnode
}
/* 解析vnode 生成真实dom*/ /* 下一步 添加 属性 */
function parseVnode(vnode) {
/* let vnode = vnode */
let realnode = vnode
console.log(realnode)
let realnodeType = realnode.type
console.log(realnodeType)
let _realnode = null
if (realnodeType === 1) {
let nodeName = realnode.tag
let attrs = realnode.data
let attrsObj = {}
for (let i = 0; i < attrs.length; i++) {
// _attrObj[attrs[i].nodeName] = attrs[i].nodeValue
}
_realnode = document.createElement(nodeName)
let childrenNodes = realnode.children;
console.log(childrenNodes)
for (let i = 0; i < childrenNodes.length; i++) {
_realnode.appendChild(parseVnode(childrenNodes[i])) //递归
}
} else if (realnodeType === 3) {
_realnode = document.createTextNode(vnode)
}
return _realnode
}
let app = new ssjVue({
el: '#root',
data: {
name: 'ssj',
age: 22,
love: 'playgame',
over: {
xixi: 1111
}
}
})
vue模板编译
最新推荐文章于 2024-12-21 09:56:41 发布