使用计算 属性 (Vuex) 时 $store 属性不是反应性的
$store properties are not reactive when using computed property (Vuex)
我有一个 Vuex 存储,我正在将其注入到我的实例中:
import store from '../store';
const mainNav = new Vue({
el: '#main-nav',
store,
components: { NavComponent }
});
我正在从组件中的那个商店创建一个计算 属性:
computed: {
isWide() {
return this.$store.state.nav.type === 'wide';
}
}
这确实会在组件初始化时为模板创建 this.isWide
属性,但是当更新存储值时,组件不会注册它 - 旧值仍在模板上.
我做错了什么?
如果您正确设置了所有内容,您的代码应该可以工作:http://codepen.io/CodinCat/pen/RKZeZe?editors=1010
一个很常见的错误是你没有给你的状态初始数据。
您应该明确声明状态形状,而不是
state: {}
// or
state: {
nav: {}
}
这样做:
state: {
nav: {
type: '...'
},
...
}
或者属性不会反应,就像这个例子:http://codepen.io/CodinCat/pen/ggxBEV?editors=1010
并确保您确实更新了状态,也许问题只是您没有按预期正确更新状态。
你不应该直接从组件方法操作存储对象,你应该对存储对象进行修改。突变是具有侦听器的函数,当被调用时,更改的变量会被跟踪并传播更改。如果你需要做一些异步的事情,比如向服务器提交数据,你甚至必须进一步定义存储上的操作,进行异步调用,然后从那里提交突变以更新状态对象。我知道这听起来很烦人,但一旦你习惯了,它就非常简单了。
const store = new Vuex.Store({
state: {
nav: {
type: 'not wide by default'
}
},
mutations: {
changeType: (state, type) => {
state.nav.type = type;
}
}
})
Vue.component('NavComponent', {
template: '<div>isWide?: {{isWide}}</div>',
computed: {
isWide () {
return this.$store.state.nav.type === 'wide'
}
}
})
new Vue({
el: '#app',
store,
methods: {
changeType (type) {
this.$store.commit('changeType', type);
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/2.1.0/vuex.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.8/vue.js"></script>
<div id="app">
<nav-component></nav-component>
<button @click="changeType('wide')">
Change to Wide
</button>
<button @click="changeType('narrow')">
Change to Narrow
</button>
</div>
https://codepen.io/zoransa/pen/KyqvWd?editors=1010
它也可以直接在 stat.nav 上工作而无需类型
https://codepen.io/zoransa/pen/xPrLyW?editors=1010
实际上,您需要使用 Vue.set() 函数来使新的 属性 具有反应性。
changeType () {
Vue.set(this.$store.state.nav, 'type', 'wide');
}
查看此代码笔:https://codepen.io/DedicatedManager/pen/JZgpaa
我做了一个关于这个主题的全屏捕获视频:youtu。be/8GHczab2Lbs
这是我的问题。
const store = new Vuex.Store({
state: {
isTrackPlaying: false,
},
...
});
我忘了设置初始状态,现在它是反应式的。
向 Vuex
商店中的对象添加新属性时,您应该使用
Vue.set(obj, 'newProp', 123)
或者用一个新的对象替换那个对象
state.obj = { ...state.obj, newProp: 123 }
我是这样解决问题的:
我有包含其他对象的状态对象。每当有突变时,我都尝试使用 Vue.set,但它很乱,仍然没有用。
所以我创建了一个名为 toggleState 的布尔状态变量,并为其提供了一个 getter。每当一个突变改变了一个主状态对象时,它也会做 state.stateToggle =! state.stateToggle
。
任何关心的人都可以观察 stateToggle 的变化,并做任何需要做的事情。在我的例子中,它是用变异的主要对象重建树视图。
两者都是反应性的
$vm.$set
this.$set(some_object, 'key', 'value')
Vue.set
Vue.set(some_object, 'key', 'value')
在我的例子中,我只是忘记在我的突变中传递变量 'state',因此,它不是反应性的
const mutations = {
[mutationTypes.storeTaskStart](state) {
state.isSubmitting = true;
},
};
我有一个 Vuex 存储,我正在将其注入到我的实例中:
import store from '../store';
const mainNav = new Vue({
el: '#main-nav',
store,
components: { NavComponent }
});
我正在从组件中的那个商店创建一个计算 属性:
computed: {
isWide() {
return this.$store.state.nav.type === 'wide';
}
}
这确实会在组件初始化时为模板创建 this.isWide
属性,但是当更新存储值时,组件不会注册它 - 旧值仍在模板上.
我做错了什么?
如果您正确设置了所有内容,您的代码应该可以工作:http://codepen.io/CodinCat/pen/RKZeZe?editors=1010
一个很常见的错误是你没有给你的状态初始数据。
您应该明确声明状态形状,而不是
state: {}
// or
state: {
nav: {}
}
这样做:
state: {
nav: {
type: '...'
},
...
}
或者属性不会反应,就像这个例子:http://codepen.io/CodinCat/pen/ggxBEV?editors=1010
并确保您确实更新了状态,也许问题只是您没有按预期正确更新状态。
你不应该直接从组件方法操作存储对象,你应该对存储对象进行修改。突变是具有侦听器的函数,当被调用时,更改的变量会被跟踪并传播更改。如果你需要做一些异步的事情,比如向服务器提交数据,你甚至必须进一步定义存储上的操作,进行异步调用,然后从那里提交突变以更新状态对象。我知道这听起来很烦人,但一旦你习惯了,它就非常简单了。
const store = new Vuex.Store({
state: {
nav: {
type: 'not wide by default'
}
},
mutations: {
changeType: (state, type) => {
state.nav.type = type;
}
}
})
Vue.component('NavComponent', {
template: '<div>isWide?: {{isWide}}</div>',
computed: {
isWide () {
return this.$store.state.nav.type === 'wide'
}
}
})
new Vue({
el: '#app',
store,
methods: {
changeType (type) {
this.$store.commit('changeType', type);
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/2.1.0/vuex.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.8/vue.js"></script>
<div id="app">
<nav-component></nav-component>
<button @click="changeType('wide')">
Change to Wide
</button>
<button @click="changeType('narrow')">
Change to Narrow
</button>
</div>
https://codepen.io/zoransa/pen/KyqvWd?editors=1010
它也可以直接在 stat.nav 上工作而无需类型 https://codepen.io/zoransa/pen/xPrLyW?editors=1010
实际上,您需要使用 Vue.set() 函数来使新的 属性 具有反应性。
changeType () {
Vue.set(this.$store.state.nav, 'type', 'wide');
}
查看此代码笔:https://codepen.io/DedicatedManager/pen/JZgpaa
我做了一个关于这个主题的全屏捕获视频:youtu。be/8GHczab2Lbs
这是我的问题。
const store = new Vuex.Store({
state: {
isTrackPlaying: false,
},
...
});
我忘了设置初始状态,现在它是反应式的。
向 Vuex
商店中的对象添加新属性时,您应该使用
Vue.set(obj, 'newProp', 123)
或者用一个新的对象替换那个对象
state.obj = { ...state.obj, newProp: 123 }
我是这样解决问题的:
我有包含其他对象的状态对象。每当有突变时,我都尝试使用 Vue.set,但它很乱,仍然没有用。
所以我创建了一个名为 toggleState 的布尔状态变量,并为其提供了一个 getter。每当一个突变改变了一个主状态对象时,它也会做 state.stateToggle =! state.stateToggle
。
任何关心的人都可以观察 stateToggle 的变化,并做任何需要做的事情。在我的例子中,它是用变异的主要对象重建树视图。
两者都是反应性的
$vm.$set
this.$set(some_object, 'key', 'value')
Vue.set
Vue.set(some_object, 'key', 'value')
在我的例子中,我只是忘记在我的突变中传递变量 'state',因此,它不是反应性的
const mutations = {
[mutationTypes.storeTaskStart](state) {
state.isSubmitting = true;
},
};