vue基础之nexTtick获取更新后的DOM

今天面试时候一个vue的面试题,第一眼看着非常简单,然后信心满满的回答,然后答错了,在此非常感谢面试官对我的引导和帮助!!也通过这次面试意识到自己很多不足需要学习的地方,加油鸭!

面试题是类似这样的代码:

<div id="app">
	<div v-if="showItem" id="content">这是div中的内容div>
	<button @click="showContent">显示button>
div>

<script>
    var vm = new Vue({
      el: '#app',
      data: {
        showItem: false
      },
      methods: {
        showContent() {
          this.showItem = true
          var text = document.getElementById('content').innerHTML
          console.log(text);
        }
      }
    })
  script>

问的是点击按钮以后输出的text是什么值? 我回答肯定是"这是div中的内容"这行字啊,结果并不是,是会在控制台报错的!

这题看着很简单,但是其实涉及了很多vue的基础知识,下面我来慢慢梳理:

首先我们要明白:

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

也就是说,我们在执行同步代码点击按钮把this.showItem设置为true时候,vue并没有立刻渲染这个div DOM,所以我们下面的同步代码document.getElementById('content').innerHTML在执行到getElementById('content')时候就只能得到null,因为目标dom还没开始渲染呢,所以null.innerHTML肯定会报错

为了解决这个问题,就衍生出了这个获取更新后的DOM的Vue方法nextTick()。所以放在Vue.nextTick()回调函数中的执行的应该是会对DOM进行操作的 js代码

理解:nextTick(),是将回调函数延迟在下一次dom更新数据后调用,简单的理解是:当数据更新了,在dom中渲染后,自动执行该函数

所以我们的代码可以修改成这样:

<div id="app">
    <p>vue.$nextTick()示范p>
    <div v-if="showItem" id="content">这是div中的内容div>
    <button @click="showContent">显示button>
  div>
  <script>
    var vm = new Vue({
      el: '#app',
      data: {
        showItem: false
      },
      methods: {
        showContent() {
          this.showItem = true
          this.$nextTick(() => {
            var text = document.getElementById('content').innerHTML
            console.log(text);
          })
        }
      }
    })
  script>

在这里插入图片描述
把需要在DOM更新完毕以后对DOM执行操作的代码放在this.$nextTick()方法里面执行,就可以了

我后来又试了一种方法可以起效果,就是把操作更新后的DOM的代码包裹在setTimeout里面,代码如下:
vue基础之nexTtick获取更新后的DOM_第1张图片
效果:
vue基础之nexTtick获取更新后的DOM_第2张图片
虽然也达到效果了,但是总感觉不太优雅,哈哈

各位大佬讨论,今天就先分享到这里

你可能感兴趣的:(vue,vue,javascript,js)