先创建一个cart组件
<template> <div> <ListItem></ListItem> </div> </template> <script> import ListItem from "./ListItem"; export default { components: { ListItem }, data() { return {} }, // 在父组件中获取购物车数据 mounted() { let url = 'http://localhost:8080/data/cart.json' this.$axios.get(url).then(ret => { // 给vuex发送一个异步请求,更新数据 vuex actions this.$store.dispatch('cartData', ret.data) }) } } </script>
在store文件夹index里面写上
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
// 数据源
state: {
cartData: [],
// 购物车总价格
cartTotalPrice: 0,
},
// 相当于组件中的计算属性
getters: {
// 这里是小计
cartData(state) {
return state.cartData.map(item => {
item.['total'] = item.price * item.num
return item
})
},
// 计算总价格
cartTotalPrice(state){
/* 开始可以这样写就是计算数量和价格 得出总价格
let total = 0
state.cartData.forEach(item => {
total += item.price * item.num
})
return total
*/
// prev 初始值 => 值取参2的值,当循环第2次时就是return和上一次返回值
// next 当前循环的对象
// 用于聚合运算 提高map reduce
return state.cartData.reduce((prev,next) => {
return prev + next.price * next.num
},0)
}
},
mutations:{
// 修改数据源
setCartData(state,data){
state.cartData = data
},
// 给数量加一
incr(state,index){
state.cratData[index].num++
},
// 给数量减一
decr(state,index){
state.cratData[index].num--
}
},
actions:{
cartData({commit},data){
// 让mutations更新state数据
commit('setCartData',data)
},
incr({commit},index){
commit('incr',index)
},
decr({commit},index){
commit('decr',index)
}
},
modules:{}
})
再创建ListItem组件 这个就是点击增加和删除功能的组件
<template> <div> <ul> <!-- 直接使用计算属性里面的cartData数据 --> <li v-for="(item, index) in cartData" :key="item.id"> <span>{{ item.name }}</span> <span>{{ item.price }}</span> <span> <button @click="incr(index)">+++</button> <input type="text" v-model="item.num" /> <button @click="decr(index, item.num)">---</button> </span> <span>小计:{{ item.total }}</span> </li> </ul> <Total></Total> </div> </template> <script> import { mapGetters } from 'vuex' import Total from './Total' export default { components: { Total }, // 子组件中得到父组件中吧数据写入到vuex中的state数据 从而实现了组件间的通信(传值) computed: { ...mapGetters(['cartData']) }, methods: { // index当前数据对象的索引号 incr(index) { this.$store.dispatch('incr', index) }, decr(index, num) { if (num > 1) { this.$store.dispatch('decr', index) } } } } </script> <style></style>
再创建Total组件就是总计的组件
<template> <div> 总计:{{ cartTotalPrice }} </div> </template> <script> import {mapGetters} from 'vuex' export default { computed:{ ...mapGetters(['cartTotalPrice']) } } </script> <style scoped> </style>
这样每个的小计和全部加起来的价格都被vuex管理起来了