使用计算属性时,Vuex $ store属性不起作用

时间:2017-01-25 12:29:43

标签: vue.js 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属性,但是当更新存储值时,组件不会注册它 - 旧值仍在模板上。

我在这里做错了什么?

7 个答案:

答案 0 :(得分:19)

如果您正确设置了所有内容,您的代码应该可以正常运行:http://codepen.io/CodinCat/pen/RKZeZe?editors=1010

一个非常常见的错误是您没有提供州的初始数据。

您应该明确声明状态形状,而不是

state: {}

// or

state: {
  nav: {}
}

这样做:

state: {
  nav: {
    type: '...'
  },
  ...
}

或属性不会被动反应,例如:http://codepen.io/CodinCat/pen/ggxBEV?editors=1010

并确保你确实更新了状态,也许问题只是你没有按照预期正确更新状态。

答案 1 :(得分:3)

实际上,您需要使用Vue.set()函数使新属性具有反应性。

changeType () {
   Vue.set(this.$store.state.nav, 'type', 'wide');
}

请参阅以下代码笔:https://codepen.io/DedicatedManager/pen/JZgpaa

我做了一个全屏拍摄有关这个主题的视频:youtu.be/8GHczab2Lbs

答案 2 :(得分:2)

你不应该直接从组件方法操作商店对象,你应该在商店对象上提交突变。变异是具有侦听器的函数,当被调用时,变量变量被跟踪并且变化被传播。如果你需要做一些异步,比如向服务器提交数据,你必须进一步定义对商店的操作,做异步调用,然后从那里提交突变来更新状态对象。我知道这听起来很烦人但是一旦你习惯了它就会非常直接。



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);
    }
  }
})
&#13;
<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>
&#13;
&#13;
&#13;

https://codepen.io/zoransa/pen/KyqvWd?editors=1010

它也可以在没有类型的情况下直接在stat.nav上运行 https://codepen.io/zoransa/pen/xPrLyW?editors=1010

答案 3 :(得分:0)

这是我的问题。

  const store = new Vuex.Store({
    state: {
      isTrackPlaying: false,
    },
  ...
  });

我忘了设置初始状态,现在它是反应性的。

答案 4 :(得分:0)

Vuex存储向对象添加新属性时,您应该使用

Vue.set(obj, 'newProp', 123)

或用新对象替换该对象

state.obj = { ...state.obj, newProp: 123 }

来自Vuex docs

答案 5 :(得分:0)

这是我解决问题的方法:

我有包含其他对象的状态对象。每当出现突变时,我都尝试使用Vue.set,但它很杂乱,仍然无法正常工作。 因此,我创建了一个名为toggleState的布尔状态变量,并为其提供了一个吸气剂。每当变异更改主状态对象时,它也会执行state.stateToggle =! state.stateToggle。 任何关心的人都可以监视stateToggle的更改,并执行所需的任何操作。就我而言,它正在使用变异的主要对象重新构建树形视图。

答案 6 :(得分:0)

两者都是反应式

$vm.$set

this.$set(some_object, 'key', 'value')

Vue.set

Vue.set(some_object, 'key', 'value')