精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Vue.js設(shè)計與實現(xiàn)之十二-渲染器的核心功能:掛載與更新01

開發(fā) 前端
在本文中主要講述了如何實現(xiàn)虛擬DOM節(jié)點轉(zhuǎn)成真實DOM樹上,最終掛載到掛載點上。討論了虛擬節(jié)點是如何掛載到DOM樹,又是如何從DOM樹上卸載的,對于屬性又是如何在元素上進行設(shè)置的。

1、寫在前面

在本文中主要講述了如何實現(xiàn)虛擬DOM節(jié)點轉(zhuǎn)成真實DOM樹上,最終掛載到掛載點上。討論了虛擬節(jié)點是如何掛載到DOM樹,又是如何從DOM樹上卸載的,對于屬性又是如何在元素上進行設(shè)置的。

2、掛載子節(jié)點和元素的屬性

在上篇文章中,在vnode.children值為字符串時,將其設(shè)置為元素的文本內(nèi)容,當vnode.children值為數(shù)組時,表示其有子節(jié)點需要遍歷設(shè)置。我們知道vnode是一個虛擬DOM節(jié)點,vnode.children是一個虛擬DOM樹,其每個元素都是一個虛擬DOM節(jié)點。

const vnode = {
type:"div",
//props是標簽的屬性
props:{
id:"super"
},
children:[
{
type:"p",
children:"pingping"
}
]
}

上面的代碼是虛擬DOM樹形結(jié)構(gòu),如果要實現(xiàn)將虛擬VNode轉(zhuǎn)為真實DOM,需要通過掛載和渲染。可以通過mountElement函數(shù)實現(xiàn)節(jié)點的渲染:

function mountElement(vnode, container){
const el = createElement(vnode.type);
//處理children
if(typeof vnode.children === "string"){
// 字符串轉(zhuǎn)為標簽的文本內(nèi)容
setElementText(el, vnode.children)
}else if(Array.isArray(vnode.children)){
//虛擬DOM節(jié)點數(shù)組 需要遍歷每個節(jié)點進行掛載
vnode.children.forEach(child=>{
patch(null,child,el);
})
}
// 在標簽上添加屬性
if(vnode.props){
for(const key in vnode.props){
// 調(diào)用setAttribute在元素上設(shè)置屬性
el.setAttribute(key, vnode.props[key]);
// 也可以使用DOM對象直接設(shè)置屬性
// el[key] = vnode.props[key];
}
}
insert(el, container);
}

在上面代碼片段中,首先會根據(jù)vnode.type的值創(chuàng)建DOM節(jié)點,children的值判斷為string類型時,直接將其設(shè)置為元素的文本內(nèi)容;children的值判斷數(shù)組時,則對數(shù)組內(nèi)的虛擬DOM節(jié)點進行遍歷,調(diào)用patch函數(shù)掛載節(jié)點。

在掛載階段patch是沒有舊vnode的,對此傳遞的第一個參數(shù)是null,而在patch函數(shù)執(zhí)行時會遞歸調(diào)用mountElement函數(shù)完成掛載。而patch傳遞的第三個參數(shù)是虛擬節(jié)點要掛載的根節(jié)點,完成掛載后需要給元素遍歷設(shè)置屬性。

3、正確地設(shè)置元素屬性

如何正確地設(shè)置元素屬性,就得先了解HTML Attribute和DOM Properties的差異和關(guān)聯(lián)。我們知道HTML Attribute是定義在HTML標簽元素上的屬性,瀏覽器會將其解析創(chuàng)建一個對應(yīng)的DOM對象,這個對象上包含許多屬性(DOM Properties)。

HTML Attribute的作用是設(shè)置與之對應(yīng)的DOM Properties初始值,當值發(fā)生改變時,DOM Properties始終存儲著當前值,那么通過getAttribute獲取到的也是初始值。

