vue之nextTick

todo简介:

vue是非常流行的框架,他结合了angular和react的优点,从而形成了一个轻量级的易上手的具有双向数据绑定特性的mvvm框架。本人比较喜欢用之。在我们用vue时,我们经常用到一个方法是this.$nextTick,相信你也用过。我常用的场景是在进行获取数据后,需要对新视图进行下一步操作或者其他操作时,发现获取不到dom。因为赋值操作只完成了数据模型的改变并没有完成视图更新。在这个时候我们需要用到本章介绍的函数。

举例:

new Vue({
  el: '#app',
  data: {
    list: []
  },
  mounted: function () {
    this.get()
  },
  methods: {
    get: function () {
      this.$http.get('/api/article').then(function (res) {
        this.list = res.data.data.list
        // ref  list 引用了ul元素,我想把第一个li颜色变为红色
     
      //下面方法无效 this.$refs.list.getElementsByTagName('li')[0].style.color = 'red'}) //$refs:注①
     
      
//下面方法有效
     this.$nextTick(() => {
      this.$refs.list.getElementsByTagName('li')[0].style.color = 'red'})
     })
  },
 }
})

我在获取到数据后赋值给数据模型中list属性,然后我想引用ul元素找到第一个li把它的颜色变为红色,但是事实上,这个要报错了,我们知道,在执行这句话时,ul下面并没有li,也就是说刚刚进行的赋值操作,当前并没有引起视图层的更新。因此,在这样的情况下,vue给我们提供了$nextTick方法,如果我们想对未来更新后的视图进行操作,我们只需要把要执行的函数传递给this.$nextTick方法,vue就会给我们做这个工作。

上面代码同时显示了nextTick的正确用法

什么时候需要用的Vue.nextTick()

1.你在Vue生命周期的created()钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中。原因是什么呢,原因是在created()钩子函数执行的时候DOM 其实并未进行任何渲染,而此时进行DOM操作无异于徒劳,所以此处一定要将DOM操作的js代码放进Vue.nextTick()的回调函数中。与之对应的就是mounted钩子函数,因为该钩子函数执行时所有的DOM挂载和渲染都已完成,此时在该钩子函数中进行任何DOM操作都不会有问题 。

2.在数据变化后要执行的某个操作,而这个操作需要使用随数据改变而改变的DOM结构的时候,这个操作都应该放进Vue.nextTick()的回调函数中。

原理:

vue更新dom是异步的执行,当监听到数据变化(利用objeect.defineProperty)的时候开启一个队列(异步更新队列),并缓冲在同一事件循环中发生的所有数据变更

例如,当你设置 vm.someData = ‘new value’,该组件不会立即重新渲染。当刷新队列时,组件会在下一个事件循环“tick”中更新。多数情况我们不需要关心这个过程,但是如果你想基于更新后的 DOM 状态来做点什么,这就可能会有些棘手。虽然 Vue.js 通常鼓励开发人员使用“数据驱动”的方式思考,避免直接接触 DOM,但是有时我们必须要这么做。为了在数据变化之后等待 Vue 完成更新 DOM,可以在数据变化之后立即使用 Vue.nextTick(callback)。这样回调函数将在 DOM 更新完成后被调用

源码分析:

 

 

 

 

 

 

注①:

1、说明:vm.$refs 一个对象,持有已注册过 ref 的所有子组件(或HTML元素);

  使用:在 HTML元素 中,添加ref属性,然后在JS中通过vm.$refs.属性来获取;

  获取:如果获取的是一个子组件,那么通过ref就能获取到子组件中的data和methods;

2、添加ref属性:

<div id="app">
    <h1 ref="h1Ele">这是H1</h1>
    <hello ref="ho"></hello>

    <button @click="getref">获取H1元素</button>
</div>

3、获取注册过ref的所有组件或属性

methods: {
    getref() {
      // 表示从 $refs对象 中, 获取 ref 属性值为: h1ele DOM元素或组件
       console.log(this.$refs.h1Ele.innerText);
       this.$refs.h1ele.style.color = 'red';// 修改html样式

       console.log(this.$refs.ho.msg);// 获取组件数据
       console.log(this.$refs.ho.test);// 获取组件的方法
    }
}

 

上一篇:vue 使用nextTick实现数据改变刷新组件


下一篇:nodejs的事件循环机制