关于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发生变化,更新后执行的回调。

相关文章
相关标签/搜索