15

简单理解vue中的nextTick

 3 years ago
source link: http://www.cnblogs.com/leise/p/14194779.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

背景

vue是异步渲染的,当data改变之后,DOM不会立刻被渲染,页面渲染时会将data的修改做整合,多次data修改只会做整合最后一次性渲染出来,这也是异步渲染的原因。只有异步渲染才可以实现整合操作。

例子

methods: {
    update() {
        for (let i = 0; i < 10; i++) {
            this.testNum = this.testNum + i;
        }
    },
},

在你的 Vue 视图中, testNum 会发生变化。不过需要注意的是这个变化的过程,虽然我们把 firstNum 循环修改了 10 次,但是实际上它只会把最后一次的值更新到视图上——这也是非常合理的,比如说我们这个 demo 里,每一次循环给 testNum 的赋值只不过是一个过程,最终的目的是拿到 10 次循环的计算结果而已。如果我们硬去算 10 次,那么不必要的性能开销必然是令人肉疼的。

需求

我们需要对data修改后并拿到DOM,对DOM进行操作解决,

例子

<template>
  <div id="app">
    <ul ref="ul1">
      <li v-for="(v, i) in list" :key="i">{{ v }}</li>
    </ul>
    <button @click="add">add DOM</button>
  </div>
</template>
<script>
export default {
  name: "app",
  data() {
    return {
      list: ["a", "b", "c"],
    };
  },
  methods: {
    add() {
      this.list.push(`${Date.now()}`);
      this.list.push(`${Date.now()}`);
      this.list.push(`${Date.now()}`);
      const ulElem = this.$refs.ul1;
      console.log(ulElem.childNodes.length);
    },
  },
};
</script>

IfeQV3I.png!mobile

本来点击完之后数组长度应该输出6个,但是实际上数组长度只有3个,因为data改变后,DOM并不会立刻改变,此时我们是拿不到新增的节点的,这时候的DOM节点还是一开始的a,b,c 。DOM操作执行完之后,它再异步渲染。

不过我们的期望是点击完之后立刻拿到后面的三个,这时候就需要请出我们的主角nextTick。

add() {
      this.list.push(`${Date.now()}`);
      this.list.push(`${Date.now()}`);
      this.list.push(`${Date.now()}`);
      const ulElem = this.$refs.ul1;
      this.$nextTick(() => {
        console.log(ulElem.childNodes.length);
      });
    },

UBBjaeU.png!mobile

这个例子也可以看出, $nextTick会待DOM渲染完成再回调 ,同时也可以看出,我们虽然一次点击有三次修改data,但是多次修改会进行整合,最后渲染一次,这也说明渲染也是异步的,如果是同步,就没办法整合。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK