UNIAPP实战项目笔记38 购物车的添加商品到购物车功能

UNIAPP实战项目笔记38 购物车的加入购物车功能

通过mapGetters实现此功能

在 shopcart.vue中
使用mapGetters中的 addShopCart方法实现商品数量的增加

核心代码 detail.vue

    <template>
        <view class="details">
            <!-- 商品图 -->
            <swiper :indicator-dots="true" :autoplay="true" :interval="3000" :duration="1000">
                <swiper-item>
                    <view class="swiper-item">
                        <image class="swiper-img" :src="goodsContent.imgUrl" mode=""></image>
                    </view>
                </swiper-item>
            </swiper>
            <!-- 价格和名称 -->
            <view class="details-goods">
                <view class="goods-pprice">¥{{goodsContent.pprice}} </view>
                <view class="goods-oprice">¥{{goodsContent.oprice}} </view>
                <view class="goods-name">{{goodsContent.name}} </view>
            </view>
            <!-- 商品详情图 -->
            <view class="">
                <view class=""><image class="details-img" src="../../static/img/b3.jpg" mode=""></image></view>
                <view class=""><image class="details-img" src="../../static/img/b3.jpg" mode=""></image></view>
                <view class=""><image class="details-img" src="../../static/img/b3.jpg" mode=""></image></view>
                <view class=""><image class="details-img" src="../../static/img/b3.jpg" mode=""></image></view>
                <view class=""><image class="details-img" src="../../static/img/b3.jpg" mode=""></image></view>
                <view class=""><image class="details-img" src="../../static/img/b3.jpg" mode=""></image></view>
            </view>
            
            <!-- 商品列表 -->
            <Card cardTitle="看了又看"></Card>
            <CommodityList :dataList="dataList"></CommodityList>
            
            <!-- 底部 -->
            <view class="details-foot">
                <view class="iconfont icon-xiaoxi"></view>
                <view class="iconfont icon-31gouwuche" @tap="goShopCart"></view>
                <view class="add-shopcart" @tap="showPop">加入购物车</view>
                <view class="purchase" @tap="showPop">立刻购买</view>
            </view>
            
            <!-- 底部弹出层 -->
            <view class="pop" v-show="isShow" @touchmove.stop="">
                <!-- 蒙层 -->
                <view class="pop-mask" @tap="hidePop"> </view>
                <!-- 内容块 -->
                <view class="pop-box" :animation="animationData">
                    <view class="">
                        <image class="pop-img" :src="goodsContent.imgUrl" mode=""></image>
                    </view>
                    <view class="pop-num">
                        <view class="">购买数量</view>
                        <UniNumberBox
                            :min=1 
                            :value="num"
                            @change="changeNumber"
                        ></UniNumberBox>
                    </view>
                    <view class="pop-sub" @tap="addCart">确定</view>
                </view>
            </view>
        </view>
    </template>

    <script>
        import $http from '@/common/api/request.js'
        import Card from '@/components/common/Card.vue';
        import CommodityList from '@/components/common/CommodityList.vue';
        import UniNumberBox from '@/components/uni/uni-number-box/uni-number-box.vue';
        import {mapMutations} from 'vuex'
        export default {
            data() {
                return {
                    isShow:false,
                    goodsContent:{},
                    animationData:{},
                    num:1,
                    swiperList:[
                        {imgUrl:"../../static/img/b3.jpg"},
                        {imgUrl:"../../static/img/b3.jpg"},
                        {imgUrl:"../../static/img/b3.jpg"}
                    ],
                    dataList:[{
                          id:1,
                          imgUrl:"../../static/logo.png",
                          name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
                          pprice:"299",
                          oprice:"659",
                          discount:"5.2"
                      },
                      {
                          id:2,
                          imgUrl:"../../static/logo.png",
                          name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
                          pprice:"299",
                          oprice:"659",
                          discount:"5.2"
                      },{
                          id:3,
                          imgUrl:"../../static/logo.png",
                          name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
                          pprice:"299",
                          oprice:"659",
                          discount:"5.2"
                      }]
                };
            },
            components:{
                Card,
                CommodityList,
                UniNumberBox
            },
            onLoad(e) {
                // console.log(e.id);
                // 设置默认id=1
                if(!e.id)
                    e.id = 1;
                this.getData(e.id);
            },
            // 修改返回默认行为
            onBackPress(){
                if (this.isShow) {
                    this.hidePop();
                    return true;  
                }
                
            },
            // 点击分享
            onNavigationBarButtonTap(e) {
                if(e.type==='share'){
                    uni.share({
                        provider:"weixin",
                        type:0,
                        scene:"WXSceneSession",
                        title:this.goodsContent.name,
                        href:"http://127.0.0.1:8080/#/pages/details/details?id="+this.goodsContent.id,
                        imageUrl:this.goodsContent.imageUrl,
                        success:function(res){
                            uni.showTabBar({
                                title:"分享成功"
                            })
                        },
                        fail: (err) => {
                            console.log("fail:"+ JSON.stringify(err));
                        }
                    })
                }
            },
            methods:{
                ...mapMutations(['addShopCart']),
                // 改变商品数量
                changeNumber(value){
                    this.num = value;
                },
                // 请求商品
                getData(id){
                    $http.request({
                        url:"/goods/id",
                        data:{
                            id:id
                        }
                    }).then((res)=>{
                        this.goodsContent = res[0];
                    }).catch(()=>{
                        uni.showToast({
                            title:'请求失败',
                            icon:'none'
                        })
                    })
                },
                showPop(){
                    // 初始化一个动画
                    var animation = uni.createAnimation({
                        duration:200 // 动画时间
                    });
                    // 定义动画内容
                    animation.translateY(600).step();
                    // 导出动画数据传递给data层
                    this.animationData = animation.export();
                    this.isShow = true;
                    setTimeout(()=>{
                        animation.translateY(0).step();
                        this.animationData = animation.export();
                    },200)
                },
                hidePop(){
                    var animation = uni.createAnimation({
                        duration:200
                    });
                    animation.translateY(600).step();
                    this.animationData = animation.export();
                    this.isShow = true;
                    setTimeout(()=>{
                        animation.translateY(0).step();
                        this.isShow = false;
                    },200)
                },
                // 跳转到购物车页面
                goShopCart(){
                    uni.switchTab({
                        url:'../shopcart/shopcart'
                    })
                },
                // 加入购物车
                addCart(){
                    let goods = this.goodsContent;
                    this.goodsContent['checked'] = false;
                    this.goodsContent['num'] = this.num;
                    // 加入购物车
                    this.addShopCart(goods);
                    // 隐藏弹出框
                    this.hidePop();
                    // 提示信息
                    uni.showToast({
                        title:"成功加入购物车",
                        icon:"none"
                    })
                },
            }
        }
    </script>

    <style lang="scss">
    swiper{
        width: 100%;
        height: 700rpx;
    }
    .swiper-img{
        width: 100%;
        height: 700rpx;
    }
    .details{
        padding-bottom: 90rpx;
    }
    .details-goods{
        text-align: center;
        font-weight: bold;
        font-size: 36rpx;
        padding: 10rpx 0;
    }
    .details-img{
        width: 100%;
    }
    .details-foot{
        position: fixed;
        left: 0;
        bottom: 0;
        width: 100%;
        height: 90rpx;
        display: flex;
        align-items: center;
        justify-content: center;
        background-color: #FFFFFF;
    }
    .details-foot .iconfont{
        width: 60rpx;
        height: 60rpx;
        border-radius: 100%;
        background-color: #000000;
        color: #FFFFFF;
        text-align: center;
        margin: 0 10rpx;
        line-height: 60rpx;
    }
    .add-shopcart{
        margin: 0 40rpx;
        padding: 6rpx 30rpx;
        background-color: #000000;
        color: #FFFFFF;
        border-radius: 40rpx;
        
    }
    .purchase{
        margin: 0 40rpx;
        padding: 6rpx 30rpx;
        background-color: #49BDFB;
        color: #FFFFFF;
        border-radius: 40rpx;
    }
    .pop{
        position: fixed;
        left: 0;
        top: 0;
        width: 100%;
        height: 100%;
        z-index: 9999;
    }
    .pop-mask{
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        height: 100%;
        background-color: rgba(0, 0, 0, 0.3);
    }
    .pop-box{
        position: absolute;
        left: 0;
        bottom: 0;
        width: 100%;
        background-color: #FFFFFF;
    }
    .pop-img{
        width: 260rpx;
        height: 260rpx;
        top:-130rpx;
        border-radius:20rpx 20rpx 0 0;
        margin: 30rpx;
    }
    .pop-sub{
        line-height: 80rpx;
        background-color: #49BDFB;
        color: #FFFFFF;
        text-align: center;
    }
    .pop-num{
        padding: 20rpx;
        display: flex;
        justify-content: space-between;
    }

    </style>

核心代码 cart.js部分

export default{
    state:{
        list:[
                /* {
                    id:1,
                    name:"332经济法能聚聚会技能大赛 经济法能聚聚会技能大赛",
                    color:"颜色:嘿嘿嘿激活",
                    imgUrl:"../../static/logo.png",
                    pprice:"27",
                    num:1,
                    checked:false
                },{
                    id:2,
                    name:"032经济法能聚聚会技能大赛 经济法能聚聚会技能大赛",
                    color:"颜色:嘿嘿嘿激活",
                    imgUrl:"../../static/logo.png",
                    pprice:"48",
                    num:6,
                    checked:false
                } */
            ],
        selectedList:[]
        
    },
    getters:{
        // 判断是否 全选
        checkedAll(state){
            return state.list.length === state.selectedList.length;
        },
        // 合计 结算数量
        totalCount(state){
            let total = {
                pprice:0,
                num:0
            }
            state.list.forEach(v=>{
                // 是否选中
                if(state.selectedList.indexOf(v.id) > -1){
                    // 合计
                    total.pprice += v.pprice*v.num;
                    // 结算数量
                    total.num = state.selectedList.length;
                }
            })            
            
            return total;
        }
    },
    mutations:{
        // 全选
        checkAll(state){
            state.selectedList = state.list.map(v=>{
                v.checked = true;
                return v.id;
            })
        },
        // 全不选
        unCheckAll(state){
            state.list.forEach(v=>{
                v.checked = false;
            })
            state.selectedList = [];
        },
        // 单选
        selectedItem(state,index){
            let id = state.list[index].id;
            let i = state.selectedList.indexOf(id);
            // 如果selectList已经存在就代表他之前的选中状态,checked=false,并且在selectedList删除
            if (i>-1) {
                state.list[index].checked = false;
                return state.selectedList.splice(i,1);
            }
            // 如果之前没有选中,checked=true,把当前的id添加到selectedList
            state.list[index].checked = true;
            state.selectedList.push(id);
        },
        // 
        delGoods(state){
            state.list = state.list.filter(v=>{
                return state.selectedList.indexOf(v.id) === -1;
            })
        },
        // 加入购物车
        addShopCart(state, goods){
            state.list.push(goods);
        }
    },
    actions:{
        checkedAllFn({commit,getters}){
            getters.checkedAll ? commit("unCheckAll") : commit("checkAll")
        },
        delGoodsFn({commit}){
            commit('delGoods');
            commit("unCheckAll");
            uni.showToast({
                title:'删除成功',
                icon:"none"
            })
        }
    }
}

实际案例图片 购物车的添加商品功能

UNIAPP实战项目笔记38 购物车的添加商品到购物车功能_第1张图片

目录结构

前端目录结构
  • manifest.json 配置文件: appid、logo…

  • pages.json 配置文件: 导航、 tabbar、 路由

  • main.js vue初始化入口文件

  • App.vue 全局配置:样式、全局监视

  • static 静态资源:图片、字体图标

  • page 页面

    • index
      • index.vue
    • list
      • list.vue
    • my
      • my.vue
    • search
      • search.vue
    • search-list
      • search-list.vue
    • shopcart
      • shopcart.vue
    • details
      • details.vue
  • components 组件

    • index
      • Banner.vue
      • Hot.vue
      • Icons.vue
      • indexSwiper.vue
      • Recommend.vue
      • Shop.vue
    • common
      • Card.vue
      • Commondity.vue
      • CommondityList.vue
      • Line.vue
      • ShopList.vue
    • uni
      • uni-number-box
        • uni-number-box.vue
      • uni-icons
        • uni-icons.vue
      • uni-nav-bar
        • uni-nav-bar.vue
  • common 公共文件:全局css文件 || 全局js文件

    • api
      • request.js
    • common.css
    • uni.css
  • store vuex状态机文件

    • modules
      • cart.js
    • index.js

你可能感兴趣的:(uni-app,uni-app,javascript,vue.js)