uniapp-商城-34-shop 购物车 选好了 进行订单确认
在shop页面选中商品添加到购物车,可选好后,进行确认和支付。具体呈现在shop页面。
1 购物车栏
shop页面代码:
购物车代码:
代码:
<template><view><view class="carlayout"><!-- 车里面 点击购物车 弹出的内容 --><view class="goods" v-if="carShow"><!-- 弹窗列表 --><view class="head"><view class="text">已选商品</view><view class="empty" @click="clearCar">清空</view></view><scroll-view scroll-y="true" class="body"><view calss="scrollContent"><view class="caritem" v-for="item,index in carsList" :key="index"><car-item :item="item"></car-item></view></view></scroll-view></view><!-- 购物车 --><view class="content"><view class="left"><view class="icon" hover-class="iconhover" hover-stay-time="50" hover-start-time="10" @click="onClickCar" v-if="!type"><!-- 鼠标点击就会 触发 iconhover 这个类名 --><!-- hover-stay-time 弹回 就很块了只有 50ms --><u-icon name="shopping-cart" size="50" color="#5ac725"></u-icon><view class="num">{{totalNumValue}}</view></view><view class="price" >合计<text class="text">¥{{totalPrice}}</text></view></view><view class="right"><view class="btn disable" v-if="!type" @click="goPaypage">选好了</view><view class="btn disable" v-else @click="confirmPay">支付</view></view></view><view class="safeAreaBottom"></view><!-- 上面安全区域是设置为ios使用的,怕底部的区域被遮挡了 --></view><!-- 遮罩层 u-overlay 通过zindex 来层级显示--><u-overlay :show="carShow" z-index="9" @click="onClickCar" duration="100"></u-overlay></view><!-- 这里有一个遮罩在view外,所以总的来说就还要一个 盒子,这vue2规定只能有一个顶级盒子在template中,不能多个盒子并起来,必须把里面的盒子包裹起来 -->
</template><script>import {mapState,mapMutations,mapGetters} from "vuex"export default {name: "car-Layout",data() {return {carShow:false,};},props:{type:{type:String,default:""}},computed:{...mapGetters(["carsList","totalPrice","totalNumValue"])},methods:{...mapMutations(["setCarsList"]),//确认支付confirmPay(){console.log("确认支付");},//清空购物车clearCar(){this.setCarsList(0);},//点击购物车,改变carShow,进而改变显示状态onClickCar(){this.carShow=!this.carShow;},//点击选好了,跳转到支付页面goPaypage(){uni.navigateTo({url:"/pagesub/pageshop/paypage/paypage"})}}}
</script><style lang="scss" scoped>.carlayout {//有这个 content 下面的css始终不生效 太tmd 想爆粗口了 找了好久这个问题,最后发现是 class写错了 写成了 <view calss="carlayout">position: relative; //相对定位,不脱离文档流z-index: 10; //比 u-overlay 遮罩层 高就好.goods {border-bottom: 1rpx solid $border-color-light;padding: 30rpx 30rpx 0;border-radius: 20rpx 20rpx 0 0;background-color: #fff;.head {@include flex-box();color: $text-font-color-3;padding: 25rpx 0;.empty {color: $brand-theme-color-aux;}}.body {height: 500rpx;}}.content {display: flex;justify-content: space-between;align-items: center;padding: 0 30rpx;height: 140rpx;background: #fff;.left {@include flex-box();.iconhover {transform: scale(0.7); //鼠标点击后就缩小到0.8 然后松开鼠标就弹回 1}.icon {width: 80rpx;height: 80rpx;background-color: #eee;border-radius: 10rpx;@include flex-box-set();position: relative; //这里就是相对定位 就是为后面的num 固定到右上角的绝对定位做铺垫 num就是子级 这里的icon 就是父级margin-right: 30rpx;.num {width: 36rpx;height: 36rpx;background: $brand-theme-color;border-radius: 50%; //圆形color: #fff;position: absolute; //这里就是绝对定位 固定到icon右上角的绝对定位 num就是子级 icon 就是父级right: -18rpx;top: -18rpx;@include flex-box-set();font-size: 22rpx;}}.price {font-size: 28rpx;.text {font-size: 32rpx;font-weight: bold;}}}.right {.btn {width: 210rpx;height: 75rpx;background: $brand-theme-color;@include flex-box-set();color: #fff;border-radius: 10rpx;&.disable {opacity: 0.4; //表示透明度 变透明意思是disable了}}}}.safeAreaBottom {//这个是 用来设置ios的安全区域的,安卓是不能执行env(safe-area-inset-bottom) 这句话的width: 100%;height: env(safe-area-inset-bottom);background: #fff;}}//有这个 下面的css始终不生效
</style>
2 购物篮代码解析
2.1、shop就使用了组件
2.2、购物车中,右边的文字就是支付和选好了
选好了跳转到确认订单页面
支付就是在订单页面展现的
实现的是一个组件多个页面共用
3 确认订单页面的代码
3.1、页面组成
a、确认页面,存在外送 自提选项,主要差异:
外送和自提组件:delivery-layout
自提选项中,需要展示商家地址、 自提时间 还有商家的联系方式
外送选项中,主要就是收货地址 收货人
b、相同点 为 购物车中商品信息(goods-list组件)
c、另外还存在支付选项
支付宝和微信,默认选项为微信
d、购物车中,右边 为支付(在shop页面显示为选好了)
3.2 确认订单具体代码
<template><view class="paypage"><!-- 确认订单,支付订单 --><!-- 配送方式 --><delivery-layout></delivery-layout><!-- 购物列表 --><view class="goodsList"><goods-list></goods-list></view><!-- #ifndef MP-WEIXIN --><view class="payType"><view class="box" :class="item.value==payDefValue ? 'active' : ''" v-for="item,index in payType":key="index" @click="clickBtn(item.value)"><u-icon :name="item.icon" size="26" class="icon":color="item.value==payDefValue ? item.color :''"></u-icon><text class="font">{{item.name}}</text><!-- <u-icon name="weixin-fill" size="26" class="font"></u-icon><text class="font">微信</text>--></view></view><!-- #endif --><view class="payTabbar"><car-Layout type="pay"></car-Layout></view><view class="safeAreaBottom"></view><!-- 上面安全区域是设置为ios使用的,怕底部的区域被遮挡了 --></view>
</template><script>export default {data() {return {// #ifdef MP-WEIXINpayDefValue: "wxpay",// #endif// #ifndef MP-WEIXINpayDefValue: "alipy",// #endifpayType: [{name: "支付宝",value: "alipy", //必须写这个值,后面要用到icon: "zhifubao",color: "#1578ff", //:color="item.value==payDefValue ? item.color :''"},{name: "微 信",value: "wxpay", //必须写这个值,后面要用到icon: "weixin-fill",color: "#04c15f", //:color="item.value==payDefValue ? item.color :''"},]};},methods: {//切换支付方式clickBtn(type) {this.payDefValue = type}}}
</script><style lang="scss">page {background-color: $page-bg-color;}.paypage {padding: 30rpx;.goodsList {margin-top: 30rpx;}.payType {@include flex-box();.box {//box 就两个支付方式 width: 45%; //一个支付方式站49 剩下中间的2的空格height: 75rpx;background: #fff;border-radius: 10rpx;@include flex-box-set();// filter: grayscale(100%); //滤镜效果 100%把颜色全滤掉 我们已经用了 :color="item.value==payDefValue ? item.color :''" 就不用滤镜了border: 1rpx solid #fff;.font {padding-left: 10rpx;}}//可以这样 当用text时,若用view + style 就不用下面的方式.box:first-child.active {border-color: #1578ff; //边框颜色color: #1578ff;}.box:last-child.active {border-color: #04c15f;color: #04c15f;}}.payTabbar {position: fixed;width: 100%;bottom: 0;left: 0}}
</style>
3.3 配送方式代码:
<template><view class="delivery"><view class="headNav">外送</view><view class="body"><view class="box" @click="goAddress"><view class="left">收货地址</view><view class="center"><view v-if="deliveryInfo.address"><view class="detail">{{deliveryInfo.address}}</view><view class="userinfo">{{deliveryInfo.username + "-" + deliveryInfo.mobile}}</view></view><view class="addressTxt" v-else>请添加收货地址</view></view><view class="right"><u-icon name="arrow-right" color="#999" size="18"></u-icon></view></view></view></view>
</template><script>export default {name:"delivery-layout",data() {return {deliveryInfo:{address:"北京市海定区颐和园路",username:"李晓峰",mobile:null}}},methods:{goAddress(){uni.navigateTo({url:"/pagesub/pageshop/address/addrlist"})}}}
</script><style lang="scss">
.delivery{.headNav{width: 100%;height: 78rpx;background: #fff;@include flex-box-set();color:$brand-theme-color;border-radius: 15rpx 15rpx 0 0;}.body{background: #fff;padding:25rpx;.box{padding:40rpx 20rpx;background: $page-bg-color;border-radius: 10rpx;font-size: 30rpx;@include flex-box();.center{flex:1;padding:0 30rpx;font-size: 30rpx;.userinfo{padding-top:10rpx;}}}}
}
</style>
3.4 收货地址页面:
订单页面需要添加地址时,需跳转到这个页面
<template><view class="selfAddress"><!-- 地址列表 --><view class="headTop"><view class="title">地址簿</view><navigator class="addressBtn" url="/pagesub/pageshop/address/addredit">+ 添加地址</navigator></view><view class="list"><view class="item" v-for="item,index in 3" :key="index"><view class="head"><view class="user">张三,18066668888</view><view class="select"><u-button v-if="false" color="#EC544F" plain size="mini" text="默认地址"></u-button><u-button color="#666" v-else plain size="mini" text="设为默认"></u-button></view></view><view class="more">云南省昆明市高新区XXX楼</view></view></view></view>
</template><script>export default {data() {return {};}}
</script><style lang="scss">
page{background: $page-bg-color;
}
.selfAddress{padding:30rpx;.headTop{@include flex-box();font-size: 30rpx;font-weight: bold;.addressBtn{border:1px solid #000;border-radius: 50rpx;padding:6rpx 15rpx;}}.list{padding-top:30rpx;.item{background: #fff;padding:40rpx 20rpx;margin-bottom: 30rpx;border-radius: 15rpx;.head{@include flex-box();font-weight: bold;}.more{font-size: 28rpx;color:$text-font-color-3;padding-top:10rpx;}}}
}
</style>
3.5 地址页面修改和添加
<template><view class="addressForm"><!-- 地址编辑 --><u--formlabelPosition="top":model="addressForm":rules="addressRules"labelWidth="100"ref="uForm" ><u-form-itemlabel="姓名"prop="username" ><u--inputv-model="addressForm.username"placeholder="请输入姓名"></u--input></u-form-item><u-form-itemlabel="联系电话"prop="mobile" ><u--inputv-model="addressForm.mobile"placeholder="请输入联系电话"></u--input></u-form-item><u-form-itemlabel="详细地址"prop="address" ><u--inputv-model="addressForm.address"placeholder="请输入街道门牌号"></u--input></u-form-item><u-form-item label="是否默认"><u-switch v-model="addressForm.selected"inactiveColor="#eee"></u-switch></u-form-item><u-form-item></u-form-item><u-form-item><u-button type="primary" @click="onSubmit">提交</u-button></u-form-item></u--form></view>
</template><script>export default {data() {return {addressForm:{username:"",mobile:"",address:"",selected:false},addressRules:{username:[{required: true,message: '姓名是必填的', trigger: ['blur', 'change']},{min: 2,max: 8,message: '长度在2-8个字符之间',trigger: ['blur', 'change']}],mobile:[{required: true,message: '电话是必填的', trigger: ['blur', 'change']},{ validator: (rule, value, callback) => { return uni.$u.test.mobile(value);},message: '手机号码不正确', trigger: ['change','blur']}],address:[{required: true,message: '地址是必填的', trigger: ['blur', 'change']}]}};},methods:{onSubmit(){this.$refs.uForm.validate().then(res => {uni.$u.toast('校验通过')}).catch(errors => {uni.$u.toast('校验失败')})}}}
</script><style lang="scss">
.addressForm{padding:30rpx;
}
</style>