尝试使用Vuex getter检索一个元素时出错

时间:2018-03-11 19:12:40

标签: vue.js vuejs2 single-page-application vue-router vuex

我正在使用Vue / Vuex / Vue-router创建单页应用。

基本上我在从显示的列表中选择一条记录后尝试检索一条记录,我的商店基本上包含:

export const store = new Vuex.Store({
  state: {
    reports: null,
    loading: false,
    reportProcessing: false
  },
  getters: {
    getReports (state) {
      return state.reports
    },
    getReport (state) {
      return (id) => {
        return state.reports.find((item) => {
          return item.id === id
        })
      }
    }
  }
  // ...

当我尝试与

一起使用时
data () {
  return {
    // Attempt to load the report by passing the current id
    report: JSON.parse(JSON.stringify(this.$store.getters.getReport(this.id))),
// ...

它显示"SyntaxError: Unexpected token u in JSON at position 0"的错误基本上返回一个null / empty对象,这实在令人困惑,因为它可以工作(从对象列表中选择第一个元素):

JSON.parse(JSON.stringify(this.$store.getters.getReports[0])),

所以我知道对象列表包含报告(并且getter似乎正常运行)。但是,当尝试像this.$store.getters.getReport(1)

那样手动传递ID时,它无法正常工作

究竟我在这里做错了什么?

编辑: 我当前的路由器文件设置为(对于单个报告路由)

{
  path: '/report/:id',
  props: true,
  component: MainLayout,
  children: [
    { path: '', name: 'edit_report', component: EditReport }
  ]
}

基本上我使用vue-router的子路由来加载具有主菜单的布局中的组件,但是当我为该路由删除此函数时:

{
  path: '/report/:id',
  name: 'edit_report',
  props: true,
  component: EditReport
}

它工作(显然没有被加载到主要布局中),不用说这不是修复(因为我仍然需要它像所有其他页面一样加载到主布局内),但也许它有一些与我做错的关系?

1 个答案:

答案 0 :(得分:1)

您正在使用不存在的this.id.find() getter中的getReports()将返回undefined,而JSON.parse()会抛出该错误。

以下是JSON.parse(JSON.stringify(this.$store.getters.getReport(this.id)))的细分,this.id等于6

  • this.$store.getters.getReport(6)返回undefined
  • JSON.stringify(undefined)返回undefined
  • JSON.parse(undefined)引发Uncaught SyntaxError: Unexpected token u in JSON at position 0错误。

下面的演示。

const store = new Vuex.Store({
  strict: true,
  state: {
    reports: [{id: 1}, {id: 2}],
    loading: false,
    reportProcessing: false
  },
  getters: {
    getReports (state) {
      return state.reports
    },
    getReport (state) {
      return (id) => {
        return state.reports.find((item) => {
          return item.id === id
        })
      }
    }
  }
});
new Vue({
  store,
  el: '#app',
  computed: {
    reports: function() {
      return this.$store.state.reports
    },
  },
  methods: {
    callGetReport() {
      console.log(this.$store.getters.getReport(6));
      console.log(JSON.stringify(this.$store.getters.getReport(6)));
      console.log(JSON.parse(JSON.stringify(this.$store.getters.getReport(6))));
    }
  }
})
<script src="https://unpkg.com/vue@2.5.15/dist/vue.min.js"></script>
<script src="https://unpkg.com/vuex"></script>

<div id="app">
  <p>Reports: {{ reports }}</p>
  <button @click="callGetReport">Click here to call getReport() - open browser's console to see result</button>
</div>

将道具传递给子(嵌套)路线

由于id未开启,您未在嵌套路线中获得props

{
  path: '/report/:id',
  props: true,
  component: MainLayout,
  children: [
    { path: '', name: 'edit_report', component: EditReport, props: true }
                                                       // ^^^^^^^^^^^^^ ------ added this
  ]
}