在使用vuex的时候vue数据的响应式问题

/*App.vue文件*/
<template>
  <div>
    <h2>{{ $store.state.count }}</h2>
    <h2>{{ $store.state.grades }}</h2>
    <button @click="change">sssss</button>
    <button @click="changes">111111</button>
  </div>
</template>

<script>
  export default {
    name: 'App',
    methods: {
      change() {
        this.$store.commit({
          type: 'arr'
        });
      },
      changes() {
        this.$store.commit({
          type: 'obj'
        });
      }
    }
  }
</script>

<style>

</style>


/*store里面的index.js文件*/
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    count: { id: 1, age: 10 },
    grades: [20, 30, 40, 50, 60]
  },
  mutations: {
    arr(state) {
      state.grades.push(98);                        /*这个是非响应式的为什么也变成响应式了呢?*/
      state.grades[1] = 98;
    },
    obj(state) {
      state.count.names = '毛毛11';                /*这个是非响应式的为什么也变成响应式了呢?*/
      Vue.set(state.count, 'name', '毛毛')
    }
  },
  actions: {

  },
  getters: {

  },
  modules: {

  }
});

export default store;



/*main.js文件*/
import Vue from 'vue'
import App from './App.vue'
import store from '@/store';

Vue.config.productionTip = false;

new Vue({
  store,
  render: h => h(App)
}).$mount('#app');


结果图:
图片说明

参考GPT和自己的思路:

在使用Vuex时,对于state中嵌套的对象和数组,对其进行修改时是存在响应式的,但是直接替换对象或者数组时,就不会有响应式了。

对于对象的修改,可以使用Vue.set() 方法来更新对象,并且保证响应式更新。

对于数组的操作有一些需要注意的地方:

  1. push() 方法也是有响应式的,因为它会在原数组的基础上进行修改,不会直接替换数组。
  2. 直接通过下标修改数组的值也是有响应式的,因为Vue会自动监测数组元素的变化。
  3. 直接替换数组是没有响应式的,因为原数组已经被替换,需要使用Vue.set() 或者 splice() 方法来完成响应式更新。

在上面的代码中,修改grades数组的操作是存在响应式的,因为调用了push() 和直接通过下标修改值的方法。而修改count对象的操作,采用了Vue.set() 方法来更新对象,所以也是存在响应式的。