您好,登錄后才能下訂單哦!
這篇“Vue中原生template標(biāo)簽失效怎么解決”文章的知識點(diǎn)大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細(xì),步驟清晰,具有一定的借鑒價(jià)值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Vue中原生template標(biāo)簽失效怎么解決”文章吧。
找了整一天也沒找著這事件為什么觸發(fā)不了, 在這中間還把代碼簡化掉只留下事件觸發(fā)邏輯執(zhí)行了好幾次.
第二天意識到原生代碼里的template
可能有問題, 在原生環(huán)境中template
標(biāo)簽內(nèi)部的東西是不會(huì)渲染出來的, 雖然解析器在加載頁面的時(shí)候確實(shí)會(huì)處理這部分代碼片段.
取自MDN:
將模板視為一個(gè)可存儲(chǔ)在文檔中以便后續(xù)使用的內(nèi)容片段.
雖然解析器在加載頁面時(shí)確實(shí)會(huì)處理 <template> 元素的內(nèi)容,
但這樣做只是為了確保這些內(nèi)容有效, 元素內(nèi)容不會(huì)被渲染.
但是放到vue里(這里特指Vue2), 如果template
標(biāo)簽在Vue實(shí)例綁定的元素內(nèi)部存在(即不是根元素外的那個(gè)template
), 那么在DOM中該template
的子元素是正常存在并顯示的, 我以前經(jīng)常拿template
做v-for
容器.
然后聯(lián)想前面幾次結(jié)構(gòu)簡化demo, 大概不是沒綁定而是綁錯(cuò)了目標(biāo).
這個(gè)原生項(xiàng)目的HTML代碼很多, 所以作者做了一些優(yōu)化, 在需要某個(gè)模塊的時(shí)候才將其appendChild
加入DOM, 其余的時(shí)候這些模塊都被放在template
標(biāo)簽內(nèi), 而vue把這些東西都出來渲染了, 那么初始化的時(shí)候事件大概率就已經(jīng)被綁到了template
里面的那些代碼里, 等到這些模塊被appendChild
的時(shí)候, 事件綁定已經(jīng)結(jié)束了, 所以appendChild
是將沒有事件綁定的DOM加到了正確位置.
我在控制臺把視口里的DOM都刪掉之后發(fā)現(xiàn)下面還有一層被擠出去的DOM, 那是有事件綁定的DOM.
的確是這樣.
我是想把他appendChild
這個(gè)優(yōu)化留下來的, 我覺得在原生環(huán)境里能有這種封裝的思想挺好, 不過看起來不好辦…
我打算把原來那幾個(gè)模塊抽到組件里, 提前把組件寫到后面會(huì)插入到的位置, 然后用這種結(jié)構(gòu)控制顯示隱藏:
<template v-if="isShow"> <aaa></aaa> </template>
這樣挺好的其實(shí), 如果這個(gè)項(xiàng)目的結(jié)構(gòu)再簡單一點(diǎn)我絕對會(huì)用組件方案的, 結(jié)果我發(fā)現(xiàn)我要傳回調(diào)函數(shù), 傳4層干擾到3個(gè)很重要的類, 只是為了在合適的時(shí)機(jī)回調(diào)改變組件的狀態(tài), 我覺得很糟糕.
而且, 如果后面會(huì)有…或者現(xiàn)在就有我沒有察覺到的需求是增加不定數(shù)量個(gè)這種模塊, 我把組件直接注冊到這里用就算是寫死了, 恐怕會(huì)不好改.
需要這種操作的組件有三個(gè), 我想起來學(xué)后端渲染的時(shí)候給前端發(fā)的html模板, 那…能不能把這些html轉(zhuǎn)成字符串存到一個(gè)單獨(dú)的js文件, 然后在需要的地方導(dǎo)入后appendChild
呢? 這樣對源代碼改動(dòng)最小, 不用改appendChild
, 也讓html文檔那邊更簡潔一些.
export const batchEditorToolsTemplate = ` <div id="batch-editor-tools-wrapper" class="non-selectable"> <div id="batch-editor-tools"> <div class="menu-button" id="exit">退出</div> <div class="menu-button" id="prev">上一頁</div> <div class="menu-button" id="next">下一頁</div> <div class="menu-button" id="trajectory">軌跡</div> <div class="menu-button" id="auto-annotate">自動(dòng)</div> <div class="menu-button" id="auto-annotate-translate-only">自動(dòng)(無旋轉(zhuǎn))</div> <div class="menu-button" id="interpolate">插值</div> <div class="menu-button" id="reload">重新加載</div> <div class="menu-button" id="finalize">定稿</div> </div> </div> `
然后用這個(gè)工具函數(shù)把appendChild
替換掉:
function analyseDomStr(str, target) { // dom字符串, 目標(biāo)元素 const template = document.createElement('template'); template.innerHTML = str; target.appendChild(template.content); }
這樣性能不如之前好, 不過——事件綁定看起來沒什么問題了.
本來想用Document.createDocumentFragment()
API的, 所以初版就寫成這樣了:
function analyseDomStr(str, target) { // dom字符串, 目標(biāo)元素 const fragment = document.createDocumentFragment(); const template = document.createElement('template'); template.innerHTML = str; fragment.appendChild(template.content); // 此處還是要按照原生template的那套來的, 這個(gè)template不會(huì)被vue特殊解析 target.appendChild(fragment); }
很遺憾并不能直接使用innerHTML
向DocumentFragment
內(nèi)寫入DOM, 仍舊需要appendChild
來完成, 所以完全沒有必要?jiǎng)?chuàng)建DocumentFragment
, 我認(rèn)為這個(gè)API更加適合用于對頻繁DOM操作進(jìn)行優(yōu)化, 比如用戶點(diǎn)擊按鈕后就要插入100條tips
, 那就更適合先使用這個(gè)API生成一個(gè)文檔內(nèi)容分段, 然后把成品分段加入DOM.
這個(gè)初版和舊版也都是回流一次…
因?yàn)槲臋n片段存在于內(nèi)存中, 并不在 DOM 樹中, 所以將子元素插入到文檔片段時(shí)不會(huì)引起頁面回流(對元素位置和幾何上的計(jì)算).
因此, 使用文檔片段通常會(huì)帶來更好的性能.
完全可以把:
const ul = document.querySelector('ul'); const li = document.createElement('li'); for (let i = 0; i < 100; i++) { ul.appendChild('li'); }
這種會(huì)引起頁面頻繁回流的寫法
改成
const ul = document.querySelector('ul'); const li = document.createElement('li'); const fragment = document.createDocumentFragment(); for (let i = 0; i < 100; i++) { fragment.appendChild('li'); } ul.appendChild(fragment);
這樣頁面只會(huì)在fragment
被appendChild
后回流一次.
以上就是關(guān)于“Vue中原生template標(biāo)簽失效怎么解決”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對大家有幫助,若想了解更多相關(guān)的知識內(nèi)容,請關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。