HTML Attribute和DOM Properties。然而在使用Vue.js的單文件模板不會被瀏覽器解析,此時需要框架自己進行解析。會影響DOM屬性的添加方式,瀏覽器會解析普通HTML元素代碼,自定分析HTML Attribute設(shè)置合適的DOM Properties。然而在使用Vue.js的單文件模板不會被瀏覽器解析,此時需要框架自己進行解析。

那么,看看在Vue.js是如何實現(xiàn)的:

const renderer = createRenderer({
//創(chuàng)建元素
createElement(tag){
return document.createElement(tag);
},
//設(shè)置元素的文本節(jié)點
setElementText(el, text){
el.textContent = text;
},
//用于給指定父節(jié)點添加指定元素
insert(el, parent, achor = null){
parent.insertBefore(el, anchor);
}
// 將屬性設(shè)置相關(guān)操作進行封裝,作為渲染器選項進行傳值
patchProps(el, key, prevValue, nextValue){
if(shouldSetAsProps(el, key, nextValue)){
const type = typeof el[key];
if(key === "class"){
//采用el.className方式設(shè)置clas,是因為其性能相對于setAttribute和el.classList更高
el.className = nextValue || "";
}else if(type === "boolean" && nextValue === ""){
el[key] = true;
}else{
el[key] = nextValue;
}
}else{
el.setAttribute(key, nextValue);
}
}
})

在上面代碼中,shouldSetAsProps函數(shù)用于分析屬性是否應(yīng)該作為DOM Properties屬性被設(shè)置,返回的是一個布爾值。當返回一個true值時,表示應(yīng)該作為DOM Properties被設(shè)置,否則就應(yīng)該使用setAttribute函數(shù)設(shè)置屬性。在設(shè)置屬性時,需要優(yōu)先設(shè)置元素的DOM Properties,當其值為空字符串時,需要將其矯正為true。

在mountElement函數(shù)中,只需要調(diào)用patchProps函數(shù)傳遞參數(shù)即可:

function mountElement(vnode, container){
const el = createElement(vnode.type);
//處理children
if(typeof vnode.children === "string"){
// 字符串轉(zhuǎn)為標簽的文本內(nèi)容
setElementText(el, vnode.children)
}else if(Array.isArray(vnode.children)){
//虛擬DOM節(jié)點數(shù)組 需要遍歷每個節(jié)點進行掛載
vnode.children.forEach(child=>{
patch(null,child,el);
})
}

// 在標簽上添加屬性
if(vnode.props){
for(const key in vnode.props){
patchProps(el, key, null, vnode.props[key])
}
}
insert(el, container);
}

在上面代碼片段中,mountElement函數(shù)會檢查每個vnode.props中的屬性,調(diào)用patchProps函數(shù)去設(shè)置DOM Properties。

4、卸載操作

在前面兩節(jié)中,討論了如何將虛擬DOM掛載到掛載點上,是通過createRenderer函數(shù)結(jié)合mountElement實現(xiàn)的。而卸載操作發(fā)生在更新階段,即初次掛載完成之后,后續(xù)渲染觸發(fā)的更新。

//初次掛載
renderer.render(vnode, document.querySelector("#app"));
// 再次掛載新vnode,觸發(fā)更新 當傳遞的是null,則進行卸載之前的操作
renderer.render(vnode, document.querySelector("#app"));
//renderer.render(null, document.querySelector("#app"));

在初次渲染完畢后,后續(xù)渲染時如果傳遞的是null作為新vnode,則表示需要卸載當前所有渲染的內(nèi)容。

在上一篇文章中,使用innerHTML設(shè)置為空作為清空容器元素內(nèi)容的方案是存在缺陷的,因為它不會移除綁定在DOM元素上的事件處理函數(shù)。對此,需要先根據(jù)vnode對象獲取到與之關(guān)聯(lián)的真實DOM元素,使用原生DOM操作方法將其進行移除。

function unmount(vnode){
const parent = vnode.el.parentNode;
if(parent){
parent.removeChild(vnode.el);
}
}

