zoukankan      html  css  js  c++  java
  • Vue中nextTick()解析

    最近,在开发的时候遇到一个问题,让我对vue中nextTick()的用法加深了了解~

    下面是在组件中引用的一个拖拽的组件:

    <vue-draggable-resizable
         class="drag-img"
         :w="coordinate[0].width"
         :h="coordinate[0].height"
         :x="coordinate[0].abs"
         :y="coordinate[0].ord"
         @dragging="onDragAvator"
         @resizing="onResizeAvator"
         @dragstop="onDragstopAvator"
         @onDragStart="onDragStartAvator"
         :min-width="50"
         :min-height="50"
         :handles="['tl','tr','br','bl']"
         :lock-aspect-ratio="true"
         :parent="true">
         <img @click="setAvatorDafault" src="@/assets/img/icon_touxiang@2x.png" alt="">          
    </vue-draggable-resizable>

    这个拖拽组件的横坐标和纵坐标、宽高是由data的一个数据控制的:

    data() {
       return {
          coordinate:[{
             50,
            height: 50,
            abs: 10,
            ord: 10
          }]  
        }      
    }

    在dragging和resizing的过程中,这个数据和dom的操作应该都是双向绑定的:

    onResizeAvator: function (x, y, width, height) {
        this.coordinate[0].abs = x
        this.coordinate[0].ord = y
    },
    onDragAvator: function (x, y) {
        this.coordinate[0].abs = x
        this.coordinate[0].ord = y
    },
    

    但是,在编辑回显的时候,需要将异步获取的数据赋给coordinate,再显示到页面。

    现在问题来了,当数据coordinate被赋值成异步获取的数据后,页面中的拖拽组件的宽高并没有变化,这是为什么?

    methods: {
      getDefaultData() {
          let that = this
          axios.get(this.$store.state.marketinghost
          + '/fission/task/get/bycode?onlischoolCode=' + this.onlischoolCode
          + '&taskCode=' + this.$route.query.id)
          .then(res => {
            if(res.data.code == "1") {
              var data = res.data.data
              if (data.components.length) {
                that.coordinate = data.components
              }
            }
          })
          .catch((err) => {
            Promise.resolve(err);
          })
      }
    }
    mounted() {
      this.getDefaultData()
    }

     加了一个变量控制拖拽组件后,组件DOM会强制性更新,宽高就变成回显时候的值了

    <vue-draggable-resizable
         class="drag-img"
         v-if="!editLoading"
         :w="coordinate[0].width"
         :h="coordinate[0].height"
         :x="coordinate[0].abs"
         :y="coordinate[0].ord"
         @dragging="onDragAvator"
         @resizing="onResizeAvator"
         @dragstop="onDragstopAvator"
         @onDragStart="onDragStartAvator"
         :min-width="50"
         :min-height="50"
         :handles="['tl','tr','br','bl']"
         :lock-aspect-ratio="true"
         :parent="true">
         <img @click="setAvatorDafault" src="@/assets/img/icon_touxiang@2x.png" alt="">          
    </vue-draggable-resizable>
    data() {
       return {
        editLoading: false, coordinate:[{ 50, height: 50, abs: 10, ord: 10 }] } }
    methods: {
      getDefaultData() { let that
    = this that.editLoading = true axios.get(this.$store.state.marketinghost + '/fission/task/get/bycode?onlischoolCode=' + this.onlischoolCode + '&taskCode=' + this.$route.query.id) .then(res => { if(res.data.code == "1") { var data = res.data.data if (data.components.length) { that.coordinate = data.components that.$nextTick(() => { that.editLoading = false }) } } }) .catch((err) => { Promise.resolve(err); })   }
    }
    mounted() {
      this.
    getDefaultData()
    }

     为了更加了解nextTick(),下面是vue官网关于异步更新队列的解释:

    https://cn.vuejs.org/v2/guide/reactivity.html#%E5%BC%82%E6%AD%A5%E6%9B%B4%E6%96%B0%E9%98%9F%E5%88%97

    总之,当你设置 vm.someData = 'new value',该组件不会立即重新渲染。当刷新队列时,组件会在下一个事件循环“tick”中更新,为了在数据变化之后等待 Vue 完成更新 DOM,可以在数据变化之后立即使用 Vue.nextTick(callback) :

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

     因为nextTick()返回的事一个Promise对象,所以也可以写成async/await的方式:

    methods: {
      updateMessage: async function () {
        this.message = '已更新'
        console.log(this.$el.textContent) // => '未更新'
        await this.$nextTick()
        console.log(this.$el.textContent) // => '已更新'
      }
    }

      

  • 相关阅读:
    IBatis简介
    cntlm代理使用
    bash快捷键你知道几个?
    django的Form中添加属性
    EMACS 中文显示为方框
    git合并子树
    算法 排序 python 实现堆排序
    android org.eclipse.wst.sse.core 0.0.0' but it could not be found
    我的EMACS配置
    python 输入# 自动跳到行首
  • 原文地址:https://www.cnblogs.com/angelatian/p/10943069.html
Copyright © 2011-2022 走看看