為什么vuex的數據不直接給data而要通過computed計算
疑惑
其實一直以來使用vue的狀態管理vuex都有一個疑惑,文檔中介紹,vue的狀態數據$store.state.xx
的在組件中的使用通常都是通過組件的計算屬性computed來使用如下:
const Counter = {
template: `<div>{{ count }}</div>`,
computed: {
count () {
return this.$store.state.count
}
}
}
雖然一直這么用 但是還是奇怪為啥這種下面這中方式為啥行不通:
const Counter = {
template: `<div>{{ count }}</div>`,
data() {
return {
count: this.$store.state.count
}
}
}
上面這種形式,如果另外一個組件修改了$store.state.count
的值,視圖中count是不會發生變化的
解惑
最近又重新了解下vue的基本原理,vue是通過Object.defineProperty()
,來給vue實例化的對象$vm掛載數據(vue實例化傳入的data對象),然后通過setter方法監控數據變化進而操作dom實時地改變了視圖。
var obj = {};
var initValue = 'hello';
Object.defineProperty(obj,"newKey",{
get:function (){
//當獲取值的時候觸發的函數
return initValue;
},
set:function (value){
//當設置值的時候觸發的函數,設置的新值通過參數value拿到
initValue = value;
// vue中 這里操作dom 修改視圖 代碼若干(詳見源碼)
// ...
}
});
//獲取值
console.log( obj.newKey ); //hello
//設置值
//因為這一步賦值,觸發了set函數 因此dom發生改變
obj.newKey = 'change value';
console.log( obj.newKey ); //change value
通過上面對Object.defineProperty()
的理解,大概可以看出:
在實例化vue對象的時候會把data初始數據掛載化到vue上,所以data() { return { count: this.$store.state.count } }
只是把$store.state.count
的初始值賦給了$vm.count
,是能在視圖中顯示出初始值的。
但是當 $store.state.count
發生改變,實際上$vm.count
還是原來的初始值沒有任何變化,所以視圖就不能響應了!因此視圖中需要使用計算屬性computed根據狀態計算出新的結果。
另外視圖中直接用$store.state.count
也是可以的。