UNIAPP实战项目笔记69 订单确认时显示为默认地址

UNIAPP实战项目笔记69 订单确认时显示为默认地址

思路

需要用到vuex
默认显示isDefault为1的地址

案例截图

订单结算页面

在这里插入图片描述

地址页面

在这里插入图片描述

代码

shopcart.vue

    <template>
        <view class="shop-cart">
            <template v-if=" list.length > 0 ">
                    
                <!-- 自定义导航栏 -->
                <uniNavBar
                    title="购物车"
                    :rightText=" isNavBar ? '完成' : '编辑'"
                    fixed="true"
                    statusBar="true"
                    @clickRight=" isNavBar = !isNavBar"
                ></uniNavBar>
                
                <!-- 商品内容 -->
                <view class="shop-item" v-for="(item,index) in list" :key="index">
                    <label for="" class="radio" @tap="selectedItem(index)">
                        <radio value="" color="#FF3333" :checked="item.checked" /> <text></text>
                    </label>
                    <image class="shop-img" :src="item.imgUrl" mode=""></image>
                    <view class="shop-text">
                        <view class="shop-name">
                            {{item.name}}
                        </view>
                        <view class="shop-color f-color">
                            {{item.color}}
                        </view>
                        <view class="shop-price">
                            <view class="">{{item.pprice}}
                            </view>
                            <template v-if="!isNavBar">
                                <view>x {{item.num}}</view>
                            </template>
                            <template v-else>
                                <uniNumberBox
                                    :value="item.num"
                                    :min=1
                                    @change="changeNumber($event,index,item)"
                                ></uniNumberBox>
                            </template>
                        </view>
                    </view>
                </view>
                <!-- 底部 -->
                <view class="shop-foot">
                    <label for="" class="radio foot-radio" @tap='checkedAllFn'>
                        <radio value="" color="#FF3333" :checked="checkedAll"></radio><text>全选</text>
                    </label>
                    <template v-if="!isNavBar">
                        <view class="foot-total">
                            <view class="foot-count">
                                合计:
                                <text class="f-active-color">{{totalCount.pprice}}
                                </text>
                            </view>
                            <view class="foot-num" @tap="goConfirmOrder">
                                结算({{totalCount.num}})
                            </view>
                        </view>
                    </template>
                    <template v-else>
                        <view class="foot-total">
                            <view class="foot-num" style="background-color: black;">
                                移入收藏夹
                            </view>
                            <view class="foot-num" @tap="delGoodsFn">
                                删除
                            </view>
                        </view>
                    </template>
                </view>
                
            </template>
            <template v-else>
                <uniNavBar 
                    title="购物车"
                    fixed="true"
                    statusBar="true"
                ></uniNavBar>
                <view class="shop-else-list">
                    <text>~ 购物车还是空的~</text>
                </view>
            </template>
            <Tabbar currentPage='shopcart'></Tabbar>
        </view>
    </template>

    <script>
        import $http from '@/common/api/request.js'
        import uniNavBar from '@/components/uni/uni-nav-bar/uni-nav-bar.vue'
        import uniNumberBox from '@/components/uni/uni-number-box/uni-number-box.vue'
        import Tabbar from '@/components/common/Tabbar.vue';//引入
        
        // 状态机引入
        import {mapState,mapActions,mapGetters,mapMutations} from 'vuex'
        export default {
            data() {
                return {
                    isNavBar:false,
                }
            },
            computed:{
                // 状态机数据处理
                ...mapState({
                    list:state=>state.cart.list,
                    selectedList:state=>state.cart.selectedList,
                }),
                ...mapGetters(['checkedAll','totalCount'])
            },
            components:{
                uniNavBar,uniNumberBox,Tabbar
            },
            onShow() {
              this.getData();  
            },
            methods: {
                ...mapActions(['checkedAllFn','delGoodsFn']),
                ...mapMutations(['selectedItem','initGetData']),
                getData(){
                    $http.request({
                        url:'/selectCart',
                        method:"POST",
                        header:{
                            token:true
                        }
                    }).then((res)=>{
                        this.initGetData(res)
                    }).catch(()=>{
                        uni.showToast({
                        title:'请求失败',
                        icon:'none'
                        })
                    })
                },
                changeNumber(value,index,item){
                    if ( value == item.num ) return;
                    $http.request({
                        url:'/updateCart',
                        method:"POST",
                        header:{
                            token:true
                        },
                        data:{
                            goodsId:item.goods_id,
                            num:value
                        }
                    }).then((res)=>{
                        this.list[index].num = value;
                    }).catch(()=>{
                        uni.showToast({
                        title:'请求失败',
                        icon:'none'
                        })
                    })
                },
                // 进入确认订单
                goConfirmOrder(){
                    if(this.selectedList.length === 0){
                        return uni.showToast({
                            title:"至少选择一件商品",
                            icon:"none"
                        })
                    }
                    uni.navigateTo({
                        url:`/pages/confirm-order/confirm-order?detail=${JSON.stringify(this.selectedList)}`
                    })
                }
            }
        }
    </script>

    <style lang="scss">

    .shop-list{
        padding-bottom: 100rpx;
    }
    .shop-else-list{
        position: absolute;
        left: 0;
        top: 0;
        right: 0;
        bottom: 0;
        background-color: #f7f7f7;
        display: flex;
        align-items: center;
        justify-content: center;
    }
    .shop-item{
        display: flex;
        padding: 20rpx;
        align-items: center;
        background-color: #f7f7f7;
        margin-bottom: 10rpx;
    }
    .shop-img{
        width: 200rpx;
        height: 200rpx;
    }
    .shop-text{
        flex: 1;
        padding-left: 20rpx;
    }
    .shop-color{
        font-size: 24rpx;
    }
    .shop-price{
        display: flex;
        justify-content: space-between;
    }

    .shop-foot{
        border-top: 2rpx solid #f7f7f7;
        background-color: #FFFFFF;
        position: fixed;
        bottom: 0;
        left: 0;
        width: 100%;
        height: 100rpx;
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 120rpx;
    }
    .foot-radio{
        padding-left: 20rpx;
    }
    .foot-total{
        display: flex;
    }
    .foot-count{
        line-height: 100rpx;
        padding: 0 20rpx;
        font-size: 32rpx;
    }
    .foot-num{
        background-color: #49bdfb;
        color: #FFFFFF;
        padding: 0 60rpx;
        line-height: 100rpx;
    }
    </style>

