You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue选项式API开发食谱应用时$store访问报错求助

问题分析与解决

错误核心原因

你遇到的Cannot read properties of undefined (reading '$store')错误,本质是组件选项中computed的写法完全错误:

  • 你直接在computed字段中执行this.$store.commit,但此时组件实例还未初始化,this为undefined,自然无法访问$store。
  • computed的正确写法是包含计算属性函数的对象,而非直接执行代码。

除此之外,代码还有多处影响功能的问题:

  • 提交按钮的onSubmit方法逻辑写反,且未实际调用Vuex的mutation提交数据。
  • 多配料输入框绑定同一个v-model变量,导致所有输入框内容同步,无法单独录入不同配料。
  • values_final变量未正确赋值,无法传递有效数据到Vuex。

修正后的完整代码

1. Main.vue 修正版

<template>
  <div>
    <div class="home_page_header">
      <h1>My Recipe</h1>
      <button @click="toggleOpen">Add New Recipe</button>
    </div>

    <!-- 渲染食谱列表 -->
    <div v-for="recipe in $store.state.recipes" :key="recipe.Recipe_Name">
      <h1>{{ recipe.Recipe_Name }}</h1>
      <p>{{ recipe.Ingredients.join(', ') }}</p>
      <router-link :to="`/recipe/${recipe.Recipe_Name}`">
        <button>View Recipe</button>
      </router-link>
    </div>

    <!-- 添加食谱弹窗 -->
    <div class="popUp" v-show="openUp">
      <div>
        <label for="receipe_name">Recipe Name</label>
        <input type="text" id="receipe_name" v-model="values.recipeName" />
      </div>
      <div>
        <label>Ingredients</label>
        <!-- 改为数组存储配料,每个输入框绑定数组对应项 -->
        <input
          type="text"
          v-for="(ingredient, index) in values.ingredients"
          :key="index"
          v-model="values.ingredients[index]"
          placeholder="输入配料"
        />
        <button @click="addIngredientRow">Add Ingredients</button>
      </div>
      <div><button @click="onSubmit">Submit</button></div>
      <div><button @click="toggleClose">Close</button></div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      values: {
        recipeName: '',
        ingredients: [''] // 用数组存储多个配料
      },
      openUp: false
    }
  },
  methods: {
    toggleOpen() {
      this.openUp = true
    },
    toggleClose() {
      this.openUp = false
      // 关闭弹窗时重置表单
      this.values = {
        recipeName: '',
        ingredients: ['']
      }
    },
    onSubmit() {
      // 修正判断逻辑:检查名称和配料是否为空
      if (!this.values.recipeName || this.values.ingredients.some(item => !item.trim())) {
        alert('请填写完整信息')
        return
      }
      // 提交到Vuex
      this.$store.commit('Add_Recipes', {
        Recipe_Name: this.values.recipeName,
        Ingredients: this.values.ingredients.map(item => item.trim())
      })
      // 提交后关闭弹窗
      this.toggleClose()
    },
    addIngredientRow() {
      this.values.ingredients.push('')
    }
  }
}
</script>

2. store/index.js 补充完整

import { createStore } from 'vuex'

export default createStore({
  state: {
    recipes: [
      {
        Recipe_Name: 'curd',
        Ingredients: ['xxxxxx']
      }
    ]
  },
  mutations: {
    Add_Recipes(state, recipe) {
      state.recipes.push(recipe)
    }
  },
  // 补充Vuex必要结构
  actions: {},
  modules: {}
})

关键修改说明

  1. 修复computed错误:删除原代码中错误的computed字段,提交逻辑移至onSubmit方法中执行。
  2. 配料输入逻辑优化:将单个变量改为数组存储配料,每个输入框绑定数组对应项,实现独立录入。
  3. 提交逻辑修正:
    • 修正表单验证条件,确保名称和所有配料都不为空。
    • 提交时正确组装数据并调用this.$store.commit,将数据传入Vuex的mutation。
  4. 弹窗重置:关闭弹窗时重置表单内容,避免残留之前的输入。
  5. Vuex结构完善:补充actions和modules字段,保持store结构完整。

内容的提问来源于stack exchange,提问作者saravana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 08:11:38