unmount函數(shù)接收一個虛擬節(jié)點作為參數(shù),并將該節(jié)點對應(yīng)的真實DOM元素從父元素上移除。

注意:在新舊vnode描述內(nèi)容不同時,即vnode.type的屬性不同時,兩個vnode之間就不存在打補丁的意義,此時應(yīng)該使用unmount函數(shù)先將舊元素進行卸載,再將n1的值重置為null,最后將新元素進行掛載到容器中。

當然,即使新舊vnode描述內(nèi)容相同,也要判斷兩者的類型是否相同,vnode可以描述普通標簽也可以描述組件,對于不同類型的vnode需要使用不同的掛載或打補丁方式。

function patch(n1, n2, container){
if(n1 && n2.type !== n1.type){
unmount(n1);
n1 = null;
}
const { type } = n2;
if(typeof type === "string"){
if(!n1){
mountElement(n2, container);
}else{
patchElement(n1, n2);
}
}else if(typeof type === "object"){
// n2.type是object對象類型,則描述的是組件
}else if(type === "xxx"){
//處理其他類型vnode
}
}

5、寫在最后

掛載子節(jié)點只需要遞歸調(diào)用patch函數(shù)即可實現(xiàn)掛載,而節(jié)點屬性的設(shè)置就取決于被設(shè)置屬性的特點。在卸載操作時,通過直接使用innerHTML清空容器元素是存在諸多問題的,對此封裝了一個新的卸載函數(shù)unmount。

責任編輯:姜華 來源: 前端一碼平川
相關(guān)推薦

2022-04-20 09:07:04

Vue.js的事件處理

2022-04-18 08:09:44

渲染器DOM掛載Vue.js

2022-04-01 08:08:27

Vue.js框架命令式

2022-04-04 16:53:56

Vue.js設(shè)計框架

2022-04-25 07:36:21

組件數(shù)據(jù)函數(shù)

2022-04-12 08:08:57

watch函數(shù)options封裝

2022-04-03 15:44:55

Vue.js框架設(shè)計設(shè)計與實現(xiàn)

2022-04-11 08:03:30

Vue.jscomputed計算屬性

2022-05-03 21:18:38

Vue.js組件KeepAlive

2022-04-14 09:35:03

Vue.js設(shè)計Reflect

2022-04-05 16:44:59

系統(tǒng)Vue.js響應(yīng)式

2022-04-26 05:55:06

Vue.js異步組件

2022-04-17 09:18:11

響應(yīng)式數(shù)據(jù)Vue.js

2022-04-09 17:53:56

Vue.js分支切換嵌套的effect

2022-04-16 13:59:34

Vue.jsJavascript

2022-04-12 08:09:22

Nodejs前端面試題

2019-04-01 19:38:28

Vue.jsJavascript前端

2010-08-13 11:02:27

Flex渲染器

2016-11-01 19:10:33

vue.js前端前端框架

2009-07-15 13:48:26

Swing模型和渲染器
點贊
收藏

51CTO技術(shù)棧公眾號

