【问题标题】:Why won't Vuex getter work in this simple code?为什么 Vuex getter 不能在这个简单的代码中工作?
【发布时间】:2020-03-24 00:18:28
【问题描述】:

我正在尝试创建一个 JSFiddle,以便我可以试验我在实际应用中面临的问题,然后希望将 JSFiddle 展示给其他人。代码如下,我收到一个错误说明

[Vue 警告]:挂载钩子错误:“TypeError: Cannot read property 'length' of undefined”

我做错了什么?

Vue.component('product-info', {
  template: '<div> {{Product[0].ProductTitle}} </div>',
  computed: {

    Product() { return this.$store.getters.getProduct},

  },
  mounted() {
    if (!this.Product.length) {
      this.getProduct();
    }
  },
  methods: {
    getProduct() {
      return this.$store.dispatch('loadProduct')
    }
  }
});

let ProductData = [{
  "ProductID": 101,
  "ProductTypeID": 1,
  "ProductTitle": "Sony PS4 Pro with Death Standing",
  "ProductDescription": "<p>Grab yourself a new console complete with a top title with the Sony PlayStation 4 Pro & Death Stranding Bundle</p>\n  <p>Experience the most spectacular graphics on every game and film with the PlayStation 4 Pro – with 4K Ultra HD resolution and HDR compatibility.  Twice the power as previous models, the PlayStation 4 Pro achieves faster and more stable frame rates as well as incredibly lifelike details.</p>"
}];

const store = new Vuex.Store({
  state: {
    Product: []
  },
  actions: {
    loadProduct({
      commit
    }) {
      commit('setProduct', ProductData)
    }
  },
  getters: {
    getProduct: (state) => state.Product
  },
  mutations: {
    setProduct(state, ProductData) {
      state.Product = ProductData
    }
  }
})

const app = new Vue({
  store,
  el: '#app'
})
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/vuex"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<div id="app">
  <product-info></product-info>
</div>

【问题讨论】:

    标签: vue.js vuejs2 vuex


    【解决方案1】:

    您必须将计算属性声明为函数:

    computed: {
    
        Product() { return this.$store.getters.getProduct }
    
    }
    

    【讨论】:

    • 谢谢!我对其进行了编辑,现在又出现了另一个错误,说 Cannot read property 'length' of undefined。那是因为Product 现在是一种方法而不是一种属性吗?我怎样才能使它成为数据属性?
    • @volumeone 你省略了return。再次检查此答案
    • 是的,你错过了return
    【解决方案2】:

    您从计算变量中错过了 return 它,并在打印之前在您的 template 检查产品的 length

    <div v-if="Product.length">
    

    Vue.component('product-info', {
      template: '<div v-if="Product.length"> {{Product[0].ProductTitle}} </div>',
      computed: {
        Product() { return this.$store.getters.getProduct},
    
      },
      mounted() {
        if (!this.Product.length) {
          this.getProduct();
        }
    
        // you need to right some promise to get value from length in your `axios`, eg:
        setTimeout(() => { console.log('product length:', this.Product.length)}, 1000)
      },
      methods: {
        getProduct() {
          return this.$store.dispatch('loadProduct')
        }
      }
    });
    
    let ProductData = [{
      "ProductID": 101,
      "ProductTypeID": 1,
      "ProductTitle": "Sony PS4 Pro with Death Standing",
      "ProductDescription": "<p>Grab yourself a new console complete with a top title with the Sony PlayStation 4 Pro & Death Stranding Bundle</p>\n  <p>Experience the most spectacular graphics on every game and film with the PlayStation 4 Pro – with 4K Ultra HD resolution and HDR compatibility.  Twice the power as previous models, the PlayStation 4 Pro achieves faster and more stable frame rates as well as incredibly lifelike details.</p>"
    }];
    
    const store = new Vuex.Store({
      state: {
        Product: []
      },
      actions: {
        loadProduct({
          commit
        }) {
          commit('setProduct', ProductData)
        }
      },
      getters: {
        getProduct: (state) => state.Product
      },
      mutations: {
        // you need to write your sxios promise here
        setProduct(state, ProductData) {
          state.Product = ProductData
        }
      }
    })
    
    const app = new Vue({
      store,
      el: '#app'
    })
    <script src="https://unpkg.com/vue"></script>
    <script src="https://unpkg.com/vuex"></script>
    <div id="app">
      <product-info></product-info>
    </div>

    【讨论】:

    • 这个答案实际上解决了我的问题的原因。我错过了&lt;div v-if="Product.length"&gt; {{Product[0].ProductTitle}} &lt;/div&gt;。没有它,我收到 Product[0].ProductTitle 未定义的错误。为什么我已经在签入mounted() 挂钩时必须在模板中签入length
    • @volumeone,因为 HTML 标记会先等待在屏幕上渲染,所以我们需要使用 v-if 来隐藏 vue 的语法来渲染到屏幕并在数据被渲染时导致错误不可用。
    • 如果我在不先检查长度的情况下执行v-for item in Product 循环,它也可以工作。是因为v-for 自动检查长度吗?
    • @volumeone 不,那是因为它循环遍历数组中的项目并且数组最初是空的
    • @lukaszmtw 所以无论如何它都会循环播放?也就是说,数组是空的,所以这不是undefined 错误吗?如果数组最终得到一些数据,它会再次循环遍历它吗?
    猜你喜欢
    • 1970-01-01
    • 2015-07-31
    • 1970-01-01
    • 2013-05-04
    • 2012-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    相关资源
    最近更新 更多