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

laluneX 2020-04-27 07:34:36
/*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');







结果图:
...全文
760 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
laluneX 2020-04-29
  • 打赏
  • 举报
回复
哦哦,我知道了,谢谢
河南棒小伙 2020-04-28
  • 打赏
  • 举报
回复
引用 2 楼 OoOinfinityOoO 的回复:

state.grades[1] = 98;                 /*这些本不应该是响应式的,为什么变成了响应式了呢*/
state.count.names = '毛毛11';
不是说直接使用数组修改值时不会起到响应式的的吗? 而且直接给对象添加属性也是不是响应式的吗?
你这个测试方式有问题,知道吗?原因在于你是这么写的:

 arr(state) {
      state.grades.push(98);                        /*这个是非响应式的为什么也变成响应式了呢?*/
      state.grades[1] = 98;
    },
    obj(state) {
      state.count.names = '毛毛11';                /*这个是非响应式的为什么也变成响应式了呢?*/
      Vue.set(state.count, 'name', '毛毛')
    }
vue里数组的push方法是可以动态响应的,Vue.set方法是动态响应的,所谓的动态响应是数据变化会引起DOM的刷新,但是DOM的重新渲染比较耗费性能,所以Vue的DOM渲染通常是在一波操作之后最后执行,因为如果后续的操作也有数据发生变化的话,可以一次渲染就全部更新了数据。那么你的问题就来了,比如你点击sssss按钮的时候,它先执行push(98),就这一行就会引起DOM的重新渲染,所以最后统一渲染的机制,所以先执行了后续的grades[1]=98,其实这一行代码并不是动态响应的,但是数据已经改了,并不更新DOM,然后由上一句代码引起的DOM更新,统一更新DOM,这个时候捎带着把下一句的数据变化也更新到DOM了。 如果不信的话,其实很好试验,你可以把push的注释掉,单独执行以下grades[1]=98,即可证明,这么赋值确实不是动态响应的。 你下面的对象操作方法也是一样的,直接count.names='毛毛11',不会引起更新,但是Vue.set引起了更新,渲染时一并给渲染了。
laluneX 2020-04-28
  • 打赏
  • 举报
回复

state.grades[1] = 98;                 /*这些本不应该是响应式的,为什么变成了响应式了呢*/
state.count.names = '毛毛11';
不是说直接使用数组修改值时不会起到响应式的的吗? 而且直接给对象添加属性也是不是响应式的吗?
河南棒小伙 2020-04-27
  • 打赏
  • 举报
回复
看vuex的源码你就明白了,store实例化的时候,收集安装完模块之后,会调用resetStoreVM(this,state)方法,该方法中执行了这个

store._vm = new Vue({
    data: {
      $$state: state
    },
    computed
  })
get state () {
    return this._vm._data.$$state
  }
然后你拿到this.$store.state的时候,实际上返回的是this._vm._data_$$state,也就是借用new Vue将state作为Vue的data进行动态响应的。

10,608

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 其他
社区管理员
  • 其他
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