48 - 案例 - 购物车

目标: 功能分析,创建项目,构建分析基本结构

一. 功能模块分析

        (1). 请求动态渲染购物车,数据存 vuex      
        (2). 数字框控件 修改数据      
        (3). 动态计算 总价和总数量

二. 脚手架新建项目     

        (1). 创建项目指令
# 黑窗口执行,在那个文件下,项目就会建在那(新建项目)
vue create vue-cart-demo(项目名)
        (2). 创建项目流程 

 

三.综合案例-购物车

目标:构建cart 购物车模块
说明:既然明确数据要存 vuex,建议分模块存,购物车数据存 cart 模块,将来还会有 user 模块,article 模块...

        1. 创建子组件
                (1). cart-header.vue
<template>
    <div>header</div>
</template>
                (2). cart-item.vue
<template>
    <div class="goods-container">
        <!-- 左侧图片区域 -->
        <div class="left">
            <img src="" class="avatar">
        </div>
        <!-- 右侧商品区域 -->
        <div class="right">
            <!-- 标题 -->
            <div class="title">标题</div>
            <div class="info">
                <!-- 单价 -->
                <span class="price">$10</span>
                <div class="btns">
                    <!-- 按钮区域 -->
                    <button class="btn btn-light">-</button>
                    <span class="count">1</span>
                    <button class="btn btn-light">+</button>
                </div>
            </div>

        </div>

    </div>
</template>
<script>
export default {
  name: 'CartItem',
}
</script>
<style lang="less" scoped>
.goods-container{
    display: flex;
    padding: 10px;
    + .goods-container{
        border-top: 1px solid #f8f8f8;
    }
    .left{
        .avatar{
            width: 100px;
            height: 100px;
        }
        margin-right: 10px ;
    }
    .right{
        margin-left: 15px;
        .title{
            margin-top: 10px;
            font-size: 15px;
        }
        .info{
            margin-top: 50px;
            .price{
                float: left;
            }
            .btns{
                float: right;
                margin-left: 30px;
                .count{
                    margin-left: 5px;
                    margin-right: 5px;

                }

            }

        }
    }
}
</style>
                (3). cart-footer.vue
<template>
    <div class="footer-container">
        <!-- 中间的合计 -->
        <div>
            <span>共  件商品,合计:</span>
            <span class="price">¥ </span>
        </div>
        <!-- 右侧结算按钮 -->
        <button class="btn btn-success btn-settle">结算</button>
    </div>
</template>
<script>
export default {
  name: 'CartFooter'
}
</script>

<style lang="less" scoped>
.footer-container{
    background-color: white;
    height: 50px;
    border-top: 1px solid #f8f8f8;
    display: flex;
    .btn{
        height: 20px;
        margin-left: 20%;
        background-color:blue;
    }
}
</style>
       
         2. App.vue引入子组件
<template>
<div class="app-container">
<!-- Header区域 -->
<cart-header></cart-header>

<!-- 商品 Item 项组件 -->
<cart-item></cart-item>
<cart-item></cart-item>
<cart-item></cart-item>

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

<script>
import CartHeader from '@/components/cart-header.vue'
import CartFooter from '@/components/cart-footer.vue'
import CartItem from '@/components/cart-item.vue'

export default {
  name: 'App',

  components: {
    CartHeader,
    CartFooter,
    CartItem
  }
}
</script>
<style lang="less" scoped>
.app-container{
  padding: 50px 0;
  font-size:14px
}
</style>
        3. 构建购物车模块状态

        4. 准备后端接口服务环境

                目标:基于json-server 工具,准备后端接口服务环境

                (1).安装 json-server                 
// 安装全局工具json-server (全局工具仅需要安装一次)   

npm i json-server -g
                (2).根目录新建 db 目录
// 项目根目录新建一个 db 目录,新建index.json存放数据

{
    "cart":[
        {
            "id":100001,
            "name":"牛皮纤维纸",
            "price":128,
            "count":1,
            "thumb":"https://img2.baidu.com/it/u=2936117222,3860513461&fm=253&app=120&size=w931&n=0&f=JPEG&fmt=auto?sec=1695574800&t=047a0ddf535ee76b5e43f5d31636a61e"
        },
        {
            "id":100002,
            "name":"牛皮纤维纸",
            "price":128,
            "count":1,
            "thumb":"https://img2.baidu.com/it/u=2936117222,3860513461&fm=253&app=120&size=w931&n=0&f=JPEG&fmt=auto?sec=1695574800&t=047a0ddf535ee76b5e43f5d31636a61e"
        },
        {
            "id":100003,
            "name":"牛皮纤维纸",
            "price":128,
            "count":1,
            "thumb":"https://img2.baidu.com/it/u=2936117222,3860513461&fm=253&app=120&size=w931&n=0&f=JPEG&fmt=auto?sec=1695574800&t=047a0ddf535ee76b5e43f5d31636a61e"
        },
        {
            "id":100004,
            "name":"牛皮纤维纸",
            "price":128,
            "count":1,
            "thumb":"https://img2.baidu.com/it/u=2936117222,3860513461&fm=253&app=120&size=w931&n=0&f=JPEG&fmt=auto?sec=1695574800&t=047a0ddf535ee76b5e43f5d31636a61e"
        },
        {
            "id":100005,
            "name":"牛皮纤维纸",
            "price":128,
            "count":1,
            "thumb":"https://img2.baidu.com/it/u=2936117222,3860513461&fm=253&app=120&size=w931&n=0&f=JPEG&fmt=auto?sec=1695574800&t=047a0ddf535ee76b5e43f5d31636a61e"
        }
    ],
    "friends":[
        {"id":1,"name":"zhangsan","age":18},
        {"id":2,"name":"lisi","age":19},
        {"id":3,"name":"wangwu","age":20}
    ]
}

                (3).启动后端接口服务
// 进入db 目录,执行命令,启动后端接口服务
json-server index.json
       
                (4).访问接口测试
http://localhost:3000/cart

       
 5. vuex请求数据,映射渲染

                目标:请求获取数据存入vuex映射渲染

            (1). 安装axios
npm i axios

// 如果报错就执行以下代码安装axios
// npm i axios --legacy-peer-deps
           (2).  cart.js 请求接口
// cart.js 请求获取数据存入vuex映射渲染
state: { list: [] },
mutations:{
    updateList (state, payload) {
        state.list = payload
       }
},    
actions: {
    async getList (ctx) {
        const res = await axios.get("http://localhost:3000/cart')
        ctx.commit("updateList",res.data)
    }
}
        (3). 页面调用 action
$store.dispatch('模块名/xxx')
        (4). 代码示例

6. 修改数量功能

目标: 修改数量功能完成
注意: 前端vuex数据,后端数据库数据都要更新

mutations: {
    updateCount (state, payload) {
      const goods = state.list.find(item => item.id === payload.id)
      goods.count = payload.count
    }
  },
  actions: {
    async UpdateCountAsync (ctx,payload) {
      await axios.patch('http://localhost:3000/cart' + payload.id, {
        count: payload.count
      })
      context.commit('updateCount', payload)
    }
  },
        (1). 代码示例

7. 底部 getter 统计

目标:底部 getters 统计

        (1). 提供 getters
getter:{
    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)
    }
}
        (2). 使用getters
 computed: {
    ...mapGetters('cart', ['total', 'totalPrice'])
  }
        (3). 代码示例

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值