vue異步加載dom元素之后無(wú)法獲得的解決
vue異步加載dom元素后無(wú)法獲得
vue存在大量的異步加載問(wèn)題,比如動(dòng)態(tài)創(chuàng)建dom元素,若你緊接著去獲取創(chuàng)建的dom元素是獲取不到的。
解決辦法
第一種辦法比較low,使用setTimeout方法,讓獲取dom的代碼在動(dòng)態(tài)創(chuàng)建元素之后一段時(shí)間(這個(gè)時(shí)間非常的短)去執(zhí)行。但這種方法應(yīng)該是存在風(fēng)險(xiǎn)的,不推薦。
第二種辦法 在將要執(zhí)行的代碼上套一層 this.$nextTick()
例如:
this.$nextTick(function() { ? ? ? ? let grids = _that.$refs.datamessage; ? ? ? ? console.log(grids); ? ? ? ? for (let i = 0; i < grids.length; i++) { ? ? ? ? ? let xb = grids[i].getAttribute("index"); ? ? ? ? ? //alert(xb); ? ? ? ? ? if (_that.value.indexOf(xb) != -1) { ? ? ? ? ? ? grids[i].setAttribute("ifSelect", "true"); ? ? ? ? ? ? grids[i].style.backgroundColor = "#b3d8ff"; ? ? ? ? ? ? grids[i].style.color = "#409eff"; ? ? ? ? ? } ? ? ? ? } ? ? ? });
vue穩(wěn)健的獲取dom元素
1、獲取Element的彈框中的Dom元素
**由于彈框由v-if控制,在初始頁(yè)面渲染的時(shí)候,并不存在該Dom元素,所以在mounted中,獲取不到該彈框的Dom元素,無(wú)法添加原生時(shí)間,如下拉加載**
下面提供穩(wěn)健的獲取彈框Dom元素的方法,
首先,由于彈框是由v-if判斷,則可以在watch中監(jiān)聽(tīng)v-if所對(duì)應(yīng)的變量,在為true時(shí),則彈框打開(kāi),此時(shí)去獲取DOM元素,發(fā)現(xiàn)仍然獲取不到。。。。
此時(shí),需要將獲取事件轉(zhuǎn)為異步執(zhí)行,即寫在setTimeout中,即可。穩(wěn)健一些,可以在nextTck中寫出。
(仍舊會(huì)存在問(wèn)題)
若在Element提供的彈框回調(diào)中(彈框打開(kāi)動(dòng)畫結(jié)束),則可以保證取到
<el-dialog ? ? ? :visible.sync="dialogVisible" ? ? ? ref="dialog" ? ? ? @opened="dialogOpened" ? ? >
? dialogOpened() { ? ? ? this.$nextTick(() => { ? ? ? ? setTimeout(() => { ? ? ? ? ? let scrollContent = document.getElementById("scrollContent"); ? ? ? ? ? if (scrollContent) { ? ? ? ? ? ? scrollContent.addEventListener("scroll", this.onScroll); ? ? ? ? ? ? console.log("獲取到滾動(dòng)節(jié)點(diǎn)----"); ? ? ? ? ? } else { ? ? ? ? ? ? console.log("未獲取到滾動(dòng)節(jié)點(diǎn)===="); ? ? ? ? ? } ? ? ? ? }); ? ? ? }); ? ? }
2、如果以上方法均無(wú)法解決
因?yàn)榭赡軘?shù)據(jù)是異步獲取而后填入DOM中,則可以在更新函數(shù)中進(jìn)行獲取DOM的操作,但此時(shí),需要加很多限制,因?yàn)闊o(wú)法限制由誰(shuí)引起的更新!需要標(biāo)志位減少獲取次數(shù)。
可以通過(guò)在watch監(jiān)聽(tīng)函數(shù)中,進(jìn)行標(biāo)志位的更改。
有此想法的前提,是在給element UI 彈框中,嵌套了標(biāo)簽頁(yè) ,在每次切換標(biāo)簽頁(yè)的過(guò)程中,DOM都會(huì)銷毀,所以對(duì)DOM獲取時(shí)機(jī)的把握比較關(guān)鍵,而根據(jù)標(biāo)簽頁(yè)中的數(shù)據(jù)是否渲染完畢后,去獲取改DOM容器,可以說(shuō)是相當(dāng)穩(wěn)健。
無(wú)法獲取Element彈窗內(nèi)嵌套的組件問(wèn)題
問(wèn)題:當(dāng)在el-dialog內(nèi)嵌套組件時(shí),若el-dialog沒(méi)有打開(kāi),則獲取不到其內(nèi)部嵌套的內(nèi)容,ref也不可以
解決方法:在翻閱Element 隱藏滾動(dòng)條部分的源碼時(shí),發(fā)現(xiàn)其獲取dom元素的方法是通過(guò)computed來(lái)獲取
經(jīng)過(guò)驗(yàn)證,可以在彈框打開(kāi)的回調(diào)里面,利用計(jì)算屬性進(jìn)行獲取
?? ?<el-dialog ref="dialog" ?@opened="dialogOpened"> ?? ??? ?<div ref="innerContent"></div> ?? ?</el-dialog>
computed:{ ?? ?getInnerDom(){ ?? ??? ?//此時(shí)之只能獲取到dialog ?? ??? ?console.log(this.$refs) ?? ??? ?return this.$refs.innerContent ?? ?} } methods:{ ?? ?dialogOpened(){ ?? ??? ?//此時(shí)可以獲取到內(nèi)容節(jié)點(diǎn) ?? ??? ?console.log(this.getInnerDom) ?? ?} }
心得
計(jì)算屬性,由于存在緩存,只有在對(duì)應(yīng)依賴變化的時(shí)候才會(huì)變化,而DOM元素只有存在和不存在兩種狀態(tài),
所以,在Dialog沒(méi)有打開(kāi)的時(shí)候,其對(duì)應(yīng)依賴項(xiàng)為空,而當(dāng)依賴項(xiàng)發(fā)生變化時(shí),也即this.$refs.innerContent存在了,getInnerDom才進(jìn)行改變。比在upDated里面獲取要方便很多
重點(diǎn):不清楚在DOM元素高度或者顏色等發(fā)生變化后,會(huì)不會(huì)觸發(fā)computed
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue中的 $slot 獲取插槽的節(jié)點(diǎn)實(shí)例
今天小編就為大家分享一篇vue中的 $slot 獲取插槽的節(jié)點(diǎn)實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-11-11vue-cli中設(shè)置publicPath的幾種方式對(duì)比
這篇文章主要介紹了vue-cli中設(shè)置publicPath的幾種方式對(duì)比,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07