无法从商店获取计算状态的数据-Vue

时间:2018-07-15 13:54:21

标签: vue.js vuex

我正在学习Vue,一直在努力从计算属性中获取数据。我正在从商店中获取评论,并通过名为chunkify()的函数对其进行处理,但是出现以下错误。

enter image description here

尽管注释已正确计算。

enter image description here

我在这里做错了什么?任何帮助将不胜感激。

Home.vue

export default {
    name: 'Home',
    computed: {
        comments() {
            return this.$store.state.comments
        },
    },
    methods: {
        init() {
            const comments = this.chunkify(this.comments, 3);
            comments[0] = this.chunkify(comments[0], 3);
            comments[1] = this.chunkify(comments[1], 3);
            comments[2] = this.chunkify(comments[2], 3);
            console.log(comments)
        },
        chunkify(a, n) {
            if (n < 2) 
                return [a];

            const len = a.length;
            const out = [];
            let i = 0;
            let size;

            if (len % n === 0) {
                size = Math.floor(len / n);
                while (i < len) {
                    out.push(a.slice(i, i += size));
                }
            } else {
                while (i < len) {
                    size = Math.ceil((len - i) / n--);
                    out.push(a.slice(i, i += size));
                }
            }
            return out;
        },
    },
    mounted() {
        this.init()
    }
}

2 个答案:

答案 0 :(得分:1)

就像我在评论中写道的那样,OP的问题在于,安装组件时,他访问的存储属性不可用(可能正在等待AJAX​​请求进入)。

我不是急切地假设在安装组件时就存在数据,而是建议在加载属性时watch ed和this.init()调用store属性。

但是,我认为这可能不是正确的方法,因为watch方法将在每次属性更改时被调用,这对于在数据上做准备工作的情况不是语义上的。我可以提出两种我认为更优雅的解决方案。

1。加载数据时触发事件

在Vue中设置全局消息传递总线很容易(例如,参见this post)。

假设该属性是通过Vuex动作加载的,则流程类似于:

{
  ...
  actions: {
    async comments() {
      try {
        await loadComments()

        EventBus.trigger("comments:load:success")
      } catch (e) {
        EventBus.trigger("comments:load:error", e)
      }
    }
  }
  ...
}

您可以对反应性和事件再经历一点点反感哲学。但这可能是事件只是语义上的一个例子。

2。反应式方法

我试图将计算保持在我的观点之外。您可以将其绑定到商店中,而不必在组件内部定义chunkify

因此,假设我有一个名为store的JavaScrip模块,该模块可以导出Vuex存储。我会在该模块中将chunkify定义为命名函数

function chunkify (a, n) {
   ...
}

(由于function hoisting,因此可以在JS模块的底部定义,以提高可读性。)

然后,在您的商店定义中,

const store = new Vuex.Store({
  state: { ... },
  ...
  getters: {
    chunkedComments (state) {
      return function (chunks) {
        if (state.comments)
          return chunkify(state.comments, chunks);

        return state.comments
      }
    }
  }
  ...
})

在您的组件中,现在计算出的道具将是

computed: {
  comments() {
    return this.$store.getters.chunkedComments(3);
  },
}

然后,更新用例将从getter流出,当检索到comments时,更新用例将更新,这将更新组件的computed的prop,这将更新ui。

答案 1 :(得分:0)

使用吸气剂,在吸气剂内部合并chuckify和init函数。对于计算后的注释函数将返回this。$ store.getters.YOURFUNC(chuckify和init函数的合并)。不要在已安装的内部添加任何东西。