vue vuex 购物车案例

新建vue项目

 此项目需要用到json-server,模拟后台服务器接口功能,

npm i json-server -g

安装此包,然后再vue项目的全局根目录中新建db文件夹,其中新建index.json文件。

{
  "cart": [
    {
      "id": 1001,
      "name": "低帮城市休闲户外鞋天然牛皮COOLMAX纤维",
      "price": 128,
      "count": 3,
      "thumb": "https://yanxuan-item.nosdn.127.net/3a56a913e687dc2279473e325ea770a9.jpg"
    },
    {
      "id": 1002,
      "name": "网易未央黑猪猪肘330g*1袋",
      "price": 39,
      "count": 3,
      "thumb": "https://yanxuan-item.nosdn.127.net/3a56a913e687dc2279473e325ea770a9.jpg"
    },
    {
      "id": 1003,
      "name": "KENROLL男女简洁多彩一片室外拖",
      "price": 88,
      "count": 3,
      "thumb": "https://yanxuan-item.nosdn.127.net/3a56a913e687dc2279473e325ea770a9.jpg"
    },
    {
      "id": 1004,
      "name": "低帮城市休闲户外鞋天然牛皮COOLMAX纤维",
      "price": 99,
      "count": 6,
      "thumb": "https://yanxuan-item.nosdn.127.net/3a56a913e687dc2279473e325ea770a9.jpg"
    }
  ],
  "friends": [
    {
      "id": 1,
      "name": "hang",
      "age": 18
    },
    {
      "id": 2,
      "name": "wang",
      "age": 29
    }
  ]
}

模拟数据库,在db文件夹下,调用系统cmd命令,启动模拟服务器

json-server --watch index.json

 

 main.js

import Vue from 'vue'
import App from './App.vue'
import store from "@/store";

Vue.config.productionTip = false;

new Vue({
  render: h => h(App),
  store
}).$mount('#app');

app.vue

<template>
  <div id="app">
    <!-- Header 区域   -->
    <cart-header></cart-header>

    <!-- Item 区域   -->
    <cart-item v-for="item in list" :key="item.id" :item="item"></cart-item>

    <!-- Footer 区域   -->
    <cart-footer></cart-footer>
  </div>
</template>

<script>
import CartHeader from "@/components/CartHeader";
import CartItem from "@/components/CartItem";
import CartFooter from "@/components/CartFooter";
import { mapState } from 'vuex'

export default {
  name: 'App',
  components: {
    CartHeader,
    CartItem,
    CartFooter
  },
  computed:{
    ...mapState('cart',['list'])
  },
  created() {
    this.$store.dispatch('cart/getList');
  }
}
</script>

<style>
  *{
    padding: 0;
    margin: 0;
  }
</style>

index.js

import Vue from 'vue'
import Vuex from 'vuex'
import cart from "@/store/modules/cart";

Vue.use(Vuex);

const store = new Vuex.Store({
    modules:{
        cart
    }
});

export default store;

cart.js

import axios from "axios";
export default {
    //开启命名空间
    namespaced:true,
    state(){
        return {
            list:[]
        }
    },
    getters:{
        //总数
        total(state){
            return state.list.reduce( (sum,item) => sum += item.count,0);
        },
        //总金额
        totalPrice(state){
            return state.list.reduce( (sum,item) => sum + item.count * item.price ,0);
        }
    },
    mutations:{
        updateList(state,newList){
            state.list = newList;
        },
        //
        updateCount(state,obj){
            //根据id找到对应的对象,更新count属性
            const goods = state.list.find( item => item.id === obj.id);
            goods.count = obj.newCount;
        }
    },
    actions:{
        //请求方式 get
        //请求地址:http://localhost:3000/cart
        async getList(context){
            const res = await axios.get('http://localhost:3000/cart');
            //console.log(res);
            context.commit('updateList',res.data);
        },
        //请求方式 patch
        //请求地址:http://localhost:3000/cart/:id值
        //请求参数 { name:'新值', [可选]}
        //
        async updateCountAsync(context,obj){
            //将修改更新同步到后台服务器
            const res = await axios.patch(`http://localhost:3000/cart/${obj.id}`,{
                count: obj.newCount
            });
            console.log(res);
            //调用mutation
            context.commit('updateCount',{
                id: obj.id,
                newCount: obj.newCount
            });
        }
    }
}

CartHeader.vue

<template>
    <div class="cart-header">
        <div class="title">购物车案例</div>
    </div>
</template>

<script>
    export default {
        name: "CartHeader"
    }
</script>

<style scoped>
    .cart-header{
        width: 100%;
        height: 70px;
        background-color: mediumseagreen;
        margin-bottom: 10px;
    }

    .cart-header .title{
        color: white;
        font-size: 34px;
        width: 200px;
        height: 100%;
        line-height: 70px;
        text-align: center;
        margin: 0 auto;
    }
</style>

CartItem.vue

