1:因为此前erp项目中的采购模块添加商品,实时计算单个商品预估价格及全部商品总额折磨了我很久,所以今天闲来无事优化一下,使用另一种思维来做一个类似demo,作为此前总结反思
2:原来项目模块是这样的
3:demo案列如下
父组件app.vue
<script setup>
import { ref,computed } from 'vue'
import goods from './goods.vue'
let goodsList=ref([])
let goodsName=['苹','果','香','焦','桃','子','西','瓜','黄','冬']
const addGoods=()=>{
goodsList.value.push({id:Math.random(),name:goodsName[Math.floor(Math.random()*10)],inputPrice:'',computedPrice:'',qty:'1',})
}
let total=computed(()=>{
return goodsList.value.reduce((total,item)=>total+item.computedPrice,0)
})
</script>
<template>
<div>
<div v-for="(item,index) in goodsList" :key="item.id">
<goods v-model:goodsList="goodsList" v-model:goodsItem="goodsList[index]" />
</div>
<div>商品总价:{{ total }}</div>
</div>
<div style="text-align: center;width: 300px;">
<span @click="addGoods">添加商品+</span>
</div>
</template>
子组件goods.vue
<script setup>
import {computed} from 'vue'
const goodsList = defineModel('goodsList')
const goodsItem = defineModel('goodsItem')
goodsItem.value.computedPrice=computed(()=>goodsItem.value.inputPrice*goodsItem.value.qty)
const deleteGoods=()=>{
let index=goodsList.value.findIndex((item)=>item.id==goodsItem.value.id)
goodsList.value.splice(index,1)
}
</script>
<template>
<div class="goods">
<div class="deleteGoods" @click="deleteGoods">-</div>
<div class="head">
<div class="title">商品名:{{ goodsItem.name }}</div>
<div class="number">
<div class="jian" @click="goodsItem.qty>1&&goodsItem.qty--">-</div>
<input v-model="goodsItem.qty"/>
<div class="jia" @click="goodsItem.qty++">+</div>
</div>
</div>
<div class="main">
<input placeholder="请输入价格" v-model="goodsItem.inputPrice"/>
</div>
<div class="footer">
<div v-if="goodsItem.computedPrice">
<span>商品价格:</span>
<span>{{ goodsItem.computedPrice }}</span>
</div>
</div>
</div>
</template>
<style>
.goods{
width: 300px;
border: 1px solid red;
padding: 10px;
margin-top: 20px;
position: relative;
.deleteGoods{
width: 30px;
height: 30px;
border-radius: 50%;
background-color: #ccc;
text-align: center;
position: absolute;
top: -15px;
right: -15px;
}
.head{
display: flex;
justify-content: space-between;
margin-bottom: 20px;
.number{
display: flex;
.jian,.jia{
width: 30px;
text-align: center;
font-weight: 700;
border: 1px solid #ccc;
}
input{
width: 50px;
}
}
}
.main{
width: 290px;
margin-bottom: 10px;
input{
width: 100%;
}
}
.footer{
}
}
</style>
页面效果如下
如有任何疑问,欢迎在评论区提出,谢谢阅读