目录
- 购物车小案例的实现
- 思路:
- 1.首先我们要知道购物车的样子是什么样的吧
- 2.再把他的内容分为两个组件写出来然后进行渲染
- 3.页面写好之后我们开始书写功能
- 4.分析他的功能先写添加进入购物车和删去
- 5.全选全不选
- 6.计算总价
购物车小案例的实现
思路:
1.首先我们要知道购物车的样子是什么样的吧
2.再把他的内容分为两个组件写出来然后进行渲染
App页
<script>
// 引入产品组件
import ProductVue from './components/Product.vue'
// 引入汇总组件
import CollectVue from './components/Collect.vue'export default {components: { ProductVue, CollectVue },data: () => ({// 购物车信息shopCar: [{id: 89,title: '四川爱媛38号果冻橙 当季时令应季彩箱装甜桔橘子新鲜水果专区 净重2斤小果尝鲜装(力荐大果,口感更好更实惠)',subtitle: '由初逐旗舰店从 四川眉山市 发货, 并提供售后服务. 现在至明日17:00前完成下单,预计11月15日19:30前发货',image: 'https://img12.360buyimg.com/n1/jfs/t1/39198/22/19565/188868/634a3bc4Ea15f2eee/2bb232b36cdd285c.jpg',price: 10,count: 1,selected: false},{id: 102,title: '【现货速发】新鲜四季青柠檬 无籽香水柠檬当季生鲜小青柠檬奶茶店水果 有籽青柠檬1斤装试吃【50-80克】',subtitle: '由朵艾美水果旗舰店发货, 并提供售后服务. 现在至明日16:00前完成下单,预计11月16日23:30前发货',image: 'https://img12.360buyimg.com/n1/jfs/t1/191077/5/6346/108268/60beea0dEc3a6d2ad/15db7dd619a0bc4f.jpg',price: 9,count: 3,selected: true},{id: 108,title: '新疆阿克苏冰糖心苹果 新鲜时令水果 阿克苏苹果红富士 10斤礼盒装 单果75-85mm 净重9斤多',subtitle: '由阿克苏苹果旗舰店发货, 并提供售后服务. 现在至明日16:00前完成下单,预计11月16日20:30前发货',image: 'https://img13.360buyimg.com/n1/jfs/t1/64647/33/22918/106322/6360afb1E9bab1003/a82bda0aeae6e953.png',price: 80,count: 2,selected: false}]}),methods: {// 产品的状态发生改变changeShopCarProductChecked(checked, id) {// 循环购物车中的每个产品this.shopCar.some(product => {// 判断更改的是哪一个产品的 checked 状态if (id === product.id) {product.selected = checked // 改变购物车中指定产品的选中的值return true // 结束循环}})},// 产品数量更改changeShopCarProductCount(count, id) {// 循环购物车中的每个产品this.shopCar.some(product => {// 判断更改的是哪一个产品的 checked 状态if (id === product.id) {product.count += count // 改变购物车中指定产品的数量return true // 结束循环}})},// 改变购物车所有产品的选中状态changeShopCarAllProductCheckedState(checked) {this.shopCar.forEach(product => product.selected = checked)}},computed: {// 是否全选购物车产品isFullSelecteProduct() {return this.shopCar.every(product => product.selected)},// 总金额total() {return this.shopCar.filter(item => item.selected) // 过滤掉被选中得产品.reduce((money, item) => (money += item.price * item.count), 0) // 累加器},// 购买总数量countSum() {return this.shopCar.filter(item => item.selected) // 过滤掉被选中得产品.reduce((count, item) => (count += item.count), 0) // 累加器}}
}
</script><template><!-- 产品组件 --><ProductVue v-for="product in shopCar" :key="product.id" :id="product.id" :picture="product.image":title="product.title" :subtitle="product.subtitle" :price="product.price" :count="product.count":is-checked="product.selected" @change-product-checked="changeShopCarProductChecked"@change-product-count="changeShopCarProductCount" /><hr><!-- 使用汇总组件 --><CollectVue :is-all-checked="isFullSelecteProduct" :all-money="total" :all-count="countSum"@change-all-checked-state="changeShopCarAllProductCheckedState" />
</template><style>
* {margin: 0;padding: 0;
}
</style>
内容页(ProductVue )
<script>
export default {// 声明组件的自定义属性props: {id: { type: Number, required: true }, // 产品编号isChecked: Boolean, // 是否被选中picture: { type: String, required: true }, // 图像title: { type: String, required: true }, // 标题subtitle: { type: String, required: true }, // 副标题price: { type: Number, defalut: 0 }, // 单价count: { type: Number, defalut: 0 } // 数量 },// 自定义事件emits: ['changeProductChecked', // 改变复选框的状态事件'changeProductCount' // 改变产品数量],methods: {// 改变产品选中的状态changeCheckedState(e) {let newCheckedState = e.target.checked // 复选框最新的状态this.$emit('changeProductChecked', newCheckedState, this.$props.id) // 触发自定义的事件,并传值给父组件}}
}
</script><template><!-- 产品容器 --><div class="box"><!-- 选项框 --><input type="checkbox" class="p_checkbox" :checked="isChecked" @change="changeCheckedState"><!-- 产品图 --><img class="p_image" :src="picture"><!-- 产品内容 --><div class="p_content"><!-- 标题 --><h3 class="p_title" v-text="title"></h3><!-- 副标题 --><span class="p_subtitle" v-text="subtitle"></span><!-- 价格 --><h2 class="p_price">¥ {{ price }}</h2><!-- 产品数量区域 --><div class="p_count_area"><button :disabled="count <= 1" @click="$emit('changeProductCount', -1, id)">-</button><!-- 购买数量 --><span v-text="count"></span><button @click="$emit('changeProductCount', 1, id)">+</button></div></div></div>
</template><style>
.box {box-shadow: 0 0 8px gray;padding: 20px;margin: 15px;display: flex;align-items: center;
}.p_checkbox {width: 25px;height: 25px;
}.p_image {width: 120px;height: 120px;margin: 0 20px;
}.p_content {align-self: start;position: relative;width: 100%;
}.p_title {margin-bottom: 8px;
}.p_subtitle {font-size: 14px;color: gray;
}.p_price {margin-top: 20px;color: rgb(201, 67, 67);
}.p_count_area {position: absolute;bottom: 0;right: 0;
}.p_count_area button {width: 25px;height: 25px;
}.p_count_area span {margin: 0 10px;
}
</style>
汇总页(Collect.vue)
<script>
export default {// 自定义属性props: {isAllChecked: Boolean, // 是否全选allMoney: { type: Number, default: 0 }, // 总金额allCount: { type: Number, default: 0 } // 总个数},// 自定义事件emits: ['changeAllCheckedState' // 改变全选状态的事件]
}
</script><template><div class="container"><!-- 全选 --><label><input type="checkbox" :checked="isAllChecked"@change="$emit('changeAllCheckedState', $event.target.checked)">全选</label><!-- 总金额 --><span>合计金额:<strong>¥ {{ allMoney }}</strong></span><!-- 结算按钮 --><button>结算【 {{ allCount }} 】</button></div>
</template><style>
.container {padding: 20px;margin: auto 15px;display: flex;justify-content: space-between;align-items: center;
}.container input {width: 25px;height: 25px;
}.container label {display: flex;align-items: center;width: 70px;justify-content: space-between;
}.container strong {color: red;
}.container button {border: none;padding: 15px 25px;background-color: rgb(50, 140, 192);color: white;border-radius: 8px;box-shadow: 0 0 5px gray;
}
</style>
3.页面写好之后我们开始书写功能
4.分析他的功能先写添加进入购物车和删去
5.全选全不选
6.计算总价
为了方便大家详细的看功能就不分批写啦,全在组件里,大家如果想验证的话可以直接用