在這個以前咱們須要瞭解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>
喜歡能夠關注微信公衆號「悲傷日記」