Back-end data emulation
Create vue.config.js in the root directory, write the interface and data, install CNPM I axios-s, and restart the server
module.exports = {
devServer: {
before(app, serve) {
app.get('/api/products', (req, res) => {
res.json({
results: products
})
})
}
}
}
const products = [
{ id: 1.title: 'iphone11'.price: 800.inventory: 10 },
{ id: 2.title: 'iphone11 pro'.price: 1200.inventory: 15 },
{ id: 3.title: 'iphone11 pro max'.price: 1400.inventory: 7}]Copy the code
Get data & Render data list
Vuex product module products.js introduces AXIos and asynchronously sends requests for data
import Axiso from 'axios'
export default {
namespaced: true.state: {
products: []},mutations: {
getAllProducts(state, results) {
state.products = results; //3. Assign the obtained data to products in the current state}},actions: {
async getAllProducts({ commit }) { //2. Send an asynchronous request for data submission
try {
const res = await Axiso.get('/api/products'); // Request data from the interface
const results = res.data.results; // Assign the extracted data to the new attribute
commit('getAllProducts', results) //commit calls mutation and passes the data obtained
} catch (error) {
console.log(error); }}}}Copy the code
Obtained data:
Data: {... },status: 200.statusText: "OK".headers: {... },config: {... },... }Copy the code
Products.vue component:
<template>
<div>
<h2>goods</h2>
<ul><! -- 5. Render product list -->
<li v-for="product in products" :key="product.id">
<h3>{{product.title}} - {{product.price}}</h3>
</li>
</ul>
</div>
</template>
<script>
import { mapState } from "vuex";
export default {
computed: {
...mapState("products"["products"]) //4. The auxiliary function gets the status of the products module in store
},
created() {
this.$store.dispatch("products/getAllProducts");//1. After the component is created, call the Action of the product component in the store to get the server data}};</script>
Copy the code
Fliter decorates the data
Register global filters in main.js:
Vue.filter('currency', (value) => {
return '$' + value;
})
Copy the code
Intra-component references:
<ul>
<li v-for="product in products" :key="product.id">
<h3>{{product.title}} - {{product.price | currency}}</h3>
</li>
</ul>
Copy the code
Registering global components
Register global components in main.js:
import CartList from '@/components/CartList.vue' // Import components
Vue.component(CartList.name, CartList) // Register the global component
Copy the code
export default {
name: "CartList" // Component name used when registering global components
};
Copy the code
Add data to the shopping cart module
Get the method in the VUEX shopping cart module in the product component and add the event button to trigger and pass the value
<template>
<div>
<h2>product</h2>
<ul>
<li v-for="product in products" :key="product.id">
<h3>{{product.title}} - {{product.price | currency}} - {{product.inventory}}</h3>
<! Add the click event to trigger the action and pass the value of the currently clicked data object to the store(this will include any not referenced in the list rendering) -->
<button @click="addProductToCart(product)">Add to shopping cart</button>
</li>
</ul>
</div>
</template>
<script>
import { mapState, mapActions } from "vuex";
export default {
computed: {
...mapState("products"["products"])
},
created() {
this.$store.dispatch("products/getAllProducts");
},
methods: {
//1. Get the methods in the vuex shopping cart module. mapActions("cartList"["addProductToCart"])}};</script>
Copy the code
The shopping cart module receives trigger events and incoming data, makes judgments and stores and modifies the shopping cart data
export default {
namespaced: true.state: {
cartList: [] //3. Declare the cart status
},
getters: {
evenOrOdd2(state) {
return state.count % 2= = =0 ? 'even number' : 'odd'}},mutations: {
//7. Add the product name to the cart
pushProductToCart(state, { id, quantity }) {
state.cartList.push({
id,
quantity
})
},
//7. Product quantity plus one
addProductQuantity(state, { id }) {
// Obtain the cartList corresponding ID data according to the id of the data passed in
const product = state.cartList.find(item= > item.id === id);
// Add one to this numberproduct.quantity++; }},actions: {
addProductToCart({ commit, state }, product) { //4. Call the add cart method to pass in state and receive product
if (product.inventory > 0) { // Check whether the inventory is greater than 0 from the inventory of product
// get the data in the cartList, determine whether the corresponding id of the item is the same as the data passed in and assign a variable
const cartItem = state.cartList.find(item= > item.id === product.id);
console.log(cartItem);
if(! cartItem) {CartItem = faulse; //6.cartList = null; cartItem = faulse
// Cart has no data to add data to cartList
commit('pushProductToCart', { id: product.id, quantity: 1})}else {
// Pass the product ID to the product add method
commit('addProductQuantity', { id: product.id })
}
}
}
}
}
Copy the code
Render shopping cart list
Getter methods in the Vuex shopping cart module generate data
state: {
cartList: []},getters: {
// Get the cart data from the product module and compare it with the cart data from the current cart module by the third parameter in the getter
getCartList(state, getters, rootState) {
// Traverse the cartList data into an ordered list via map and deconstruct the ID and quantity,
// Returns a new array generated by map. Map does not detect empty arrays
return state.cartList.map(({ id, quantity }) = > {
/* The first products is the module name, the second is the status name, get an array of all product data of the product module, judge by the function in the find method,map each traverse of cartList compares all product data one by one, obtain the same ID object to assign value to product */
const product = rootState.products.products.find(item= > item.id === id);
return { // Each product ID of the cartList corresponds to the product object,
// Get the number of title and price and cartlist. id of the product data, which is returned to map to store in a new array
title: product.title, //title is the title of the product
price: product.price, //price is the title of product
quantity // Quantity is the number of corresponding ids in the current shopping cart module}}}})Copy the code
The shopping cart component gets the shopping cart data generated by the getter
<template>
<div>
<h2>The shopping cart</h2>
<ul><! Render the getter data as a list -->
<li v-for="(item,index) in getCartList" :key="index">
<h3>{{item. The title}} - {{item. The price | currency}} ({{item. Quantity}}</h3>
</li>
</ul>
</div>
</template>
<script>
import { mapGetters } from "vuex";
export default {
name: "CartList".computed: {
// Get the cart data generated by the getter method of the Vuex shopping cart module. mapGetters("cartList"["getCartList"])}};</script>
Copy the code
Gross price calculation
Vuex shopping cart module:
getters: {
getCartList(state, getters, rootState) {
return state.cartList.map(({ id, quantity }) = > {
const product = rootState.products.products.find(item= > item.id === id);
return {
title: product.title,
price: product.price,
quantity
}
})
},
//1. Add the cart total price method and pass the second parameter getters to get another getter
cartTotalPrice(state, getters) {
//2. Get the array returned by getCartList above, use reduce() to calculate and pass in the array product generated by getCartList
return getters.getCartList.reduce((total, product) = > {
//3. Total acts as an accumulator and accumulates the total price of a single product by multiplying the price and quantity of product starting from 0. Reduce () returns the total price of all products
return total + product.price * product.quantity
}, 0); }},Copy the code
The reduce() method takes a function as an accumulator, and each value in the array (from left to right) starts to shrink and eventually adds up to a single value, because the shopping cart is empty when it doesn’t have any data, and the reduce() method gives an error when the object is empty, passes in the default value, and evaluates from zero
<template>
<div>
<h2>The shopping cart</h2>
<ul>
<li v-for="(item,index) in getCartList" :key="index">
<h3>{{item. The title}} - {{item. The price | currency}} ({{item. Quantity}}</h3>
</li>
</ul>
<! -- 5. Reference methods and add global filters -->
<h3>Total price: {{cartTotalPrice | currency}}</h3>
</div>
</template>
<script>
import { mapGetters } from "vuex";
export default {
name: "CartList".computed: {
//4. Add the method of vuex shopping cart module total price calculation into the auxiliary function. mapGetters("cartList"["getCartList"."cartTotalPrice"])}};</script>
Copy the code
Inventory reduction
Under the Add product to cart method in the shopping cart module, submit a call to the method in the product module
actions: {
addProductToCart({ commit, state }, product) {
if (product.inventory > 0) {
const cartItem = state.cartList.find(item= > item.id === product.id);
if(! cartItem) { commit('pushProductToCart', { id: product.id, quantity: 1})}else {
commit('addProductQuantity', { id: product.id })
}
// Every time you click add to cart, the method in the Products module is triggered and the id of the current product is passed
// If you want to submit methods in one module in another, you need a third argument {root:true} to return to the root
commit('products/decrementProductsInventory', { id: product.id }, { root: true})}}}Copy the code
Mutations of the product module:
mutations: {
// Method passes in product data and deconstructs the id of the passed product
decrementProductsInventory(state, { id }) {
// Compare the data in the module with the incoming id to obtain the corresponding product data
const product = state.products.find(item= > item.id === id);
// The inventory of each triggered product is reduced by oneproduct.inventory--; }}Copy the code
The button cannot be clicked when the inventory is 0
Determine whether the inventory of the current product is 0 by binding the Button’s Disabled event. If 0 is faulse, set it to true and let disabled take effect
<button :disabled=! "" product.inventory" @click="addProductToCart(product)">Add to shopping cart</button>
Copy the code