赞助

先创建一个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管理起来了

posted on 2021-01-13 15:32  Tsunami黄嵩粟  阅读(149)  评论(0编辑  收藏  举报