Vue中data里沒有申明數據,但是在view里面綁定了數據,當數據改變時,視圖會發生更新嗎,為什么??


例如下面情況:

templete:

<div id="app">
        <h2>{{dataObj.text}}</h2>
</div>

js:

new Vue({
            el: '#app',
            data: {
                dataObj: {}
            },
            ready: function () {
                var self = this;

                /**
                 * 異步請求模擬
                 */
                setTimeout(function () {
                    self.dataObj = {};//真正實現數據更新的是這行代碼
                    self.dataObj['text'] = 'new text';
                }, 3000);
            }
})

上面的代碼非常簡單,我們都知道vue中在data里面聲明的數據才具有響應式的特性,所以我們一開始在data中聲明了一個dataObj空對象,然后在異步請求中執行了兩行代碼,如下:

self.dataObj = {};
self.dataObj['text'] = 'new text';

解決辦法: 首先清空原始數據,然后添加一個text屬性並賦值。然后數據和模版都更新里。

其中.text屬性不具有響應式,但是數據更新了。原因:
vue的dom更新是異步的,即當setter操作發生后,指令並不會立馬更新,指令的更新操作會有一個延遲,當指令更新真正執行的時候,此時.text屬性已經賦值,所以指令更新模板時得到的是新值。
具體流程如下:

self.dataObj = {};發生setter操作
vue監測到setter操作,通知相關指令執行更新操作
self.dataObj[‘text’] = ‘new text’;賦值語句
指令更新開始執行
所以真正的觸發更新操作是self.dataObj = {};這一句引起的,所以單看上述例子,具有響應式特性的數據只有dataObj這一層,它的子屬性是不具備的。

數組更新檢測

Vue 包含一組觀察數組的變異方法,所以它們也將會觸發視圖更新。這些方法如下:

push()
pop()
shift()
unshift()
splice()
sort()
reverse()

注意事項

由於 JavaScript 的限制,Vue 不能檢測以下變動的數組:

當你利用索引直接設置一個項時,例如:vm.items[indexOfItem] = newValue
當你修改數組的長度時,例如:vm.items.length = newLength
舉個例子:

var vm = new Vue({
  data: {
    items: ['a', 'b', 'c']
  }
})
vm.items[1] = 'x' // 不是響應性的
vm.items.length = 2 // 不是響應性的

為了解決第一類問題,以下兩種方式都可以實現和vm.items[indexOfItem] = newValue相同的效果,同時也將觸發狀態更新:

// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)

你也可以使用 vm.$set 實例方法,該方法是全局方法 Vue.set 的一個別名:

vm.$set(vm.items, indexOfItem, newValue)

為了解決第二類問題,你可以使用 splice:

vm.items.splice(newLength)

對象更改檢測注意事項

還是由於 JavaScript 的限制,Vue 不能檢測對象屬性的添加或刪除:

var vm = new Vue({
  data: {
    a: 1
  }
})
// `vm.a` 現在是響應式的

vm.b = 2
// `vm.b` 不是響應式的

對於已經創建的實例,Vue 不能動態添加根級別的響應式屬性。但是,可以使用 Vue.set(object, key, value)方法向嵌套對象添加響應式屬性。例如,對於:

var vm = new Vue({
  data: {
    userProfile: {
      name: 'Anika'
    }
  }
})

你可以添加一個新的 age 屬性到嵌套的 userProfile 對象:

Vue.set(vm.userProfile, 'age', 27)

你還可以使用 vm.$set 實例方法,它只是全局 Vue.set 的別名:

vm.$set(vm.userProfile, 'age', 27)

有時你可能需要為已有對象賦予多個新屬性,比如使用 Object.assign() 或 _.extend()。在這種情況下,你應該用兩個對象的屬性創建一個新的對象。所以,如果你想添加新的響應式屬性,不要像這樣:

Object.assign(vm.userProfile, {
  age: 27,
  favoriteColor: 'Vue Green'
})

你應該這樣做:

vm.userProfile = Object.assign({}, vm.userProfile, {
  age: 27,
  favoriteColor: 'Vue Green'
})

 

 

 

參考文獻:https://blog.csdn.net/weixin_41767649/article/details/82797373


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM