UNIAPP Practical Project Notes 69 Displayed as the default address when order confirmation

UNIAPP Practical Project Notes 69 Displayed as the default address when order confirmation

Ideas

You need to use vuex
to display the address whose isDefault is 1 by default.

Case screenshot

Order settlement page

Insert image description here

address page

Insert image description here

code

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);
        }
    }
}

Directory Structure

Front-end directory structure
  • manifest.json configuration file: appid, logo…

  • pages.json configuration file: navigation, tabbar, routing

  • main.js vue initialization entry file

  • App.vue global configuration: styles, global monitoring

  • static static resources: pictures, font icons

  • page 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 components

    • index
      • banner.view
      • 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 public files: global css file || global js file

    • api
      • request.js
    • common.css
    • uni.css
  • store vuex state machine file

    • modules
      • cart.js
      • path.js
      • user.js
    • index.js

Guess you like

Origin blog.csdn.net/gixome/article/details/130651663