• vue 之 $nextTick


    官方说明:在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM

    疑问:

    1. DOM 更新循环是指什么?
    2. 下次更新循环是什么时候?
    3. 修改数据之后使用,是加快了数据更新进度吗?
    4. 在什么情况下要用到?

    原理

       vue的响应式并不是数据发生变化之后DOM立即变化,而是按照一定的方式进行DOM的更新

    第一个案例:

    <template>
      <div id="app">
        <input type="text" ref="ipt" v-if="isShow" />
        <button @click="fn" v-else>点击修改</button>
      </div>
    </template>
    
    <script>
    
    export default {
      name: "App",
      data() {
        return {
          isShow: false,
        };
      },
      methods: {
        fn() {
          this.isShow = true;
          console.log(this.$refs.ipt);  // undefined
    this.$refs.ipt.focus() //报错
    }, }, }; </script> <style></style>

    遇到上述情况怎么解决呢?

    this.isShow = true;
    setTimeout(() => {
       console.log(this.$refs.ipt); //<input type="text">
    this.$refs.ipt.focus()
    }, 0); 
    //或者
    this.$nextTick(() => {
    console.log(this.$refs.ipt); //<input type="text">
    this.$refs.ipt.focus()
    });
    
    

    分析:因为  this.isShow = true;时,虚拟dom需要通过diff算法进行更新,这个过程是需要时间的,而同步的代码中,this.$refs.ipt 所需时间 小于  这个渲染时间

    第二个案例

    <template>
      <section>
        <h1 ref="hello">{{ value }}</h1>
        <el-button type="danger" @click="get">点击</el-button>
      </section>
    </template>
    <script>
      export default {
        data() {
          return {
            value: 'Hello World ~'
          };
        },
        methods: {
          get() {
            this.value = '你好啊';
            console.log(this.$refs['hello'].innerText); // Hello World ~
            this.$nextTick(() => {
              console.log(this.$refs['hello'].innerText); // 你好啊
            });
          }
        },
        mounted() {
        },
        created() {
        }
      }
    </script>
    

      

    应用场景:

        需要在视图更新之后,基于新的视图进行操作

    思考的问题:$nextTick  如何 结合 created 和 mounted 来处理问题

    疑问:

    疑问一 . this.$nextTick 为什么要放在 created 或者 mounted ,有什么区别

    疑问二 . 为什么$nextTick能保证子组件都加载完?

    第一步:了解 created

    //组件创建之后
     created() {
          // 可以操作数据,发送ajax请求,并且可以实现
          // vue对页面的影响 应用:发送ajax请求
          console.log('组件创建后:'+this.msg);   //哈哈哈
     }  

    第二步:了解mounted

    //装载数据到DOM之后
     mounted() {
          // 可以操作DOM
          console.log('DOM装载后:'+document.getElementById('app'));  //<div id="app"><div id="test"></div></div>
     }

    第三步:分析

    疑问一

    1.例如在parent 里面有 两个child组件,但是父组件通过异步获取的数据data(created),data里面有childData1 和 childData2 那么此时通过this.$refs.child1是获取不到的,所以需要用到 this.$nextTick,这样可以解决刚才的案例问题(但是,若是同步的组件,那么在parent里面的 mounted 获取 this.$refs.child1也是可以的,那么就不需要该死的this.$nextTick)

    2.将this.$nextTict 写在 created 和 mounted 没太大的区别,只是created 会优先 mounted执行,参考 vue 之 生命周期(钩子)

    疑问二

    如果是同步子组件,mounted 就已经能保证了同步子组件都加载完了。因为对于一个页面来说,第一次 DOM 更新循环结束,也就是 mounted 的时候。

    同步顺序是 parent created → child created → child mounted → child $nextTick → parent mounted → parent $nextTick

    如果是异步子组件,你需要在 mounted 里写 $nextTick,但也并不能完全保证子组件加载完毕,因为异步子组件里还可以再套异步孙子组件。

    总而言之,同步子组件,写 created + $nextTick 和写 mounted 都行;异步子组件,除非是在父组件中直接操作异步子组件的生命周期钩子、或者子组件通过 $emit 的方式通知父组件,否则单纯靠父组件自己,是无法百分百保证的。

    参考:http://errornoerror.com/question/10048646268771205890/

  • 相关阅读:
    python人工智能——机器学习——分类算法k近邻算法——kaggle案例: Facebook V: Predicting Check Ins
    python人工智能——机器学习——分类算法k近邻算法——kaggle案例: Facebook V: Predicting Check Ins
    python人工智能——机器学习——分类算法k近邻算法——kaggle案例: Facebook V: Predicting Check Ins
    js刷新当前页面的5种方式
    再谈Jquery Ajax方法传递到action
    再谈Jquery Ajax方法传递到action
    ContentType是什么意思?
    ContentType是什么意思?
    POST提交数据之ContentType的理解;
    POST提交数据之ContentType的理解;
  • 原文地址:https://www.cnblogs.com/zmztya/p/14476018.html
Copyright © 2020-2023  润新知