07-购物车页面-列表展示-本地
目的:实现本地状态下的,购物车商品列表展示功能。
大致步骤:
- 准备失效商品列表数据。已选择商品列表数据。已选择商品件数数据。需要支付的金额数据。
- 渲染模版
落的代码:
- 准备数据
src/store/module/cart.js
// ... getters 代码
// 无效商品列表
invalidList (state) {
return state.list.filter(item => !(item.stock > 0 && item.isEffective))
},
// 选中商品列表
selectedList (state, getters) {
return getters.validList.filter(item => item.selected)
},
// 选中商品件数
selectedTotal (state, getters) {
return getters.selectedList.reduce((p, c) => p + c.count, 0)
},
// 选中商品总金额
selectedAmount (state, getters) {
return getters.selectedList.reduce((p, c) => p + (c.nowPrice * 100 * c.count), 0) / 100
},
// 是否全选
isCheckAll (state, getters) {
return getters.validList.length === getters.selectedList.length && getters.selectedList.length !== 0
}
渲染列表
<div class="cart">
<table>
<thead>
<tr>
+ <th width="120"><XtxCheckbox :modelValue="$store.getters['cart/isCheckAll']">全选</XtxCheckbox></th>
<th width="400">商品信息</th>
<th width="220">单价</th>
<th width="180">数量</th>
<th width="180">小计</th>
<th width="140">操作</th>
</tr>
</thead>
<!-- 有效商品 -->
<tbody>
+ <tr v-for="item in $store.getters['cart/validList']" :key="item.skuId">
+ <td><XtxCheckbox :modelValue="item.selected" /></td>
<td>
<div class="goods">
+ <RouterLink :to="`/product/${item.id}`">
+ <img :src="item.picture" alt="">
</RouterLink>
<div>
+ <p class="name ellipsis">{{item.name}}</p>
<!-- 选择规格组件 -->
+ <p class="attr">{{item.attrsText}}</p>
</div>
</div>
</td>
<td class="tc">
+ <p>¥{{item.nowPrice}}</p>
+ <p v-if="item.price-item.nowPrice>0">
比加入时降价
+ <span class="red">¥{{item.price-item.nowPrice}}</span>
</p>
</td>
<td class="tc">
+ <XtxNumbox :modelValue="item.count" />
</td>
+ <td class="tc"><p class="f16 red">¥{{item.nowPrice*100*item.count/100}}</p></td>
<td class="tc">
<p><a href="javascript:;">移入收藏夹</a></p>
<p><a class="green" href="javascript:;">删除</a></p>
<p><a href="javascript:;">找相似</a></p>
</td>
</tr>
</tbody>
<!-- 无效商品 -->
<tbody v-if="$store.getters['cart/invalidList'].length>0">
<tr><td colspan="6"><h3 class="tit">失效商品</h3></td></tr>
<tr v-for="item in $store.getters['cart/validList']" :key="item.skuId">
<td><XtxCheckbox style="color:#eee;" /></td>
<td>
<div class="goods">
<RouterLink :to="`/product/${item.id}`">
<img :src="item.picture" alt="">
</RouterLink>
<div>
<p class="name ellipsis">{{item.name}}</p>
<p class="attr">{{item.attrsText}}</p>
</div>
</div>
</td>
<td class="tc"><p>¥{{item.nowPrice}}</p></td>
<td class="tc">{{item.count}}</td>
<td class="tc"><p>¥{{item.nowPrice*100*item.count/100}}</p></td>
<td class="tc">
<p><a class="green" href="javascript:;">删除</a></p>
<p><a href="javascript:;">找相似</a></p>
</td>
</tr>
</tbody>
</table>
</div>
<!-- 操作栏 -->
<div class="action">
<div class="batch">
+ <XtxCheckbox :modelValue="$store.getters['cart/isCheckAll']">全选</XtxCheckbox>
<a href="javascript:;">删除商品</a>
<a href="javascript:;">移入收藏夹</a>
<a href="javascript:;">清空失效商品</a>
</div>
<div class="total">
+ 共 {{$store.getters['cart/validTotal']}} 件商品,已选择 {{$store.getters['cart/selectedTotal']}} 件,商品合计:
+ <span class="red">¥{{$store.getters['cart/selectedAmount']}}</span>
<XtxButton type="primary">下单结算</XtxButton>
</div>
</div>
08-购物车页面-单选操作-本地
目的:实现本地状态下的,选中商品操作。
大致步骤:
- 使用购物车商品修改信息的mutations(已实现)
- 定义购物车商品选中状态的actions
- 在购物车页面绑定单选的复选框change事件
- 在事件中调用actions的修改函数
落的代码:
- 定义修改购物车商品选中状态的mutations
src/store/module/cart.js
// 修改购物车商品
updateCart (state, goods) {
// goods中字段有可能不完整,goods有的信息才去修改。
// 1. goods中必需又skuId,才能找到对应的商品信息
const updateGoods = state.list.find(item => item.skuId === goods.skuId)
for (const key in goods) {
// 布尔类型 false 值需要使用
+ if (goods[key] !== null && goods[key] !== undefined && goods[key] !== '') {
updateGoods[key] = goods[key]
}
}
},
- 定义修改购物车商品的actions
src/store/module/cart.js
// 修改购物车商品
updateCart (ctx, goods) {
// goods 中:必须有skuId,其他想修改的属性 selected count
return new Promise((resolve, reject) => {
if (ctx.rootState.user.profile.token) {
// 登录 TODO
} else {
// 本地
ctx.commit('updateCart', goods)
resolve()
}
})
},
- 在购物车页面绑定单选的复选框change事件并处理选中
src/views/cart/index.vue
<td><XtxCheckbox @change="$event=>checkOne(item.skuId,$event)" :modelValue="item.selected" /></td>
import GoodRelevant from '@/views/goods/components/goods-relevant'
import { useStore } from 'vuex'
export default {
name: 'XtxCartPage',
components: { GoodRelevant },
setup () {
const store = useStore()
// 单选
const checkOne = (skuId, selected) => {
store.dispatch('cart/updateCart', { skuId, selected })
}
return { checkOne }
}
}
09-购物车页面-全选操作-本地
目的:实现本地状态下的,全选商品操作。
大致步骤:
- 修改购物车所有有效商品选中状态的actions
- 在购物车页面修改调用actions的代码
- 在购物车页面绑定全选的复选框change事件
- 在事件中调用actions的修改函数
落的代码
- 修改购物车商品选中状态的actions让其支持全选
src/store/module/cart.js
// 做有效商品的全选&反选
checkAllCart (ctx, selected) {
return new Promise((resolve, reject) => {
if (ctx.rootState.user.profile.token) {
// 登录 TODO
} else {
// 本地
// 1. 获取有效的商品列表,遍历的去调用修改mutations即可
ctx.getters.validList.forEach(item => {
ctx.commit('updateCart', { skuId: item.skuId, selected })
})
resolve()
}
})
},
- 在购物车页面修改调用actions的代码
src/views/cart/index.vue
// 全选
const checkAll = (selected) => {
store.dispatch('cart/checkAllCart', selected)
}
return { checkOne, checkAll }
- 在购物车页面绑定全选的复选框change事件并处理选中
src/views/cart/index.vue
<!-- 两处都需要加 -->
<XtxCheckbox @change="checkAll" :modelValue="$store.getters['cart/isCheckAll']">全选</XtxCheckbox>
10-购物车页面-删除操作-本地
目的:实现本地状态下,购物车商品删除
大致步骤:
- 绑定
删除
点击事件指定处理函数,调用删除actions - 处理无商品展示界面
落的代码:
- 绑定
删除
点击事件指定处理函数,调用删除actionssrc/views/cart/index.vue
<!-- 两处删除都绑定 -->
<p><a @click="deleteCart(item.skuId)" class="green" href="javascript:;">删除</a></p>
// 删除
const deleteCart = (skuId) => {
store.dispatch('cart/deleteCart', skuId)
}
return { checkOne, checkAll, deleteCart }
- 处理无商品展示界面
组件src/views/cart/components/cart-none.vue
<template>
<div class="cart-none">
<img src="@/assets/images/none.png" alt="" />
<p>购物车内暂时没有商品</p>
<div class="btn">
<XtxButton type="primary" @click="$router.push('/')">继续逛逛</XtxButton>
</div>
</div>
</template>
<script>
export default {
name: 'CartNone'
}
</script>
<style scoped lang="less">
.cart-none {
text-align: center;
padding: 150px 0;
background: #fff;
img {
width: 180px;
}
p {
color: #999999;
padding: 20px 0;
}
}
</style>
使用 src/views/cart/index.vue
+import XtxConfirm from '@/components/library/xtx-confirm'
import { useStore } from 'vuex'
export default {
name: 'XtxCartPage',
+ components: { GoodRelevant, CartNone },
<!-- 有效商品 -->
<tbody>
<tr v-if="$store.getters['cart/validList'].length===0">
<td colspan="6">
<CartNone />
</td>
</tr>