免费无遮挡无码永久在线观看视频| 午夜精品视频在线观看一区二区| 欧美视频一区二区在线| 懂色av色香蕉一区二区蜜桃| 亚洲日本va在线观看| 成人h视频在线观看播放| 久久国产精品波多野结衣av| 婷婷亚洲精品| 在线91免费看| 少妇性饥渴无码a区免费| 第一福利在线| 国产精品一区免费在线观看| 欧美极度另类性三渗透| 国产精品手机在线观看| 欧美日韩va| 国产精品日产欧美久久久久| 国产在线精品一区二区三区| 亚洲午夜激情视频| 91精品国产视频| 日韩精品亚洲视频| 天天色天天干天天色| free欧美| 五月婷婷综合网| 亚洲精品国产一区| 午夜成人鲁丝片午夜精品| 韩国成人在线视频| 国产精品免费看久久久香蕉| 女教师淫辱の教室蜜臀av软件| 久久97精品| 欧美一级免费大片| 国产高清视频网站| 亚洲欧美se| 亚洲大片一区二区三区| 色爽爽爽爽爽爽爽爽| www在线免费观看| 91蜜桃视频在线| 国产精品免费区二区三区观看| 亚洲一区二区影视| 青青草成人在线观看| 日本sm极度另类视频| 国产真实夫妇交换视频| 日韩中文在线电影| 亚洲性无码av在线| 少妇熟女视频一区二区三区| 亚洲美女色播| 欧美日韩国产bt| gogogo高清免费观看在线视频| 香蕉伊大人中文在线观看| 亚洲一级二级三级在线免费观看| 中文字幕の友人北条麻妃| 蜜桃av在线免费观看| 中文字幕国产一区| 日本欧洲国产一区二区| 精品乱码一区二区三四区视频| 91麻豆高清视频| 欧美成人蜜桃| 精品999视频| 国产亚洲一区字幕| 午夜视频久久久| 嫩草研究院在线观看| 久久日一线二线三线suv| 久久精品国产第一区二区三区最新章节 | 亚洲三级黄色片| 91香蕉国产在线观看软件| 国产精品久久亚洲7777| 亚洲精品国产av| 成人爽a毛片一区二区免费| 97久久精品午夜一区二区| 国产乱色精品成人免费视频| 韩国av一区二区三区| 91免费国产网站| 国产青青草视频| 大陆成人av片| 久久精品aaaaaa毛片| 日本黄在线观看| 欧美激情一区二区三区四区| 一级二级三级欧美| 国产不卡在线| 五月天久久比比资源色| 免费看a级黄色片| 欧美黄页在线免费观看| 欧美大黄免费观看| 9.1成人看片免费版| 成人高清电影网站| 九九九久久久久久| 国产精品xxxx喷水欧美| 日韩国产成人精品| 亚洲a一级视频| 六十路在线观看| 亚洲特黄一级片| 久操网在线观看| 国产一二三在线| 欧美午夜激情在线| 爽爽爽在线观看| 亚洲一区二区三区免费| 亚洲激情在线视频| ass极品国模人体欣赏| 你懂的国产精品| 国产97色在线| 亚洲精品.www| 国产欧美日韩在线视频| 日本一道在线观看| 成人线上视频| 精品人在线二区三区| 亚洲av成人无码久久精品| 欧美精品自拍| 日本最新高清不卡中文字幕| 国产手机av在线| 久久久久亚洲蜜桃| 亚洲一区美女| www.九色在线| 91精品国产全国免费观看| 女同毛片一区二区三区| 希岛爱理一区二区三区| 日韩免费av一区二区| 亚洲精品成av人片天堂无码| 欧美国产禁国产网站cc| 亚洲熟妇无码另类久久久| 久久69成人| 亚洲人成在线播放| 亚洲一区欧美在线| 精品一区二区三区视频| 欧美日韩精品综合| 国模私拍一区二区国模曼安| 日韩一卡二卡三卡四卡| 亚洲AV无码成人精品区明星换面| 亚洲精品社区| 亚洲伊人久久综合| 日本精品在线| 欧美日韩综合在线免费观看| 国产麻豆天美果冻无码视频 | jizz一区二区| 色狠狠久久av五月综合| 亚洲美女尤物影院| 亚洲第一天堂无码专区| 欧美特黄一级片| 久久综合综合久久综合| 亚洲成人自拍| 成人动漫一区| 国产视频久久久久| av资源免费观看| 99精品一区二区三区| 久操手机在线视频| 免费精品一区| 久久影院在线观看| 国产女同91疯狂高潮互磨| 中文字幕一区二区三区色视频 | 国产人妻互换一区二区| 国产精品日韩精品在线播放| 波霸ol色综合久久| 国产精品嫩草影院桃色| 亚洲欧美乱综合| 黄色片子免费看| 午夜国产精品视频| 97中文在线观看| 77导航福利在线| 色综合天天综合网国产成人综合天 | 九九热国产视频| 国产精品一区二区在线播放| 亚洲一区二区三区精品动漫| 国模私拍国内精品国内av| 日韩av在线免费观看一区| 成年免费在线观看| 久久久91精品国产一区二区三区| 一本久道综合色婷婷五月| 成人6969www免费视频| 成人写真视频福利网| av在线免费播放| 亚洲一区二区三区四区在线观看| 亚洲v中文字幕| 五月天丁香花婷婷| 欧美1级片网站| 92看片淫黄大片看国产片| 亚洲区欧洲区| 亚洲精品久久久久中文字幕欢迎你| 欧美福利视频一区二区| 久久久久久久综合狠狠综合| jizz欧美激情18| 性欧美69xoxoxoxo| 国产经典一区二区三区| 成人影院大全| 久久久精品在线观看| 欧日韩在线视频| 欧美专区亚洲专区| 国产高潮流白浆| 91亚洲大成网污www| 亚洲免费av一区二区三区| 91tv官网精品成人亚洲| 久久爱av电影| 亚洲一区二区av| 欧美激情a在线| 欧美日韩在线中文字幕| 欧美二区三区91| 久久久久久福利| 久久精品亚洲精品国产欧美kt∨ | 日韩欧美大片在线观看| 91视频精品在这里| 日韩av影视大全| 日韩激情一区二区| 日韩精品伦理第一区| 中文字幕区一区二区三| 亚州欧美日韩中文视频| 性感美女一级片| 777亚洲妇女| 成人毛片在线播放| 久久精品一区二区| 免费看毛片的网站| 国产在线日韩欧美| 国产视频在线视频| 亚洲欧美亚洲| 熟女视频一区二区三区| 成人51免费| 国内精品美女av在线播放| 国产日产一区二区三区| 日韩午夜激情av| 依依成人在线视频| 日韩欧美亚洲一二三区| 久久久久性色av无码一区二区| 国产精品福利一区二区三区| 欧洲女同同性吃奶| 成人激情午夜影院| 国产精品久久久久久9999| 亚洲欧美网站| 男人插女人视频在线观看| 日韩中文在线电影| 五码日韩精品一区二区三区视频| 窝窝社区一区二区| 99国产高清| 欧美日韩视频免费观看| 欧美一级视频免费在线观看| 欧美日韩在线视频免费观看| 久久综合五月天| 黄色网在线看| 国产亚洲一区二区在线| 全色精品综合影院| 日韩精品在线观看网站| 日韩有码电影| 日韩精品在线免费观看| 神马精品久久| 欧美刺激脚交jootjob| va婷婷在线免费观看| 欧美男女性生活在线直播观看| 国产综合精品视频| 亚洲风情在线资源站| av最新在线观看| 国产欧美日韩三区| 99久久99久久精品免费看小说. | 久久高清免费视频| 久久嫩草精品久久久精品一| 日韩av在线看免费观看| 久久精品网站免费观看| 91成年人网站| 欧美极品少妇xxxxⅹ高跟鞋 | 26uuu国产| 丁香婷婷综合激情五月色| 美女露出粉嫩尿囗让男人桶| 精品制服美女丁香| 中文字幕第100页| 国产麻豆视频精品| 国模无码视频一区| 久久理论电影网| 国产精品美女高潮无套| 欧美激情在线看| 欧美三级在线免费观看| 播五月开心婷婷综合| 国产精品久久久久野外| 成人av网站免费观看| 中文字幕 欧美 日韩| a级高清视频欧美日韩| b站大片免费直播| 日韩免费毛片| 久久香蕉精品香蕉| 久久一区免费| 99久久99视频只有精品| 成人国产在线看| 国产精品日韩欧美一区| 日本一区二区黄色| 精品制服美女久久| 在线免费看污网站| 粉嫩13p一区二区三区| www.自拍偷拍| 综合亚洲深深色噜噜狠狠网站| 青青青在线视频| 一区二区三区在线观看欧美| 久久免费视频99| 在线观看成人免费视频| 99精品人妻无码专区在线视频区| 亚洲国产精品人久久电影| 国产主播福利在线| 久99久在线视频| hd国产人妖ts另类视频| 国产成人综合精品在线| 欧美成年网站| 日韩妆和欧美的一区二区| 欧美在线国产| 五月婷婷丁香色| 99麻豆久久久国产精品免费 | 91精品国偷自产在线电影 | 神马影院我不卡| 黄页网站一区| 一级片视频免费观看| 国产福利一区二区三区| 欧美 日本 国产| 国产欧美一区二区精品性色超碰| 久草视频免费播放| 欧美日韩亚洲综合| 欧美日韩国产综合视频| 久久精品99无色码中文字幕| 亚洲性受xxx喷奶水| 91精品入口蜜桃| 一区二区三区四区在线看 | 伊人精品成人久久综合软件| 福利在线一区二区三区| 成人高清av在线| 91久久久久久久久久久久久久| 亚洲午夜视频在线| 日本a级c片免费看三区| 精品日产卡一卡二卡麻豆| 大地资源网3页在线观看| 国产成人一区二区| 一区二区在线视频观看| 永久免费在线看片视频| 亚洲永久在线| 99视频在线观看视频| 国产精品久久久久久久蜜臀 | 国产熟女一区二区| 一个色在线综合| 中文字幕91爱爱| 日韩精品在线免费播放| 国产777精品精品热热热一区二区| 亚洲www在线| 成人免费a**址| 欧美午夜性生活| 久久嫩草精品久久久精品一| 精品欧美一区二区三区免费观看| 精品精品国产高清a毛片牛牛 | 日韩免费一级| 麻豆md0077饥渴少妇| 国产最新精品精品你懂的| 欧美风情第一页| 欧美日本视频在线| 日本电影在线观看网站| 国产精品国产亚洲伊人久久| 国产亚洲第一伦理第一区| 免费看毛片的网址| 成人精品视频一区| 亚洲国产精一区二区三区性色| 精品对白一区国产伦| 性欧美猛交videos| 成人天堂噜噜噜| 国产韩国精品一区二区三区| 天天视频天天爽| 1区2区3区精品视频| 国产精品一区二区人人爽| 亚洲老司机av| 欧美日韩亚洲国产| 亚洲欧美日韩另类精品一区二区三区 | 国产成人无码a区在线观看视频| 国产成人福利片| 99精品视频99| 中文字幕日韩专区| 日韩av黄色| 欧美少妇一级片| 捆绑变态av一区二区三区| 青娱乐国产视频| 欧美一区二区三区播放老司机| 天堂av在线电影| 亚洲va久久久噜噜噜久久天堂| 欧美在线三区| 日韩人妻一区二区三区| 欧美日韩高清在线| 免费污视频在线| 精品国产乱码久久久久久蜜柚| 性久久久久久| 999福利视频| 欧美电影精品一区二区| 日韩免费va| 亚洲精品人成| 国产99精品国产| 中文字幕永久在线| 菠萝蜜影院一区二区免费| 久久99国产精品久久99大师| 嫩草影院国产精品| 欧美高清在线精品一区| 在线观看中文字幕码| 欧美精品激情视频| 精品一区二区三区的国产在线观看| 手机在线视频一区| 色域天天综合网| 污片视频在线免费观看| 欧美午夜免费| 精品制服美女丁香| 天码人妻一区二区三区在线看| 亚洲天堂精品在线| 97久久超碰| 911福利视频| 日韩欧美在线视频免费观看| 成人精品一区二区三区免费| 国产精品久久亚洲7777| 久久成人精品无人区|