• Vue this.$nextTick原理


      虽然 Vue.js 通常鼓励开发人员沿着“数据驱动”的方式思考,避免直接接触 DOM,但是有时我们确实要这么做。比如一个新闻滚动的列表项。如果在这里需要操作dom, 应该是等待 Vue 完成更新 DOM之后。

    一、新闻滚动列表

    1、在created函数中获取后台数据;

    2、模板引擎中用v-for生成列表项;

    3、调用滚动函数,假设该滚动函数式原生方法写的;

    4、什么时候开始调用滚动函数比较合适呢?

    二、this.$nextTick()

    官方解释:将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。它跟全局方法 Vue.nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例上。

    Vue.component('example', {
      template: '<span>{{ message }}</span>',
      data: function () {
        return {
          message: 'not updated'
        }
      },
      methods: {
        updateMessage: function () {
          this.message = 'updated'
          console.log(this.$el.textContent) // => 'not updated'
          this.$nextTick(function () {
            console.log(this.$el.textContent) // => 'updated'
          })
        }
      }
    })

    三、新闻滚动列表中的this.$nextTick()放哪里?

      因为数据是根据请求之后获取的,所以应该放到请求的回调函数里面。

    四、原理【重点】

    前面只是利用一个例子引入话题。

    在进行获取数据后,需要对新视图进行下一步操作或者其他操作时,为什么获取不到 DOM呢?

    原因:

    这里就涉及到 Vue 一个很重要的概念:异步更新队列(JS运行机制 、 事件循环)。

    Vue 在观察到数据变化时并不是直接更新 DOM,而是开启一个队列,并缓冲同一事件循环中发生的所有数据改变。

    在缓冲时会去除重复数据,从而避免不必要的计算和DOM操作。

    然后,在下一个事件循环 tick 中,Vue 刷新队列并执行实际(已去重的)工作。

    所以如果用 for 循环来动态改变数据100次,其实它只会应用最后一次改变,如果没有这种机制,DOM就要重绘100次,是一个很大的开销,损耗性能。

    例子:

    //改变数据
    vm.message = 'changed'
    
    //想要立即使用更新后的DOM。这样不行,因为设置message后DOM还没有更新
    console.log(vm.$el.textContent) // 并不会得到'changed'
    
    //这样可以,nextTick里面的代码会在DOM更新后执行
    Vue.nextTick(function(){
        console.log(vm.$el.textContent) //可以得到'changed'
    })
    

      

    五、常见应用

    点击按钮显示原本以 v-show = false 隐藏起来的输入框,并获取焦点。

    showsou(){
      this.showit = true //修改 v-show
      document.getElementById("keywords").focus()  //在第一个 tick 里,获取不到输入框,自然也获取不到焦点
    }
    
    //修改
    showsou(){
      this.showit = true
      this.$nextTick(function () {
        // DOM 更新了
        document.getElementById("keywords").focus()
      })
    }
    

      

  • 相关阅读:
    ChinaCock界面控件介绍-CCLoadingIndicator
    delphi-search-path-vs-library-path-vs-browsing-path
    10.3制作Android Splash启动界面
    FMX取得屏分辨率
    REST easy with kbmMW #20 – OpenAPI and Swagger UI
    升级ChinaCock 10.3遇到的问题
    FastJson中的ObjectMapper对象的使用详解
    fastjson的值过滤器ValueFilter
    springboot 2.0 配置 spring.jackson.date-format 不生效
    War 包部署
  • 原文地址:https://www.cnblogs.com/leaf930814/p/7247478.html
Copyright © 2020-2023  润新知