confirm-order.vue

<template>
    <view class="confirm-order bg-active-color">
        <Lines></Lines>
        
        <!-- 地址 -->
        <view class="order-map" @tap="goPathList">
            <block v-if="path">
                <view class="map-title">
                    <view class="map-name">收件人:{{path.name}}</view>
                    <view class="">{{path.tel}}</view>
                </view>
                <view class="map-add">
                    收货地址:{{path.city}} {{path.detail}}
                </view>
            </block>
            <block v-else>
                <view class="map-title">
                    <view class="map-name">请选择地址</view>
                </view>
            </block>
            
        </view>
        
        <!-- 商品 -->
        <view class="goods-list" v-for="(item,index) in goodsList" :key="index">
                
            <view class="goods-content bg-active-color">
                <image class="goods-img" :src="item.imgUrl" mode=""></image>
                <view class="goods-text">
                    <view class="goods-name">
                        {{item.name}}
                    </view>
                    <view class="goods-size f-color">
                        颜色分类:黑色
                    </view>
                    <view class="f-active-color">
                        7天无理由
                    </view>
                </view>
                <view class="">
                    <view class="">{{item.pprice}}
                    </view>
                    <view class="goods-size">
                        x {{item.num}}
                    </view>
                </view>
            </view>
            
        </view>
    
        <!-- 底部:提交订单 -->
        <view class="order-foot">
            <view class="total-price">
                合计: <text class="f-active-color">${{totalCount.pprice}}</text>
            </view>
            <view class="confirm" @tap="goPayment">
                提交订单
            </view>
        </view>
    </view>
</template>

