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