vue指令與$nextTick 操做DOM的不一樣之處

異步更新隊列

可能你尚未注意到,Vue 異步執行 DOM 更新。只要觀察到數據變化,Vue 將開啓一個隊列,並緩衝在同一事件循環中發生的全部數據改變。若是同一個 watcher 被屢次觸發,只會被推入到隊列中一次。這種在緩衝時去除重複數據對於避免沒必要要的計算和 DOM 操做上很是重要。而後,在下一個的事件循環「tick」中,Vue 刷新隊列並執行實際 (已去重的) 工做。Vue 在內部嘗試對異步隊列使用原生的 Promise.then 和 MessageChannel,若是執行環境不支持,會採用 setTimeout(fn, 0) 代替。

例如,當你設置 vm.someData = 'new value' ,該組件不會當即從新渲染。當刷新隊列時,組件會在事件循環隊列清空時的下一個「tick」更新。多數狀況咱們不須要關心這個過程,可是若是你想在 DOM 狀態更新後作點什麼,這就可能會有些棘手。雖然 Vue.js 一般鼓勵開發人員沿着「數據驅動」的方式思考,避免直接接觸 DOM,可是有時咱們確實要這麼作。爲了在數據變化以後等待 Vue 完成更新 DOM ,能夠在數據變化以後當即使用 Vue.nextTick(callback) 。這樣回調函數在 DOM 更新完成後就會調用。例如:vue

<div id="example">{{message}}</div>
var vm = new Vue({
  el: '#example',
  data: {
    message: '123'
  }
})
vm.message = 'new message' // 更改數據
vm.$el.textContent === 'new message' // false
Vue.nextTick(function () {
  vm.$el.textContent === 'new message' // true
})

在組件內使用 vm.$nextTick() 實例方法特別方便,由於它不須要全局 Vue ,而且回調函數中的 this 將自動綁定到當前的 Vue 實例上:node

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) // => '更新完成'
      })
    }
  }
})

vue指令

鉤子函數dom


一個指令定義對象能夠提供以下幾個鉤子函數 (均爲可選):異步

bind:只調用一次,指令第一次綁定到元素時調用。在這裏能夠進行一次性的初始化設置。函數

inserted:被綁定元素插入父節點時調用 (僅保證父節點存在,但不必定已被插入文檔中)。佈局

update:所在組件的 VNode 更新時調用,可是可能發生在其子 VNode 更新以前。指令的值可能發生了改變,也可能沒有。可是你能夠經過比較更新先後的值來忽略沒必要要的模板更新 (詳細的鉤子函數參數見下)。this

componentUpdated:指令所在組件的 VNode 及其子 VNode 所有更新後調用。spa

unbind:只調用一次,指令與元素解綁時調用。code

鉤子函數的參數 (即 el、binding、vnode 和 oldVnode)。component

須要注意的是:update時dom可能尚未插入文檔,componentUpdated是DOM已經插入文檔。而且所謂的「更新」這個鉤子函數的觸發條件很是寬泛,不容易把控。好比,其餘與該節點無關的相鄰節點更新,引起其佈局的重流,也會致使該鉤子函數觸發

所以,若是想要在數據更新後,操做DOM,使用指令的update, componentUpdated 須要謹慎,能夠考慮使用nextTick

相關文章
相關標籤/搜索