<script>
    import $http from '@/common/api/request.js'
    import Lines from '@/components/common/Lines.vue'
    import {mapGetters,mapState,mapMutations} from 'vuex'
    export default {
        data() {
            return {
                path:false
            };
        },
        computed:{
            ...mapState({
                list:state=>state.cart.list
            }),
            ...mapGetters(['defaultPath','totalCount']),
            // 根据商品列表找到对应的e.detail 数据的 id 最终返回商品数据
            goodsList(){
                return this.item.map(id=>{
                    return this.list.find(v=>v.id == id)
                })
            }
        },
        onLoad(e) {
            console.log(e.detail,this.list);
            // 选中的商品id集合 [1,3]
            this.item = JSON.parse(e.detail);
            
            // 如果默认地址的一个赋值
            $http.request({
                url:'/selectAddress',
                method:"POST",
                header:{
                    token:true
                }
            }).then((res)=>{
                this.__initAddressList(res);
                if(this.defaultPath.length){
                    this.path = this.defaultPath[0];
                }
            }).catch(()=>{
                uni.showToast({
                title:'请求失败',
                icon:'none'
                })
            })
            
            
            // 如果出发自定义事件,on去接收值
            uni.$on('selectPathItem',(res)=>{
                // console.log(res);
                this.path = res;
            })
        },
        onUnload() {
          uni.$off('selectPathItem',()=>{
              console.log('移除了selectPathItem');
          })  
        },
        components:{
            Lines
        },
        methods:{
            ...mapMutations(['__initAddressList']),
            // 跳转到地址管理页面
            goPathList(){
                uni.navigateTo({
                    url:'/pages/my-path-list/my-path-list?type=selectedPath'
                })
            },
            // 确认支付
            goPayment(){
                if( this.path ){
                    return uni.showToast({
                        title:'请选择收货地址',
                        icon:'none'
                    })
                }
                
                uni.navigateTo({
                    url:'/pages/payment/payment'
                })
            }
        }
    }
</script>

<style lang="less">
.confirm-order{
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    width: 100%;
    height: 100%;
}
.order-map{
    margin-bottom: 10rpx;
    padding: 20rpx;
    background-color: #fff;
    line-height: 50rpx;
}
.map-title{
    display: flex;
    justify-content: space-between;
}
.map-name{
    font-weight: bold;
}
.goods-list{
    background-color: #fff;
    padding: 10rpx 0;
}

.goods-content{
    padding: 10rpx 20rpx;
    display: flex;
    justify-content: space-between;
    align-items: center;
}
.goods-text{
    width: 360rpx;
    padding: 0 10rpx;
    font-size: 26rpx;
}
.goods-img{
    width: 160rpx;
    height: 160rpx;
}
.goods-size{
    font-size: 24rpx;
}

.order-foot{
    width: 100%;
    height: 80rpx;
    position: fixed;
    bottom: 0;
    left: 0;
    background-color: #fff;
    display: flex;
    justify-content: flex-end;
    align-items: center;
}
.confirm{
    color: #fff;
    background-color: #49bdfb;
    padding: 10rpx 30rpx;
}
.total-price{
    padding: 0 20rpx;
}


</style>

path.js

export default{
    state:{
        list:[
            /* {
                name:"张果老",
                tel:"18010101919",
                city:"北京市朝阳区建国路",
                details:"四惠东199号",
                isDefault:false
            },{
                name:"吕洞宾",
                tel:"18010102929",
                city:"北京市石景山区鲁谷",
                details:"中心西街199号",
                isDefault:true
            } */
        ]
    },
    getters:{
        defaultPath(state){
            // return state.list.filter(v=>v.isDefault)
            return state.list.filter(v=>{
                return v.isDefault == 1
            })
        }
    },
    mutations:{
        // 拿到初始化请求当前用户收货地址数据
        __initAddressList(state,list){
            state.list = list;
        },
        createPath( state, obj ){
            state.list.unshift( obj );
        },
        updatePath( state, {index,item} ){
            for(let key in item){
                state.list[index][key] = item[key];
            }
        },
        // 把之前选中默认的改完未选中
        removePath(state){
            state.list.forEach(v=>{
                if(v.isDefault){
                    v.isDefault = 0;
                }
            })
        }
    },
    actions:{
        createPathFn({commit}, obj){
            if(obj.isDefault){
                commit('removePath')
            }
            commit('createPath', obj);
        },
        updatePathFn({commit}, obj){
            if(obj.item.isDefault){
                commit('removePath')
            }
            commit('updatePath', obj);
        }
    }
}

目录结构

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

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

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

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

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

  • page 页面

    • index
      • index.vue
    • list
      • list.vue
    • my
      • my.vue
    • my-config
      • my-config.vue
    • my-config
      • my-config.vue
    • my-add-path
      • my-add-path.vue
    • my-path-list
      • my-path-list.vue
    • search
      • search.vue
    • search-list
      • search-list.vue
    • shopcart
      • shopcart.vue
    • details
      • details.vue
    • my-order
      • my-order.vue
    • confirm-order
      • confirm-order.vue
    • payment
      • payment.vue
    • payment-success
      • payment-success.vue
    • login
      • login.vue
    • login-tel
      • login-tel.vue
    • login-code
      • login-code.vue
  • components 组件

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

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

    • modules
      • cart.js
      • path.js
      • user.js
    • index.js
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值