<template>
    <div class="cart-item">
        <!-- 左侧图片区域       -->
        <div class="left">
            <img :src="item.thumb" alt="" class="avatar">
        </div>
        <!-- 右侧商品区域       -->
        <div class="right">
            <!-- 标题           -->
            <div class="title">{{ item.name }}</div>
            <div class="info">
                <span class="price">¥{{ item.price }}</span>
                <div class="btns">
                    <!-- 按钮区域                   -->
                    <button class="btn btn-light" @click="btnClick(-1)">-</button>
                    <span class="count">{{ item.count }}</span>
                    <button class="btn btn-light" @click="btnClick(+1)">+</button>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        name: "CartItem",
        props:{
            item: {
                type: Object,
                required:true
            }
        },
        methods:{
            btnClick(step){
                const newCount = this.item.count + step;
                const id = this.item.id;
                //console.log(id,newCount);
                if(newCount < 1) return;
                this.$store.dispatch('cart/updateCountAsync',{
                    id,
                    newCount,
                });
            }
        }
    }
</script>

<style scoped>


    .cart-item{
        width: 98%;
        height: 200px;
        margin-left: 2%;
    }

    .cart-item .left{
        width: 180px;
        height: 180px;
        float: left;
    }

    .left img{
        width: 100%;
        height: 100%;
    }

    .cart-item .right{
        width: 30%;
        height: 100%;
        float: left;
    }

    .right .title{
        text-indent: 40px;
        font-size: 24px;
        height: 75%;
        font-family: Arial,"Arial Black",Georgia;
    }

    .right .info{
        width: 100%;
        height: 25%;
        line-height: 30px;

    }

    .right .price{
        padding: 3px;
        margin-left: 40px;
        color: orange;
        font-size: 24px;
    }

    .right .btns{
        float: right;
    }

    .btns .btn{
        width: 30px;
        height: 33px;
        line-height: 30px;
        font-size: 20px;
        margin: 0 15px;
    }

    .btns .count{
        display: inline-block;
        width: 25px;
        text-align: center;
        font-size: 20px;
        font-weight: bold;
    }

    .btns .btn-light{
        background-color: #cccccc;
    }
</style>

CartFooter.vue

<template>
    <div class="cart-footer">
        <!--  中间合计      -->
        <div>
            <span>共 {{ total }} 件商品,合计:</span>
            <span class="price">¥ {{ totalPrice }}</span>
        </div>
        <!--  右侧结算按钮      -->
        <button class="btn">结算</button>
    </div>
</template>

<script>
    import { mapGetters} from 'vuex'
    export default {
        name: "CartFooter",
        computed:{
            ...mapGetters('cart',['total','totalPrice'])
        }
    }
</script>

<style scoped>
    .cart-footer{
        width: 30%;
        height: 50px;
        font-size: 20px;
        float: right;
    }

    .cart-footer div{
        display: inline;
        width: 400px;
        margin-left: 8%;
    }
    .cart-footer .price{
        font-size: 30px;
        font-weight: bold;
        color: red;
    }

    .cart-footer .btn{
        width: 150px;
        height: 50px;
        background-color: mediumseagreen;
        border-radius: 30px;
        float: right;
        margin-right: 40px;
    }
</style>

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
抱歉,我是一个AI语言模型,无法提供代码示例。但是,我可以简要介绍如何使用Vue3和Vuex实现购物车功能。 首先,需要在Vue3项目中安装Vuex。可以使用以下命令: ```bash npm install vuex ``` 然后,在src目录下创建一个store.js文件来存储Vuex store实例。在store.js文件中,需要导入Vue3和Vuex,并创建一个新的store实例。 ```javascript import { createStore } from 'vuex' const store = createStore({ state: { cart: [] }, mutations: { addToCart(state, item) { state.cart.push(item) }, removeFromCart(state, index) { state.cart.splice(index, 1) } }, getters: { cartTotal(state) { return state.cart.reduce((total, item) => total + item.price, 0) } } }) export default store ``` 在上面的代码中,我们定义了一个状态对象state,其中包含一个名为cart的数组。我们还定义了两个mutation,一个用于将商品添加到购物车中,另一个用于从购物车中删除商品。最后,我们定义了一个getter,用于计算购物车中商品的总价值。 在Vue3项目中,可以通过以下方式将store实例传递给根组件: ```javascript import { createApp } from 'vue' import App from './App.vue' import store from './store' createApp(App).use(store).mount('#app') ``` 现在,我们已经将store实例传递给了根组件,可以在组件中使用Vuex的状态管理功能。例如,在组件中添加商品到购物车中的代码可以如下所示: ```javascript <button @click="addToCart(item)">Add to Cart</button> ... methods: { addToCart(item) { this.$store.commit('addToCart', item) } } ``` 在上面的代码中,我们将addToCart方法映射到一个按钮的点击事件上。当用户点击按钮时,我们将商品对象作为参数传递给addToCart方法,并使用commit方法将该操作提交给store。Vuex会在store中执行addToCart mutation,并将商品对象添加到cart数组中。 同样,我们可以使用Vuex的getter来计算购物车中商品的总价值: ```javascript <template> <div> <p>Cart Total: {{ cartTotal }}</p> </div> </template> <script> export default { computed: { cartTotal() { return this.$store.getters.cartTotal } } } </script> ``` 在上面的代码中,我们使用computed属性将cartTotal getter映射到组件的模板中。当cart数组中的商品数量发生变化时,cartTotal getter会重新计算购物车中商品的总价值,并将其更新到模板中。 以上是使用Vue3和Vuex实现购物车功能的基本流程,具体实现方式可能因项目而异。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

虾米大王

有你的支持,我会更有动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值