uinapp项目+vue3+pinia,将商品加入购物车

197 阅读1分钟

uinapp项目+vue3+pinia,将商品加入购物车

先写一个商品卡片组件

<template>
  <view class="nb-card" >
    <view class="shopping_box">
      <view v-if="isSelect">
        <checkbox-group @change="radioChange">
          <label>
            <checkbox color="#e4020e" :value="item" style="border-radius: 50%;" value="cb" :checked="checkedSelect"/>
          </label>
        </checkbox-group>
      </view>
      <view>
        <image style="width: 100px; height: 100px;border-radius: 10px"
               :src="item.cover"></image>
      </view>

<!--      右边-->
      <view class="right" >
        <view class="title">
          {{ item?.title }}
        </view>

        <view class="description">任选2-3杯~具体饮品温度请备注~</view>

        <view class="discount" >
          <view >限时特价</view>
        </view>

<!--底部-->
        <view style="margin-top: 10px">
          <view style="display: flex;justify-content: space-between;width: 100%">
            <view>
              <text style="font-size: 12px"></text>
              <text style="font-size: 16px">{{ item.minPrice }}</text>
            </view>
            <view class="addOrDelete">
              <view class="my-circle" @click.stop="delete_shopping">-</view>
              <view style="border: 1px  blue;width: 30px" @click.stop="">
                <text>{{ commoditySize(item.id) }}</text>
              </view>
              <view class="my-circle" @click.stop="add_shopping">+</view>
            </view>
          </view>
        </view>

      </view>
    </view>
  </view>
</template>

<script lang="ts" setup>
import {ref} from "vue";
import {useCommodityStore} from "@/store/modules/CommodityStore";
const emits = defineEmits(['click'])
const props = withDefaults(defineProps<{
  treeTagId?: string,
  item?: any,
  isSelect?: Boolean,
}>(), {
  treeTagId: "",
  item: {
    title: "6666",
    cover: "https://img2.baidu.com/it/u=3088885732,2641299430&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500",
    minPrice: "999",
    isSelect: false,
    id: ""
  }
})
// 放进缓存
const commodity = useCommodityStore()
function goClick() {
  emits('click')
}
//添加
async function add_shopping() {
  await commodity.joinChart({id: props.item.id, action: "up"})
  const data = commodity.getInfo(props.item.id)
}
function commoditySize(id: any) {
  const data = commodity.getInfo(id)
  return data?.size || 0
}
// 删除
function delete_shopping() {
  commodity.joinChart({id: props.item.id, action: "down"})
}
const checkedSelect = ref<boolean>(false)
async function radioChange(value: any) {
  checkedSelect.value = !checkedSelect.value
  console.log(value.detail.value, commoditySize(props.item.id));//选择的东西和数量
  if (checkedSelect.value) {
    const info = useCommodityStore().info;
    info[props.item.id].flag = true;
  } else {
    const info = useCommodityStore().info;
    info[props.item.id].flag = false;
  }

}


</script>

<style scoped lang="scss">
.shopping_box {
  display: flex;
  justify-content: space-between;
  align-items: center;
  text-align: center;
}

.right {
  flex: 1 1 auto;
  height: 100%;
  margin-left: 10px;
  justify-content: space-between;
  flex-direction: column;

}

.my-circle {
  border: 1px solid;
  border-radius: 50%;
  height: 20px;
  width: 20px;
  line-height: 15px;
  text-align: center;
  background-color: #e4020e;
  color: #fff;
}

.title {
  font-size: 14px;
  text-align: left;
  color: #393939;
  font-weight: 1000;
  font-family: 宋体;
}

.description {
  text-align: start;
  font-size: 10px;
  color: #a9a9a9;
  margin-top: 8px;
}

.discount {
  display:flex;
  margin-top: 8px;
  &>view{
     padding: 5px 10px;
     font-size: 10px;
     color: #a9a9a9;
     border: #df5e62 1px solid;
     border-radius: 3px;
   }
}

.addOrDelete {
  display: flex;
  margin-right: 10px;
  background-color: #f3f4f6;
  border-radius: 30px;
}
</style>

先定义一个pinia缓存

import {defineStore} from "pinia";

export const commodityStore = defineStore('commodity', {
    state: (): {
        info: {
            [key: string]: {
                id: string
                size: number
            }
        }
    } => ({
        info: {}
    }),
    getters: {},
    actions: {
        joinChart(data: {
            id: string,
            action: 'up' | 'down'
        }) {
            if (!this.info[data.id]) {
                this.info[data.id] = {
                    id: data.id,
                    size: 0
                }
            }
            if (data.action === 'up') {
                this.info[data.id].size++
            } else {
                this.info[data.id].size--
            }

            if (this.info[data.id].size <= 0) {
                delete this.info[data.id]
            }
            this.info = {
                ...this.info
            }
        },

        getInfo(id: any) {
            return this.info[id]
        },
        getInfoList():Object{
            return this.info
        }


    }
})

将商品加入缓存的部分 (卡片里面已经包含此部分)

//在页面使用
//加入购物车
async function add_shopping() {
  await commodity.joinChart({id: props.item.id, action: "up"})
  const data = commodity.getInfo(props.item.id)
}
//移除购物车
function delete_shopping() {
  commodity.joinChart({id: props.item.id, action: "down"})
}


在购物车中给购物车加入选择(卡片里面已经包含此部分)

<view v-if="isSelect">
        <checkbox-group @change="radioChange">
          <label>
            <checkbox color="#e4020e" :value="item" style="border-radius: 50%;" value="cb" 							:checked="checkedSelect"/>
          </label>
       </checkbox-group>
</view>

//选中的方法
const checkedSelect = ref<boolean>(false)
async function radioChange(value: any) {
  checkedSelect.value = !checkedSelect.value
  console.log(value.detail.value, commoditySize(props.item.id));//选择的东西和数量
  if (checkedSelect.value) {
    const info = useCommodityStore().info;
    info[props.item.id].flag = true;
  } else {
    const info = useCommodityStore().info;
    info[props.item.id].flag = false;
  }
}


我们在引用组件的页面写一个apiSubmit事件---去结算

//加入了购物车的商品list
const list = ref<ShoppingCartItem[]>([])

//从商品list中过滤,选中的才放进去,得到的form就是去生成订单的参数
async function apiSubmit() {
  const _list = list.value.filter(o => o.flag);
  const form = {
    list: _list.map(o => {
      return {
        id: o.id,
        size: o.size
      }
    })
  }
  //我们已经得到了选中的商品,然后将这些商品去生成订单------这儿用你们自己的api
  const {data} = await commodityApi.commodity.torderCreate({
    ...form
  })
  form1.value.value = data.totalPrice
  await apiPayment(data.torderId)
}