關於vue中的nextTick深刻理解

1、定義[nextTick、事件循環]

  nextTick的由來:html

    因爲VUE的數據驅動視圖更新,是異步的,即修改數據的當下,視圖不會馬上更新,而是等同一事件循環中的全部數據變化完成以後,再統一進行視圖更新。vue

  nextTick的觸發時機:react

    在同一事件循環中的數據變化後,DOM完成更新,當即執行nextTick(callback)內的回調。bootstrap

  應用場景:api

    須要在視圖更新以後,基於新的視圖進行操做。dom

  以上出現了事件循環的概念,其涉及到JS的運行機制,包括主線程的執行棧、異步隊列、異步API、事件循環的協做,此處不展開以後再總結。大體理解:主線程完成同步環境執行,查詢任務隊列,提取隊首的任務,放入主線程中執行;執行完畢,再重複該操做,該過程稱爲事件循環。而主線程的每次讀取任務隊列操做,是一個事件循環的開始。異步callback不可能處在同一事件循環中。異步

  簡單總結事件循環:ide

    同步代碼執行 -> 查找異步隊列,推入執行棧,執行callback1[事件循環1] ->查找異步隊列,推入執行棧,執行callback2[事件循環2]...post

  即每一個異步callback,最終都會造成本身獨立的一個事件循環。ui

  結合nextTick的由來,能夠推出每一個事件循環中,nextTick觸發的時機:

    同一事件循環中的代碼執行完畢 -> DOM 更新 -> nextTick callback觸發

   tips:本文的任務隊列、消息隊列、異步隊列指同一個東西,均指macrotask queue。

       事件循環詳解:http://www.cnblogs.com/hity-tt/p/6733062.html 

 

上面這些內容純屬是從網上搬運過來的,接下來講說在項目中遇到的問題

    仍是用文字囉嗦點說吧!代碼實在很差展現我想表現的,由於我認爲這種問題會在其餘地方還會有相似問題;

     項目中用到了bootstrap-select.js插件(帶搜索功能的下拉框),相似這樣的插件在vue渲染完數據後確定須要初始化,大概以下

mounted: function () {
    $('#select').selectpicker();
 }

個人業務需求是上面還有一個下拉框須要先選擇上面的,來決定下面顯示哪一個模塊,這時問題就來了,數據發生改變了,個人下拉框就變成以下圖

而後我很機智呀!果斷去watch裏面再初始化一下插件呀!可是發現無效,這下完全懵逼了,後面通過各類打印,各類百度發現了這個東東

複製代碼

watch:{
     type: function (val, oldVal) {
         if(val==2){
             Vue.nextTick(function () {   //或者用 this.$nextTick 
                 $('#select').selectpicker();
              })
      }
     }
}

最近,在項目中要使用Swiper作一個移動端輪播插件。須要先異步動態加載數據後,而後使用v-for渲染節點,再執行插件的滑動輪播行爲。解決這個問題,咱們經過在組件中使用vm.$nextTick來解決這一需求。

1、vm.$nextTick( [callback] )

image.png

 

2、Vue.nextTick( [callback, context] )

image.png

3、異步更新隊列

image.png

 

實例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

<ul id="demo">

    <li v-for="item in list">{{item}}</div>

</ul>

 

new Vue({

    el:'#demo',

    data:{

        list=[0,1,2,3,4,5,6,7,8,9,10]

    },

    methods:{

        push:function(){

            this.list.push(11);

            this.nextTick(function(){

                alert('數據已經更新')

            });

            this.$nextTick(function(){

                alert('v-for渲染已經完成')

            })

        }

    }})

或者:

1

2

3

4

5

6

7

8

9

10

11

this.$http.post(apiUrl)

    .then((response) => {

    if (response.data.success) {

        this.topFocus.data = response.data.data;

        this.$nextTick(function(){

                    //渲染完畢

        });

        }

    }).catch(function(response) {

        console.log(response);

    });

See

 

總結:

* `Vue.nextTick(callback)`,當數據發生變化,更新後執行回調。 * `Vue.$nextTick(callback)`,當dom發生變化,更新後執行的回調。

相關文章
相關標籤/搜索