Vue异步更新DOM

  我们在使用Vue的过程中把注意力都放在了数据操作上,而忽略了关于DOM的一些东西。

  场景1:在created生命周期从后端获取数据后想要对DOM进行操作,发生报错,当然这时候DOM元素还没渲染完成怎么会操作成功,但是我就要操作DOM怎么办?

  场景2:使用 swiper 插件通过 ajax 请求图片后的滑动问题。 

  首先我们要对vue的数据更新有一定理解: vue是依靠数据驱动视图更新的,该更新的过程是异步的。即:当侦听到你的数据发生变化时, Vue将开启一个队列(该队列被Vue官方称为异步更新队列)。视图需要等队列中所有数据变化完成之后,再统一进行更新。

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

 1 <div id="App">
 2     <input type="button" value="改变文本" @click="change">
 3     <p ref="myP">{{str}}</p>
 4 </div>
 5 <script>
 6     new Vue({
 7         el:"#App",
 8         data:{
 9             str:"我之前很瘦的。"
10         },
11         methods:{
12             change(){
13                 this.str = "现在超胖了!";
14                 //此时DOM 并没有更新
15                 console.log(this.$refs.myP.innerText)// 输出结果:我之前很瘦的。
16                 this.$nextTick(() => {
17                   //此时DOM更新了
18                   console.log(this.$refs.myP.innerText)  // 输出结果:现在超胖了!
19                  })
20             }
21         }
22     })
23 </script>

  

  因为 $nextTick() 返回一个 Promise 对象,所以你可以使用新的 ES2017 async/await 语法完成相同的事情:

1  methods:{
2            change(){
3                this.str = "现在超胖了!";
4                console.log(this.$refs.myP.innerText)// 我之前很瘦的。
5                await this.$nextTick()
6                console.log(this.$el.textContent) // 现在超胖了!
7            }
8        }
9      

  nextTick原理

  1、异步说明
    Vue 实现响应式并不是数据发生变化之后 DOM 立即变化,而是按一定的策略进行 DOM 的更新
  2、事件循环说明
    简单来说,Vue 在修改数据后,视图不会立刻更新,而是等同一事件循环中的所有数据变化完成之后,再统一进行视图更新。

  

上一篇:Vue $nextTick


下一篇:Vue学习笔记(十七)——$nextTick()的使用场景