溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

vue獲取v-for異步數(shù)據(jù)dom問題怎么解決

發(fā)布時間:2023-03-25 15:10:50 來源:億速云 閱讀:121 作者:iii 欄目:開發(fā)技術

這篇文章主要講解了“vue獲取v-for異步數(shù)據(jù)dom問題怎么解決”,文中的講解內(nèi)容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“vue獲取v-for異步數(shù)據(jù)dom問題怎么解決”吧!

    vue獲取v-for異步數(shù)據(jù)dom

    問題描述

    每次加載界面時,在 mounted階段,只能獲取普通dom(指靜態(tài)渲染的dom),獲取不到v-for的dom,盡管使用$nextTick也獲取不到,雖然使用setTimeOut能解決,但這種方法真的很low,作為程序員要追求完美,下面我們看看怎么完美解決這個問題。

    原因

    在v-for里的數(shù)據(jù)是異步獲取的,里面的id或者class也都是動態(tài)綁定的,而mounted階段只是實例掛載完成,這時候異步請求的數(shù)據(jù)大概率還沒請求完成,從而v-for要渲染的dom肯定也還沒開始渲染,這時候連異步請求的數(shù)據(jù)都獲取不到,更別說需要異步數(shù)據(jù)來渲染的dom了。

    $nextTick是指整個視圖渲染完成,注意這里不包含異步請求的數(shù)據(jù),在整個視圖渲染完成時異步數(shù)據(jù)未必能請求到。所以調(diào)用$nextTick其實也沒什么兩樣。

    解決思路及方案

    第一種并不是很完美的方案:使用updated鉤子

    updated 階段是完成了數(shù)據(jù)更新到 DOM 的階段(對加載回來的數(shù)據(jù)進行處理),此時,在使用document等獲取dom是可以得到的。

    updated 與 mounted 不同的是,在每一次的 DOM 結構更新,Vue.js 都會調(diào)用一次 updated 鉤子函數(shù)!而 mounted 鉤子函數(shù)僅僅只執(zhí)行一次而已。

    但是,本人不推薦這么做,因為如果項目中數(shù)據(jù)更新很頻繁,虛擬dom也會跟著經(jīng)常更新,如果在updated中獲取dom,會造成操作過于頻繁的問題,也就會多多少少影響程序性能。在vue官方也有提到。

    vue獲取v-for異步數(shù)據(jù)dom問題怎么解決

    完美解決的方案:在異步數(shù)據(jù)獲取完成時調(diào)用$nextTick獲取dom

    想獲取異步請求數(shù)據(jù)渲染的dom就一定得等到數(shù)據(jù)接收到后再進行相應的操作。而有同學就問了,為什么在獲取到數(shù)據(jù)后還要調(diào)$nextTick呢?

    因為獲取到數(shù)據(jù)之后v-for去動態(tài)渲染dom肯定也是需要一定時間的,不可能馬上就能渲染完成,所以在獲取到異步數(shù)據(jù)之后再等整個視圖渲染完成時去獲取dom是最好的選擇。

    那要在created或者mounted或者在watch中獲取就看個人選擇了。

    created或者mounted中需要在獲取完數(shù)據(jù)后在then或者await接受返回的數(shù)據(jù)再調(diào)用$nextTick獲取dom,在watch中就直接監(jiān)視請求的數(shù)據(jù),數(shù)據(jù)改變就說明獲取到了,就可以調(diào)用$nextTick獲取dom了。

    vue獲取DOM問題

    利用 ref 和 $refs 可以用于獲取 dom 元素

    <h2 id="h" ref="myH">我是一個孤獨可憐又能吃的h2</h2>
     
    mounted() {
        console.log(document.getElementById("h"));
        console.log(this.$refs.myH);
      },

    使用ref調(diào)用組件內(nèi)的方法。

    <Demo ref="de"></Demo>
     
    import Demo from "./child/demo";
     
    //組件起別名ref
    let demoObj = this.$refs.de;
    //可以以此調(diào)用組件內(nèi)的方法,變量等
        demoObj.fn();

    $nextTick使用

    如果我們修改某個出現(xiàn)在DOM里的變量,之后又要獲取DOM里的變量值,那么會發(fā)現(xiàn)DOM里變量值并未修改成功,因為Vue更新DOM是異步的,用$nextTick解決。

    因為vue 通過異步隊列控制 DOM 更新和 nextTick 回調(diào)函數(shù)先后執(zhí)行。

    <p ref="myP">{{ count }}</p>
    <button @click="btn">點擊count+1, 馬上提取p標簽內(nèi)容</button>
     
    btn() {
          this.count++; // vue監(jiān)測數(shù)據(jù)更新, 開啟一個DOM更新隊列(異步任務)
          console.log(this.count) //1
          //因為Vue更新DOM是異步的,所以count雖然完成加一,但這里的DOM還未更新。
          console.log(this.$refs.myP.innerHTML); // 0
     
          // 解決: this.$nextTick()
          // 過程: DOM更新完會挨個觸發(fā)$nextTick里的函數(shù)體
          this.$nextTick(() => {
            console.log(this.$refs.myP.innerHTML); // 1
          });
     
          //方法二: async 函數(shù)執(zhí)行時, async btn(){}
          //如果遇到 await 就會先暫停執(zhí)行 ,等到觸發(fā)的異步操作完成后,
          //恢復 async 函數(shù)的執(zhí)行并返回解析值
          await this.$nextTick()
          this.$refs.myP.innerHTML
      },

    組件name屬性使用 

    我們封裝的組件-可以自己定義name屬性組件名-讓使用者有個統(tǒng)一的前綴風格

    1.給組件(Demo)起個名字,用組件的name屬性值, 來注冊組件名字

    export default {
      name: "Mmm",
    }

    2.之后就可以用Mmm當作標簽使用

    import Demo from "./child/demo";
     
    components: {
        // Demo,
        [Demo.name]: Demo,
      },

    感謝各位的閱讀,以上就是“vue獲取v-for異步數(shù)據(jù)dom問題怎么解決”的內(nèi)容了,經(jīng)過本文的學習后,相信大家對vue獲取v-for異步數(shù)據(jù)dom問題怎么解決這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

    向AI問一下細節(jié)

    免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

    AI