【vue3.0】17.0 某东到家(十七)——底部购物车展开页(三)
这里主要进行一些细节的优化
全选按钮图标的居中
首先是全选按钮图标的居中
.product {
......
&__header {
......
&__all {
......
&__icon {
display: inline-block;
vertical-align: top;
font-size: 0.2rem;
color: #0091ff;
}
全选取消状态图标优化
更新内容如下:
更新Cart.vue中的icon名称,最终效果如下:
点击蒙层,购物车隐藏
src\views\shop\Cart.vue
<template>
<!-- 蒙层 -->
<div class="mask" v-if="showCart" @click="handleCartShowChange"></div>
......
样式颜色集成
<style lang="scss" scoped>
@import '@/style/viriables.scss';
@import '@/style/mixins.scss';
.mask {
position: fixed;
left: 0;
right: 0;
bottom: 0;
top: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 1;
}
.cart {
position: absolute;
left: 0;
right: 0;
bottom: 0;
z-index: 2;
background: $bg-color;
}
.product {
overflow-y: scroll;
flex: 1;
background: $bg-color;
&__header {
display: flex;
line-height: 0.52rem;
border-bottom: 0.01rem solid $content-bg-color;
font-size: 0.14rem;
color: $content-font-color;
&__all {
width: 0.64rem;
margin-left: 0.18rem;
&__icon {
display: inline-block;
vertical-align: top;
font-size: 0.2rem;
margin-right: 0.05rem;
color: $btn-bg-color;
}
&__text {
display: inline-block;
margin-left: 0.04rem;
line-height: 0.52rem;
}
}
&__clear {
flex: 1;
text-align: right;
margin-right: 0.16rem;
}
}
&__item {
position: relative;
display: flex;
padding: 0.12rem 0.16rem;
margin: 0 0.16rem;
border-bottom: 0.01rem solid $content-bg-color;
&__checked {
line-height: 0.5rem;
margin-right: 0.2rem;
color: $btn-bg-color;
i {
font-size: 0.25rem;
}
}
// 配合解决超出长度以省略号显示而不会出现换行
&__detail {
overflow: hidden;
}
&__img {
width: 0.46rem;
height: 0.46rem;
margin-right: 0.16rem;
}
&__title {
margin: 0;
line-height: 0.2rem;
font-size: 0.14rem;
color: $content-font-color;
// 超出长度以省略号显示而不会出现换行
@include ellipsis;
}
&__price {
margin: 0.06rem 0 0 0;
line-height: 0.2rem;
font-size: 0.14rem;
color: $height-light-font-color;
}
&__yen {
font-size: 0.12rem;
}
&__origin {
margin-left: 0.06rem;
line-height: 0.2rem;
font-size: 0.12rem;
color: $light-font-color;
text-decoration: line-through; //中划线
}
// 购物车选购数量和加减号
.product__number {
position: absolute;
right: 0rem;
bottom: 0.12rem;
&__minus,
&__plus {
display: inline-block;
width: 0.2rem;
height: 0.2rem;
line-height: 0.16rem;
border-radius: 50%;
font-size: 0.2rem;
text-align: center;
}
// 边框白色
&__minus {
border: 0.01rem solid $medium-font-color;
color: $medium-font-color;
margin-right: 0.05rem;
}
//无边框,背景蓝色
&__plus {
color: $bg-color;
background: $btn-bg-color;
margin-left: 0.05rem;
}
}
}
}
.check {
display: flex;
box-sizing: border-box; //往内塞入border
line-height: 0.49rem;
height: 0.49rem;
border-top: 0.01rem solid $content-bg-color;
&__icon {
width: 0.84rem;
position: relative;
&__img {
margin: 0.12rem auto;
display: block;
width: 0.28rem;
height: 0.28rem;
}
&__tag {
// 乘以2然后等比例缩小
position: absolute;
left: 0.46rem;
top: 0.04rem;
padding: 0 0.04rem;
min-width: 0.2rem;
height: 0.2rem;
line-height: 0.2rem;
text-align: center;
background-color: $height-light-font-color;
border-radius: 0.1rem;
font-size: 0.12rem;
color: $bg-color;
transform: scale(0.5);
transform-origin: left center;
}
}
&__info {
flex: 1;
color: $content-font-color;
font-size: 0.12rem;
&__price {
line-height: 0.49rem;
color: $height-light-font-color;
font-size: 0.18rem;
}
}
&__btn {
width: 0.98rem;
background-color: #4fb0f9;
text-align: center;
color: $bg-color;
font-size: 0.14rem;
}
}
</style>
购物车详情加减号居中
// 购物车选购数量和加减号
.product__number {
......
bottom: 0.26rem;
“清空购物车”高度撑满
<template>
<!-- 蒙层 -->
<div class="mask" v-if="showCart" @click="handleCartShowChange"></div>
<div class="cart">
<div class="product" v-show="showCart">
<div class="product__header">
......
<div class="product__header__clear">
<span
class="product__header__clear__btn"
@click="cleanCartProducts(shopId)"
>清空购物车</span
>
</div>
</div>
......
.product {
.....
&__header {
.....
&__clear {
.....
&__btn {
display: inline-block;
}
}
}
最终调整效果如下:
<template>
<!-- 蒙层 -->
<div class="mask" v-if="showCart" @click="handleCartShowChange"></div>
<div class="cart">
<div class="product" v-show="showCart">
<div class="product__header">
<div class="product__header__all" @click="setCartItemsChecked(shopId)">
<i
:class="[
'product__header__all__icon',
'custom-icon',
allChecked
? 'custom-icon-radio-checked'
: 'custom-icon-radio-unchecked'
]"
></i>
<span class="product__header__all__text">全选</span>
</div>
<div class="product__header__clear">
<span
class="product__header__clear__btn"
@click="cleanCartProducts(shopId)"
>清空购物车</span
>
</div>
</div>
<template v-for="item in productList" :key="item._id">
<div class="product__item" v-if="item.count > 0">
<div
class="product__item__checked"
@click="changeCartItemChecked(shopId, item._id)"
>
<i
:class="[
'custom-icon',
item.checked == true
? 'custom-icon-radio-checked'
: 'custom-icon-radio-unchecked'
]"
></i>
</div>
<img class="product__item__img" :src="item.imgUrl" />
<div class="product__item__detail">
<h4 class="product__item__title">{{ item.name }}</h4>
<p class="product__item__price">
<span class="product__item__yen"> ¥{{ item.price }} </span>
<span class="product__item__origin">
¥{{ item.oldPrice }}
</span>
</p>
</div>
<div class="product__number">
<span
class="product__number__minus"
@click="
() => {
0
changeCartItemInfo(shopId, item._id, item, -1)
}
"
>-</span
>
{{ cartList?.[shopId]?.[item._id]?.count || 0 }}
<span
class="product__number__plus"
@click="
() => {
changeCartItemInfo(shopId, item._id, item, 1)
}
"
>+</span
>
</div>
</div>
</template>
</div>
<div class="check">
<div class="check__icon" @click="handleCartShowChange">
<img src="/i18n/9_16/img/basket.png" alt="" class="check__icon__img" />
<div class="check__icon__tag">
{{ total }}
</div>
</div>
<div class="check__info">
总计:<span class="check__info__price">¥ {{ totalPrice }}</span>
</div>
<div class="check__btn">去结算</div>
</div>
</div>
</template>
<script>
import { ref, computed } from 'vue'
import { useRoute } from 'vue-router' // 路由跳转方法
import { useStore } from 'vuex' // 路由跳转方法
import { useCommonCartEffect } from './commnCartEffect'
const useCartEffect = shopId => {
const { changeCartItemInfo } = useCommonCartEffect()
const store = useStore()
// 单个勾选或者不勾选
const changeCartItemChecked = (shopId, productId) => {
store.commit('changeItemChecked', { shopId, productId })
}
// 清除购物车按钮
const cleanCartProducts = shopId => {
store.commit('changeCleanCartProducts', { shopId })
}
// 购物车全选或者取消全选
const setCartItemsChecked = shopId => {
store.commit('setCartItemsChecked', { shopId })
}
// 计算shopId下所有cartList的商品数量total、价钱之和totalPrice
const cartList = store.state.cartList // 加入购物车的商品列表fv
const total = computed(() => {
const productList = cartList[shopId]
let count = 0
if (productList) {
for (const i in productList) {
const product = productList[i]
count += product.count
}
}
return count
})
const totalPrice = computed(() => {
const productList = cartList[shopId]
let count = 0
if (productList) {
for (const i in productList) {
const product = productList[i]
if (product.checked === true) {
count += product.count * product.price
}
}
}
return count.toFixed(2) // 保留2位小数
})
// 全选的计算属性
const allChecked = computed(() => {
const productList = cartList[shopId]
let result = true
if (productList) {
for (const i in productList) {
const product = productList[i]
if (product.count > 0 && !product.checked) {
result = false
break
}
}
}
return result
})
const productList = computed(() => {
const productInfoList = cartList[shopId] || [] // 不存在默认空数组
return productInfoList
})
return {
cartList,
total,
totalPrice,
productList,
allChecked,
changeCartItemChecked,
changeCartItemInfo,
cleanCartProducts,
setCartItemsChecked
}
}
// 展示隐藏购物车
const toggleCartEffect = () => {
const showCart = ref(false)
// 显示隐藏购物车具体内容
const handleCartShowChange = () => {
showCart.value = !showCart.value
}
return { showCart, handleCartShowChange }
}
export default {
name: 'Cart',
setup() {
const route = useRoute()
const shopId = route.params.id // 店铺id
// 展示隐藏购物车
const { showCart, handleCartShowChange } = toggleCartEffect()
// 计算总价和加入购物车的总数量
const {
cartList,
total,
totalPrice,
productList,
allChecked,
changeCartItemChecked,
changeCartItemInfo,
cleanCartProducts,
setCartItemsChecked
} = useCartEffect(shopId)
return {
cartList,
total,
totalPrice,
productList,
shopId,
allChecked,
showCart,
handleCartShowChange,
changeCartItemChecked,
changeCartItemInfo,
cleanCartProducts,
setCartItemsChecked
}
}
}
</script>
<style lang="scss" scoped>
@import '@/style/viriables.scss';
@import '@/style/mixins.scss';
.mask {
position: fixed;
left: 0;
right: 0;
bottom: 0;
top: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 1;
}
.cart {
position: absolute;
left: 0;
right: 0;
bottom: 0;
z-index: 2;
background: $bg-color;
}
.product {
overflow-y: scroll;
flex: 1;
background: $bg-color;
&__header {
display: flex;
line-height: 0.52rem;
border-bottom: 0.01rem solid $content-bg-color;
font-size: 0.14rem;
color: $content-font-color;
&__all {
width: 0.64rem;
margin-left: 0.18rem;
&__icon {
display: inline-block;
vertical-align: top;
font-size: 0.2rem;
margin-right: 0.05rem;
color: $btn-bg-color;
}
&__text {
display: inline-block;
margin-left: 0.04rem;
line-height: 0.52rem;
}
}
&__clear {
flex: 1;
text-align: right;
margin-right: 0.16rem;
&__btn {
display: inline-block;
}
}
}
&__item {
position: relative;
display: flex;
padding: 0.12rem 0.16rem;
margin: 0 0.16rem;
border-bottom: 0.01rem solid $content-bg-color;
&__checked {
line-height: 0.5rem;
margin-right: 0.2rem;
color: $btn-bg-color;
i {
font-size: 0.25rem;
}
}
// 配合解决超出长度以省略号显示而不会出现换行
&__detail {
overflow: hidden;
}
&__img {
width: 0.46rem;
height: 0.46rem;
margin-right: 0.16rem;
}
&__title {
margin: 0;
line-height: 0.2rem;
font-size: 0.14rem;
color: $content-font-color;
// 超出长度以省略号显示而不会出现换行
@include ellipsis;
}
&__price {
margin: 0.06rem 0 0 0;
line-height: 0.2rem;
font-size: 0.14rem;
color: $height-light-font-color;
}
&__yen {
font-size: 0.12rem;
}
&__origin {
margin-left: 0.06rem;
line-height: 0.2rem;
font-size: 0.12rem;
color: $light-font-color;
text-decoration: line-through; //中划线
}
// 购物车选购数量和加减号
.product__number {
position: absolute;
right: 0rem;
bottom: 0.26rem;
&__minus,
&__plus {
display: inline-block;
width: 0.2rem;
height: 0.2rem;
line-height: 0.16rem;
border-radius: 50%;
font-size: 0.2rem;
text-align: center;
}
// 边框白色
&__minus {
border: 0.01rem solid $medium-font-color;
color: $medium-font-color;
margin-right: 0.05rem;
}
//无边框,背景蓝色
&__plus {
color: $bg-color;
background: $btn-bg-color;
margin-left: 0.05rem;
}
}
}
}
.check {
display: flex;
box-sizing: border-box; //往内塞入border
line-height: 0.49rem;
height: 0.49rem;
border-top: 0.01rem solid $content-bg-color;
&__icon {
width: 0.84rem;
position: relative;
&__img {
margin: 0.12rem auto;
display: block;
width: 0.28rem;
height: 0.28rem;
}
&__tag {
// 乘以2然后等比例缩小
position: absolute;
left: 0.46rem;
top: 0.04rem;
padding: 0 0.04rem;
min-width: 0.2rem;
height: 0.2rem;
line-height: 0.2rem;
text-align: center;
background-color: $height-light-font-color;
border-radius: 0.1rem;
font-size: 0.12rem;
color: $bg-color;
transform: scale(0.5);
transform-origin: left center;
}
}
&__info {
flex: 1;
color: $content-font-color;
font-size: 0.12rem;
&__price {
line-height: 0.49rem;
color: $height-light-font-color;
font-size: 0.18rem;
}
}
&__btn {
width: 0.98rem;
background-color: #4fb0f9;
text-align: center;
color: $bg-color;
font-size: 0.14rem;
}
}
</style>
发表评论 (审核通过后显示评论):