【原 因】:共有 和 私有 有冲突 【过 程】:更改样式表名称 【影 响】: # 类型 包含: # feat:新功能(feature) # fix:修补bug # docs:文档(documentation) # style: 格式(不影响代码运行的变动) # refactor:重构(即不是新增功能,也不是修改bug的代码变动) # test:增加测试 # chore:构建过程或辅助工具的变动
335 lines
9.8 KiB
Vue
335 lines
9.8 KiB
Vue
<template>
|
||
<view class="flex column">
|
||
<!-- topbar -->
|
||
<u-navbar :title="spu.name" bgColor="#d43030" :titleStyle="{ color: '#FFF'}" :autoBack="true" placeholder>
|
||
<view class="u-nav-slot" slot="left">
|
||
<u-icon name="arrow-left" color="#fff" size="19"></u-icon>
|
||
</view>
|
||
</u-navbar>
|
||
<!-- 主图 -->
|
||
<u-swiper :list="spu.photo" height="572.5rpx" easingFunction="easeInCubic" radius="0" circular></u-swiper>
|
||
<!-- 标题 和 内容 -->
|
||
<view class="p-24 z-top fz44 fb bg-w">{{spu.name}}</view>
|
||
<view class="p-l-24 p-r-24 p-b-24 fcb fz24 borderB bg-w">
|
||
<u-read-more ref="uReadMore" showHeight="36" closeText="详情展开" openText="收起" toggle="true" color="#808080">
|
||
<u-parse class="fz28 l-h-18" :content="spu.content" @load="load"></u-parse>
|
||
</u-read-more>
|
||
</view>
|
||
<!-- spu列表 -->
|
||
<view class="p-l-24 p-r-24 m-t-24" v-for="(spuB,index) in spu.bind_sku" :key="index">
|
||
<!-- sku组标题 -->
|
||
<view class="flex mac m-b-12">
|
||
<u-icon name="plus-square-fill" size="36rpx" color="#333"></u-icon>
|
||
<text class="fz36 fb">{{spuB.tit}}</text>
|
||
</view>
|
||
<!-- sku组内容 -->
|
||
<view class="grid-container m-b-24">
|
||
<view v-for="(sku,i) in spuB.skuG" :key="i" class="grid-item bg-g rad8 border4 border-g flex column"
|
||
:class="isSel(sku.id)?'border-m':''" style="height: 296rpx;" @click="selSku(sku.id)">
|
||
<u--image :src="sku.photo[0]" width="100%" height="182rpx" radius="4rpx"></u--image>
|
||
<view class="fz28 tc l-h-18 m-t-12">{{sku.name}}</view>
|
||
<view class="flex1 flex msb mac">
|
||
<view class="m-l-12 fcm">
|
||
<text v-if="priceDifference(sku.id)<0">
|
||
{{priceDifference(sku.id) | formatPrice}}
|
||
</text>
|
||
<text v-else-if="priceDifference(sku.id)>0">
|
||
+{{priceDifference(sku.id) | formatPrice}}
|
||
</text>
|
||
</view>
|
||
<view class="border rad-c m-r-12 radioBox" :class="isSel(sku.id)?'border-m bg-m':''">
|
||
<u-icon name="checkbox-mark" size="40rpx" color="#fff" v-if="isSel(sku.id)"></u-icon>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<!-- 底部占位 -->
|
||
<view class="extra-space">
|
||
<u-divider text="产品包装以实物为准" :hairline="true"></u-divider>
|
||
</view>
|
||
<!-- 购物车按钮 -->
|
||
<view class="cartBox flex mc">
|
||
<!-- 购物车框 -->
|
||
<view class="bottomBox rad32 flex mc mac">
|
||
<view class="flex mc mac bottomBoxin">
|
||
<view class="rad8 flex mc mac bottomBoxinin ">
|
||
<view class="flex mac bottomBoxCon p-b-24">
|
||
<view v-for="(spuB,index) in spu.bind_sku" :key="index" class="m-t-24 bowlBox">
|
||
<!-- 删除小按钮 -->
|
||
<view v-if="isSelSkuG(spuB.value)" class="cBUt bg-w rad-c flex mc mac z-top"
|
||
@click="delSku(spuB.value)">
|
||
<u-icon :name="spuB.skuG.length!==1?'close':'lock'" :bold="true" color="#333"
|
||
size="10"></u-icon>
|
||
</view>
|
||
<!-- 碗 -->
|
||
<view class="bg-mg rad-c bowl ofh border4"
|
||
:class="isSelSkuG(spuB.value)?'border-m':'border-g'">
|
||
<u--image v-for="(sku,i) in spuB.skuG" :key="i" v-if="isSel(sku.id)"
|
||
:src="sku.photo[0]" width="108rpx" height="108rpx" mode="aspectFit"></u--image>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<!-- 加入购物车 -->
|
||
<view v-if="isSelAll" class="bg-m rad16 fci flex msb cartButBox">
|
||
<view class="flex1 p-l-24 flex column mc">
|
||
<view class="fz36">¥{{totalPrice | formatPrice}}</view>
|
||
</view>
|
||
<view class="flex column mac mc" style="width: 220rpx;" @click="handleAddCart">
|
||
<view class="fz36">加入购物车</view>
|
||
<view class="fz24">Add to Cart</view>
|
||
</view>
|
||
</view>
|
||
<view v-else class="bg-g rad16 flex mc mac cartButBox">
|
||
<view class="fz36 fb">请选择餐品</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import {
|
||
formatPrice
|
||
} from '@/utils/index.js'
|
||
export default {
|
||
data() {
|
||
return {
|
||
spu_id: null, //get接收spuid
|
||
initerr: true, //sel初始化之前 禁止 selSku点击事件
|
||
sel: [] //选中的sku
|
||
}
|
||
},
|
||
computed: {
|
||
spu() {
|
||
return this.$store.state.spuList.find(item => item.id === this.spu_id)
|
||
},
|
||
//判断 是否每项sku组都 被选中其一
|
||
isSelAll() {
|
||
if (this.spu !== null) {
|
||
return this.sel.length === this.spu.bind_sku.length
|
||
} else {
|
||
return false
|
||
}
|
||
},
|
||
//已选中sku 的价格总和
|
||
totalPrice() {
|
||
let totalPrice = 0
|
||
let sku
|
||
this.sel.forEach(id => {
|
||
for (let i = 0; i < this.spu.bind_sku.length; i++) {
|
||
let index = this.spu.bind_sku[i].value.indexOf(Number(id))
|
||
if (index !== -1) {
|
||
sku = this.spu.bind_sku[i].skuG[index]
|
||
break
|
||
}
|
||
}
|
||
totalPrice += parseFloat(sku.price)
|
||
})
|
||
return totalPrice.toFixed(2)
|
||
}
|
||
},
|
||
methods: {
|
||
load() {
|
||
this.$refs.uReadMore.init()
|
||
},
|
||
//判断是否选择 改变样式
|
||
isSel(id) {
|
||
return this.sel.indexOf(id.toString()) !== -1
|
||
},
|
||
//判断 一组id中 有没有没选择 有一个被选择 改变样式
|
||
isSelSkuG(idArr) {
|
||
let res = false
|
||
idArr.forEach(id => {
|
||
if (this.sel.indexOf(id.toString()) !== -1) {
|
||
res = true
|
||
return
|
||
}
|
||
})
|
||
return res
|
||
},
|
||
//选择sku
|
||
selSku(sku_id) {
|
||
if (this.initerr === true) { //sel初始化 完成与否
|
||
return
|
||
}
|
||
let ord = this.sel.indexOf(sku_id) //点击的id 在选中sel组中的位置
|
||
//当前没有选中 执行
|
||
if (ord === -1) {
|
||
// 遍历 spu.bind_sku 数组
|
||
this.spu.bind_sku.forEach(item => {
|
||
// 如果当前 item.value 中包含 sku_id,则将其从 this.sel 中移除
|
||
if (item.value.indexOf(Number(sku_id)) !== -1) {
|
||
item.value.forEach(v => {
|
||
// 找到要移除的值在 this.sel 中的索引
|
||
let index = this.sel.indexOf(v.toString())
|
||
// 如果索引不为 -1,则从 this.sel 中移除该值
|
||
if (index !== -1) {
|
||
this.sel.splice(index, 1)
|
||
}
|
||
})
|
||
}
|
||
})
|
||
// 将新的 sku_id 添加到 sel 数组中
|
||
this.sel.push(sku_id)
|
||
} else { //如果当前已经选中 还被点击 则取消选择
|
||
this.sel.splice(ord, 1)
|
||
}
|
||
},
|
||
//小按钮 删除 清楚当前选中sku
|
||
delSku(idArr) {
|
||
if (idArr.length > 1) {
|
||
idArr.forEach(id => {
|
||
const subscript = this.sel.indexOf(id.toString())
|
||
if (subscript !== -1) {
|
||
this.sel.splice(subscript, 1)
|
||
}
|
||
})
|
||
}
|
||
},
|
||
//sel 初始化 sku组只有单sku的 默认选中 即将sku id添加到sel数组
|
||
initSel() {
|
||
// 遍历 spu.bind_sku 数组
|
||
this.spu.bind_sku.forEach(item => {
|
||
this.sel.push(item.value[0].toString()) //添加
|
||
})
|
||
//初始化完成后 才允许selSku点击事件执行
|
||
this.initerr = false
|
||
},
|
||
//添加购物车
|
||
handleAddCart() {
|
||
let orderSel = [] //把sel数组 按照sku组的顺序 重新排序
|
||
this.spu.bind_sku.forEach(item => {
|
||
item.value.forEach(id => {
|
||
if (this.sel.indexOf(id.toString()) !== -1) {
|
||
orderSel.push(id.toString())
|
||
}
|
||
})
|
||
})
|
||
let orderPrice = [] //skuG对应的单价
|
||
let orderCount = [] //skuG对应的数量
|
||
orderSel.forEach(id => {
|
||
const sku = this.$store.state.skuList.find(item => item.id.toString() === id.toString())
|
||
orderPrice.push(Number(parseFloat(sku.price).toFixed(2)))
|
||
orderCount.push(1)
|
||
})
|
||
let cart = {
|
||
"spu_id": this.spu.id,
|
||
"skuG": orderSel,
|
||
"countG": orderCount,
|
||
"priceG": orderPrice
|
||
}
|
||
this.$store.commit('setCartList', cart)
|
||
|
||
// 返回上一页
|
||
uni.navigateBack({
|
||
delta: 1 // 返回的页面数,这里是返回上一页,如果是返回多级页面,可以设置为对应的值
|
||
})
|
||
},
|
||
//sku组 差价显示 ps:sku组第一个为默认选择 其价格为价格基数 算各sku的差价
|
||
priceDifference(sku_id) {
|
||
let priceDifference = 0 //记录差价
|
||
for (let i = 0; i < this.spu.bind_sku.length; i++) {
|
||
let index = this.spu.bind_sku[i].value.indexOf(Number(sku_id))
|
||
if (index !== -1) {
|
||
if (index !== 0) { //因为第一个是基数所以差价是0 只有不是第一个值时才计算差价
|
||
const baseSku = this.spu.bind_sku[i].skuG[0]
|
||
const sku = this.spu.bind_sku[i].skuG[index]
|
||
priceDifference = Number(sku.price) - Number(baseSku.price)
|
||
}
|
||
break
|
||
}
|
||
}
|
||
return priceDifference
|
||
}
|
||
},
|
||
onLoad: function(option) { //option为object类型,会序列化上个页面传递的 get参数
|
||
this.spu_id = option.spu_id //get 传spuid
|
||
this.initSel() //sel初始化
|
||
},
|
||
filters: {
|
||
formatPrice //格式化价格
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.grid-container {
|
||
display: grid;
|
||
grid-template-columns: repeat(3, 1fr); //每行3列,等分
|
||
grid-gap: 24rpx; //设置网格项之间的间距
|
||
}
|
||
|
||
.grid-item {}
|
||
|
||
.extra-space {
|
||
height: 420rpx;
|
||
}
|
||
|
||
.cartBox {
|
||
z-index: 10076;
|
||
width: 100vw;
|
||
background: linear-gradient(to bottom, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.7) 70%, rgba(255, 255, 255, 1) 100%);
|
||
position: fixed;
|
||
bottom: 0rpx;
|
||
}
|
||
|
||
.bottomBox {
|
||
width: 678rpx;
|
||
margin-bottom: 102rpx;
|
||
background: #333;
|
||
padding: 12rpx;
|
||
position: relative;
|
||
}
|
||
|
||
.bottomBoxin {
|
||
width: 100%;
|
||
background-color: black;
|
||
border-radius: 20rpx;
|
||
padding: 12rpx;
|
||
}
|
||
|
||
.bottomBoxinin {
|
||
width: 100%;
|
||
background-color: #231e1f;
|
||
}
|
||
|
||
.bottomBoxCon {
|
||
flex-wrap: wrap;
|
||
width: 100%;
|
||
margin-bottom: 36rpx;
|
||
}
|
||
|
||
.cartButBox {
|
||
height: 108rpx;
|
||
width: 100%;
|
||
position: absolute;
|
||
bottom: -54rpx;
|
||
}
|
||
|
||
.bowlBox {
|
||
margin-left: 20rpx;
|
||
width: 108rpx;
|
||
height: 108rpx;
|
||
position: relative;
|
||
}
|
||
|
||
.bowl {
|
||
width: 108rpx;
|
||
height: 108rpx;
|
||
background-image: url(#{$image-base-url}/Public/images/appUrlImg/null-100.svg);
|
||
background-size: cover;
|
||
background-position: center;
|
||
background-repeat: no-repeat;
|
||
}
|
||
|
||
.cBUt {
|
||
width: 28rpx;
|
||
height: 28rpx;
|
||
position: absolute;
|
||
top: -12rpx;
|
||
right: -16rpx;
|
||
}
|
||
</style> |