1.獲取不到DOM的解決方案(使用$nextTick)
定義:在下次 DOM 更新循環結束之后執行延遲回調。在修改數據之后立即使用這個方法,獲取更新后的 DOM。
理解:nextTick(),是將回調函數延遲在下一次dom更新數據后調用,簡單的理解是:當數據更新了,在dom中渲染后,自動執行該函數.
使用場景:
1.1、Vue生命周期的created()鈎子函數進行的DOM操作一定要放在Vue.nextTick()的回調函數中,原因是在created()鈎子函數執行的時候DOM 其實並未進行任何渲染,而此時進行DOM操作無異於徒勞,所以此處一定要將DOM操作的js代碼放進Vue.nextTick()的回調函數中。與之對應的就是mounted鈎子函數,因為該鈎子函數執行時所有的DOM掛載已完成。
1.2、當項目中你想在改變DOM元素的數據后基於新的dom做點什么,對新DOM一系列的js操作都需要放進Vue.nextTick()的回調函數中;通俗的理解是:更改數據后當你想立即使用js操作新的視圖的時候需要使用它
1.3、在使用某個第三方插件時 ,希望在vue生成的某些dom動態發生變化時重新應用該插件,也會用到該方法,這時候就需要在 $nextTick 的回調函數中執行重新應用插件的方法。
new Vue({ el: '#app', data: { list: [] }, mounted: function () { this.get() }, methods: { get: function () { this.$http.get('/api/article').then(function (res) { this.list = res.data.data.list // ref list 引用了ul元素,我想把第一個li顏色變為紅色 this.$refs.list.getElementsByTagName('li')[0].style.color = 'red' }) }, } })
我在獲取到數據后賦值給數據模型中list屬性,然后我想引用ul元素找到第一個li把它的顏色變為紅色,但是事實上,這個要報錯了,我們知道,在執行這句話時,ul下面並沒有li,也就是說剛剛進行的賦值操作,當前並沒有引起視圖層的更新。因此,在這樣的情況下,vue給我們提供了$nextTick方法,如果我們想對未來更新后的視圖進行操作,我們只需要把要執行的函數傳遞給this.$nextTick方法,vue就會給我們做這個工作。
this.$nextTick(()=> { // DOM 更新了 this.$refs.list.getElementsByTagName('li')[0].style.color = 'red' })
2.改變數據DOM不更新的解決方案
2.1數組
由於 JavaScript 的限制,Vue 不能檢測以下變動的數組:
當你利用索引直接設置一個項時,例如:this.items[indexOfItem] = newValue
當你修改數組的長度時,例如:this.items.length = newLength
解決方案:
- Vue.set(this.items, indexOfItem, newValue)
- this.items.splice(indexOfItem, 1, newValue)
- this.$set(this.items, indexOfItem, newValue) (this.$set 實例方法是全局方法 Vue.set 的一個別名)
- this.items.splice(newLength)
2.2對象
由於 JavaScript 的限制,Vue 不能檢測對象屬性的添加或刪除:
var vm = new Vue({ data: { userProfile: { name: 'Anika' } } }) //你可以添加一個新的 age 屬性到嵌套的 userProfile 對象: Vue.set(vm.userProfile, 'age', 27) //你還可以使用 vm.$set 實例方法,它只是全局 Vue.set 的別名: this.$set(this.userProfile, 'age', 27) //有時你可能需要為已有對象賦予多個新屬性,比如使用 Object.assign() 或 _.extend()。在這種情況下,你應該用兩個對象的屬性創建一個新的對象。 this.userProfile = Object.assign({}, this.userProfile, { age: 27, favoriteColor: 'Vue Green' })
通俗來說:
//刪除對象屬性的方法(前面對象名稱,后面具體屬性名):
this.$delete(this.userProfile, "name");