关于vuex的数据不直接给data而要通过computed


为什么vuex的数据不直接给data而要通过computed计算

疑惑

其实一直以来使用vue的状态管理vuex都有一个疑惑,文档中介绍,vue的状态数据$store.state.xx的在组件中的使用通常都是通过组件的计算属性computed来使用如下:

const Counter = {
  template: `
{{ count }}
`, computed: { count () { return this.$store.state.count } } }

虽然一直这么用 但是还是奇怪为啥这种下面这中方式为啥行不通:

const Counter = {
  template: `
{{ count }}
`, 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也是可以的。