提交,但vue提示我在变异处理程序之外改变vuex存储状态'为什么?

时间:2018-04-08 13:02:10

标签: web vue.js frontend vuex

<template>
  <div class="counter-warp">
    <p>make</p>
    <div class="statusCon">
      <p class="card">
        last: {{completed.length > 0 ? completed[completed.length - 1].text : ''}}
      </p>
      <p>completed: {{completed.length}} </p>
      <button @click="showAllSentences">showall</button>
    </div>
    <input v-model="currentText"/>
    <p>remain: {{wordsRemain}}</p>
    <button @click="addSentence">Next</button>

    <a href="/pages/index/main" class="home">home</a>
  </div>
</template>

<script>
// Use Vuex
import { mapGetters } from 'vuex';
import wxapi from '@/lib/wxapi';

export default {
  components: {
  },
  computed: {
    ...mapGetters(['wordsRemain', 'completed']),
    currentText: {
      get() {
        return this.$store.state.make.current.text;
      },
      set(val) {
        this.$store.commit('setText', val);
      },
    },
  },
  methods: {
    addSentence() {
      this.$store.commit('addSentence', this.$store.state.make.current);
    },
    complete() {
      this.$store.dispatch('complete').then((workId) => {
        wxapi.navigateTo({ url: `/pages/index/main?id=${workId}` });
      });
    },
  },
};

</script>
<style>
.counter-warp {
  text-align: center;
  margin-top: 100px;
}
.home {
  display: inline-block;
  margin: 100px auto;
  padding: 5px 10px;
  color: blue;
  border: 1px solid blue;
}

</style>

// store.js
// https://vuex.vuejs.org/zh-cn/intro.html
// make sure to call Vue.use(Vuex) if using a module system
import Sentence from '@/lib/Sentence';
import Constants from '@/lib/Constants';
import { Work, User } from '@/lib';


// 
const ROW_LENGTH = {
  portrait: Constants.WINDOW_WIDTH,
  landscape: Constants.WINDOW_HEIGHT,
};


const store = {
  state: {
    orientation: 'portrait',
    current: new Sentence(),
    sentences: [],
  },
  getters: {
    completed: state => state.sentences,
    sentencesLength: state => state.sentences.length,
    wordsRemain: (state) => {
      const fontSize = state.current.fontSize;
      const marginTextLength = Constants.MARGIN * fontSize;
      const remainPx = ROW_LENGTH[state.orientation] - marginTextLength;
      const textLimit = Math.floor(remainPx / fontSize);
      return textLimit - state.current.text.length;
    },
    // 
    lastSentence: (state, getters) => {
      const obj = state;
      return obj.sentences[getters.sentencesLength - 1];
    },
  },
  mutations: {
    addSentence: (state, sentence) => {
      state.sentences.push(sentence);
      state.current = new Sentence();
      console.log(state);
    },
    setText: (state, text) => {
      state.current.text = text;
    },
  },
  actions: {
    complete: ({ state, commit }) => {
      // commit('setText',)
      // commit('addSentence', state.current);
      const config = Object.assign({}, state);
      commit('setConfig', config);
      const work = new Work();
      work.set('author', User.current);
      work.set('config', config);
      return work.save().then(obj => Promise.resolve(obj.id), (err) => {
        console.log(err);
      });
    },
  },
};

export default store;

当我点击下一个&#39;按钮,&#39; addSentence&#39;应该调用变异处理程序,但是vue提示我&#39; [vuex]不要在变异处理程序之外改变vuex存储状态。

Error: [vuex] Do not mutate vuex store state outside mutation handlers.'

句子是一个简单的类,如{ text:'' ,sth: {}};

1 个答案:

答案 0 :(得分:0)

我认为问题出在组件方法中:

methods: {
    addSentence() {
        this.$store.commit('addSentence', this.$store.state.make.current);
    },
    complete() {
        this.$store.dispatch('complete').then((workId) => {
            wxapi.navigateTo({ url: `/pages/index/main?id=${workId}` });
        });
    }   ,
},

当你调用它时。$ store.state.make.current,这是直接修改商店。您需要做的就是让商店直接在变异中创建当前的句子,而不是向addSentence()添加有效负载。

顺便说一句,您不应该直接从组件调用commit。您需要在商店上调用调度操作,然后通过它提交突变。

模式是:

COMPONENT:

methods: {
    addSentence () {
        this.$store.dispatch('attemptAddSentence');
    },

STORE:

actions: {
    attemptAddSentence (({state, commit}) => {
        return new Promise((resolve, reject) => {
            commit(‘addSentence’)
            resolve()
        })
    }),

mutations: {
    addSentence (state) => {
        // Build sentence here...
    }),

希望有所帮助。