在这个以前咱们须要了解render是什么?html
能够去以前的文章里面看看 《 搞懂vue-render函数(入门篇)》vue
废话很少说,快快快 上车!!!数组
先定义一个数据对象来做为咱们的数据微信
let data = { tag:"h2", props:{}, children:"严老湿" }
tag
做为标签名,props
做为属性对象,children
做为子元素或者文本节点数据结构
哈哈哈 仍是老套路 先写一个 h2
标签试试水app
这个So Easy啦ide
<div id="app"></div>
// app 做为咱们的根节点 let app = document.querySelector('#app')
获取到 app
节点以后呢? 咱们是否是须要 appendChild
咱们第一步定义的 data
对象函数
// 此时尚未render这个函数 app.appendChild(render(data))
这个 render
函数就是咱们今天要写的重要内容ui
天才第一步 ,先定义一个 render
函数spa
// 接收传入的参数 const render = (options) = >{ // 获取数据中的标签并建立 let el = document.createElement(options.tag); // 打印el console.log(el) // <h2></h2> // 将节点返回 return el } app.appendChild(render(data))
此时咱们的元素已经建立成功,接下来咱们须要作的就是,把它的文本,渲染上去。
渲染文本节点
将 children
赋值给到节点文本内容
const render = (options) = >{ let el = document.createElement(options.tag); // 咱们在这里传入 children 文本 el.textContent = options.children return el } app.appendChild(render(data))
严老湿 :好了,render
写完了,下课吧!
童鞋 :等等!! 就这???
开个玩笑 固然不是啦!这写得也真是太简陋了吧
刚刚咱们其实已经写了一个简陋版本的render 有不少问题!
children
若是是数组,多个子元素呢?props
里面有属性呢?....
还有不少问题,因此咱们来增强一下,冲鸭!!!
咱们如今先来升级一下 props
参数,如咱们须要在元素上加 class
、id
、on
首先是一号选手 class
咱们先将数据中的props
中新增一个class
且 它的值为 myClass
let data = { tag:"h2", props:{ class:"myClass" }, children:"严老湿" }
数据改造好了,咱们来看看 render
改如何升级
const render = (options) = >{ let el = document.createElement(options.tag); // 判断是不是对象,而且不是null if(typeof options.props === 'object' && options.props !== null){ for(key in options.props){ // 拿到 props 中的 key、val vla = options.props[key]; // 给元素添加指定的属性 el.setAttribute(key, vla); } } el.textContent = options.children; return el } app.appendChild(render(data))
这样咱们就已经完成了class
的添加
老湿,那ID呢?
等等,我拿下锤子...
第二位选手 id
id其实都不用说了,就改改数据而已,So Easy
let data = { tag:"h2", props:{ class:"myClass", id:"myId" }, children:"严老湿" }
props的最后一位选手 on
on
里面是用来绑定事件的,因此咱们不能跟class
与 id
同等对待。渣男!区别对待
仍是先改造数据,咱们加上 on-click
let data = { tag:"h2", props:{ class:"myClass", id:'myId', on:{ // 传入点击事件 click:(e)=>{ console.log(e) } } }, children:"严老湿" }
数据改造完成,咱们接着升级 render
const render = (options) = >{ let el = document.createElement(options.tag); if(typeof options.props === 'object' && options.props !== null){ for(key in options.props){ vla = options.props[key]; // 若是key等于on if(key === "on"){ // 将on对象赋值给 incident incident = options.props[key] for(k in incident){ // 给元素绑定事件传入Event el.addEventListener(k,e=>incident[k](e)) } }else{ // 其余的都进来这里 el.setAttribute(key, vla); } } } el.textContent = options.children; return el } app.appendChild(render(data))
点击标签以后看看打印
是否是也是很简单
到这里咱们就已经完成了这个 props
里面常常会用到的一些操做了。
有时候咱们的数据中可能不止一个元素,那若是children
是一个数组呢?
那咱们就不能直接赋值给元素的 textContent
了,继续加判断。
咱们仍是同样的先修改数据,将 children
改成一个数组,结构呢仍是个以前同样
let data = { tag:"ul", props:{ class:"myClass", id:'myId', }, children:[ { tag: 'li', props: { class: "list", }, children: "4万面五星红旗挂上武汉街头" }, { tag: 'li', props: { class: "list", }, children: "机场水门最高礼遇迎接烈士遗骸" } ] }
数据结构修改完成以后了,咱们接下来修改 render
函数
const render = (options) = >{ let el = document.createElement(options.tag); if(typeof options.props === 'object' && options.props !== null){ for(key in options.props){ vla = options.props[key]; if(key === "on"){ incident = options.props[key] for(k in incident){ el.addEventListener(k,e=>incident[k](e)) } }else{ el.setAttribute(key, vla); } } } // 在内容赋值这里咱们作一个判断 // 若是 children 是一个数组 if (options.children instanceof Array) { // 咱们进行 forEach 遍历一下 options.children.forEach((item)=>{ // 进行递归 render 函数,传入 el.appendChild(render(item)); }); }else{ // 若是不是数据,咱们进行赋值 el.textContent = options.children } return el } app.appendChild(render(data))
是否是已经渲染成功呢?
给你们贴一下所有代码吧!
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>老严讲render</title> </head> <body> <div id="app"></div> <script> const app = document.querySelector('#app') let data = { tag: "ul", props: { class: "myClass", id: 'myId', }, children: [ { tag: 'li', props: { class: "list", }, children: "4万面五星红旗挂上武汉街头" }, { tag: 'li', props: { class: "list", }, children: "机场水门最高礼遇迎接烈士遗骸" } ] } const render = (options) => { let el = document.createElement(options.tag); if (typeof options.props === 'object' && options.props !== null) { for (key in options.props) { vla = options.props[key]; if (key === "on") { incident = options.props[key] for (k in incident) { el.addEventListener(k, e => incident[k](e)) } } else { el.setAttribute(key, vla); } } } if (options.children instanceof Array) { options.children.forEach((item) => { el.appendChild(render(item)); }); } else { el.textContent = options.children } return el; }; app.appendChild(render(data)); </script> </body> </html>
喜欢能够关注微信公众号“悲伤日记”