【问题标题】:Vue.Js / Vuex - how to declare id of elementsVue.Js / Vuex - 如何声明元素的 id
【发布时间】:2020-06-04 06:06:59
【问题描述】:

这是一个简单的购物车 实际上,当我们点击商品时,它会更新购物车中的总数。

但我现在想做一个更好的购物车:显示列表中的每个项目。就像我们选择 2 个羊角面包时一样,它会在购物车中添加 2 个羊角面包。

我的问题是,在本课程中,我并没有真正学习如何根据项目的 ID 进行 Mutation。我正在寻找将我们单击的项目的 ID 发送到商店的语法。

这是我的 3 个文件:(商店的“索引”、“主页”和子“菜单项”)

商店:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    restaurantName: 'Cafe with A Vue',
    shoppingCart: 0,
    croissiantNumber: 0,
    baguetteNumber: 0,
    eclairNumber: 0,
    simpleMenu: [
      {
        id: 1,
        name: 'Crossiant',
        image: {
          source: '/images/crossiant.jp',
          alt: 'A crossiant'
        },
        inStock: true,
        quantity: 1,
        price: 2.99
      },
      {
        id: 2,
        name: 'French Baguette',
        image: {
          source: '/images/french-baguette.jpe',
          alt: 'Four French Baguettes'
        },
        inStock: true,
        quantity: 1,
        price: 3.99
      },
      {
        id: 3,
        name: 'Éclair',
        image: {
          source: '/images/eclair.jp',
          alt: 'Chocolate Éclair'
        },
        inStock: false,
        quantity: 1,
        price: 4.99
      }
    ]
  },
  getters: {
    copyright: state => {
      const currentYear = new Date().getFullYear()

      return `Copyright ${state.restaurantName} ${currentYear}`
    }
  },
  mutations: {
    ADD_ITEMS_TO_SHOPPING_CART(state, amount) {
      state.shoppingCart += amount
    }
  },
  actions: {
    updateShoppingCart({ commit }, amount) {
      commit('ADD_ITEMS_TO_SHOPPING_CART', amount),
      commit('ADD_ITEM_TO_SHOPPING_CART', amount)
    }
  },
  modules: {}
})

首页:

<template>
  <div>
    <h1>{{ restaurantName }}</h1>
    <p class="description">
      Welcome to {{ restaurantName }}! We are known for our freshly baked bread
      and french pastries! Give you morning a warm start or treat yourself in
      the middle of the day. Our butter is imported from local farmers in
      France. Once you take your first bite, you will see why everyone can't get
      enough!
    </p>

    <section class="menu">
      <h2>Menu</h2>
      <MenuItem
        v-for="item in simpleMenu"
        :name="item.name"
        :image="item.image"
        :price="item.price"
        :quantity="item.quantity"
        :inStock="item.inStock"
        :key="item.name"
        :id="item.id"
      />
    </section>

    <div class="shopping-cart">
      <h2>Shopping Cart: {{ shoppingCart }} items</h2>
      <h2>Croissiant: {{ croissiantNumber }} items</h2>
      <h2 v-if="baguetteNumber">French Baguette: {{ baguetteNumber }} items</h2>
      <h2 v-if="eclairNumber">Eclair: {{ eclairNumber }}items</h2>
    </div>

    <footer class="footer">
      <p>{{ copyright }}</p>
    </footer>
  </div>
</template>

<script>
import MenuItem from '../components/MenuItem'
import { mapGetters, mapState } from 'vuex'

export default {
  name: 'Home',
  components: {
    MenuItem
  },
  computed: {
    ...mapGetters({
      copyright: 'copyright'
    }),
    ...mapState({
      restaurantName: 'restaurantName',
      shoppingCart: 'shoppingCart',
      croissiantNumber: 'croissiantNumber',
      baguetteNumber: 'baguetteNumber',
      eclairNumber: 'eclairNumber',
      simpleMenu: 'simpleMenu'
    })
  }
}
</script>

菜单项:

<script>
import { mapActions } from 'vuex'
import BaseButton from './BaseButton.vue'

export default {
  name: 'MenuItem',
  components: {
    BaseButton
  },
  props: {
    image: {
      type: Object,
      required: true
    },
    inStock: {
      type: Boolean,
      required: true
    },
    name: {
      type: String,
      required: true
    },
    price: {
      type: Number,
      required: true
    },
    quantity: {
      type: Number,
      defaut: 1
    }
  },
  data() {
    return {
      onSale: false
    }
  },
  computed: {
    generatedPrice() {
      if (this.onSale) {
        return (this.price * 0.9).toFixed(2)
      } else {
        return this.price
      }
    }
  },
  methods: {
    ...mapActions(['updateShoppingCart'])
  },
  beforeMount() {
    const today = new Date().getDate()

    if (today % 2 === 0) {
      this.onSale = true
    }
  }
}
</script>

<template>
  <div class="menu-item">
    <img class="menu-item__image" :src="image.source" :alt="image.alt" />
    <div>
      <h3>{{ name }}</h3>
      <p>Price: {{ generatedPrice }} <span v-if="onSale">(10% off!)</span></p>
      <p v-if="inStock">In Stock</p>
      <p v-else>Out of Stock</p>
      <div>
        <label for="add-item-quantity">Quantity: {{ quantity }}</label>
        <input v-model.number="quantity" id="add-item-quantity" type="number" />
        <BaseButton @click="updateShoppingCart(quantity, id)" class="test">
          Add to shopping cart
        </BaseButton>
      </div>
    </div>
  </div>
</template>

所以我想更新这个值,例如:

Croissiant: 0 items

Website preview

谢谢。

【问题讨论】:

    标签: javascript vue.js vuex


    【解决方案1】:

    您必须将对象或数组传递给您的操作以处理多个参数。

    @click="updateShoppingCart({quantity, id})"

    然后在商店:

     ...
      actions: {
        updateShoppingCart({ commit }, {quantity, id}) {
          commit('ADD_ITEMS_TO_SHOPPING_CART', amount),
    
          //here you have id that you can map to item type
        }
      },
    

    我建议在 simpleMenu 中使用恒定的项目类型,而不是依赖于 ID。

    【讨论】:

      猜你喜欢
      • 2018-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-22
      • 2018-06-24
      • 2016-05-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多