持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第4天,点击查看活动详情
在上一文我们介绍了一些前期工作,现在我们就开始虚拟节点转化,因为我们没有做模版转化,所以就直接用写好的数据了,
// 这个就是我们用到的数据,把当前数据转化虚拟节点
var vdom = createElement('ul',{class:'list',width:'300px'},[
createElement('li',{class:'item',"data-index":0},[
createElement('p',{ class:'text' },['第一个列表'])
]),
createElement('li',{ class: 'item',"data-index":1},[
createElement('p',{ class:'text' },['第二个列表'])
]),
createElement('li',{ class:'item',"data-item":2 },["第三个列表"])
])
conso.log(vdom)
把上面数据转化为虚拟节点的方式主要是实现createElement可以看下createElement的实现方式 vdom.js
import Element from './Element.js'
function createElement(type,props,children) { // 把这三个转化为对象
return new Element(type,props,children) // 利用new一个对象的方式把每一条数据独立起来,后续也会其他用处
}
export {
createElement
}
Element.js
// 新建一个类(也就是构造函数)
function Element(type,props,children) { // 没一个标签都是一个类, 互不影响
// type 标签 props属性 children子元素
this.type = type
this.props = props
this.children = children
}
export default Element
可以看下目录结构
图片上是我的目录结构
可以看下我的打印的结构
虚拟节点转化完成
下一步虚拟节点转真实dom 需要写一个render函数 大家可以看下
function render(vdom) {
// 虚拟转真实 我们需要新建html标签
let { type, props, children} = vdom // 把属性解构出来
const el = document.createElement(type)
// 我们需要遍历属性 用 for in
for (let key in props) { // 直接为新建元素新建属性是不行的 ,
// 我们需要判断元素区分input节点 textarea节点 剩下的节点就可以setAttrbute
setAtts(el,key,props[key]) // 判断节点方法
}
// 还需要去判断children
children.map(c=>{
// 需要判断c 是否字符串节点 换另外一种思路
//非文本我们都是用Element构造函数生成,所以我们可以判断是否是Element
if (c instanceof Element) {
c = render(c)
} else {
c = document.createTextNode(c)
}
el.appendChild(c)
})
console.log(el)
return el
}
function setAtts(el,key,value) { // 属性添加也需要判断
// 判断属性是否是value
if (key=='value') {
if (el.tagName=='INPUT'||el.tagName=="TEXTAREA") {
el.value = value
} else {
el.setAttribute(key,value)
}
} else if(key=='style') { //
el.style.cssText = value
} else {
el.setAttribute(key,value)
}
}
后面是渲染到页面上
function renderDom(el,rootel) {
rootel.appendChild(el)
}