vue2-购物车小程序

本文介绍如何使用Vue2和ElementUI来构建一个购物车功能的小程序。内容涵盖Vue组件化开发,ElementUI组件应用,以及小程序中状态管理和数据交互的实现。
摘要由CSDN通过智能技术生成
<template>
	<view class="shopping">
		<GoodsItem :shappings="shappings" @shapcount="shapcounts" @checkss="checksss"  @checks="checkse"></GoodsItem>
		<view class="header">
			<view class="header-left">购物({{shappinglength}})</view>
			<view class="header-right">编辑</view>
		</view>
		<view style="width: 100%;height: 70px;float:left;"></view> 
		<!-- <GoodsItem :shappings="shappings" @shapcount="shapcount" @checkss="checkss"  @checks="checks"></GoodsItem> -->
		<view class="footer">
			<view class="footer-left">
				<checkbox class="check" @click="checkboxAll()" :checked="checkboxAlls">全选</checkbox>
			</view>
			<view class="footer-main" v-if="shappinglength2">
				合计:<text>{{shappricesum|currntprice}}</text>
			</view>
			<view class="footer-right" v-if="shappinglength2">
				<text @click="settlement">结算({{shappinglength2}})</text>
			</view>
		</view>
	</view>
</template>

<script>
	import { mapGetters, mapMutations, mapState ,mapActions} from 'vuex'
	import GoodsItem from "@/pages/components/GoodsItem.vue"
	export default {
		components: {
			GoodsItem
		},
		data() {
			return {
			}
		},
		methods: {
			...mapMutations({
				settlement:"settlement",
				checkboxAll:"checkboxAll",
				checks:"checks",
				shapcount:"shapcount",
				checkss:"checkss"
			}),
			...mapActions({
			}),
			//单选商品
			checksss(index, indexs) {
				this.checkss({index,indexs})
			},
			//数量增加
			shapcounts(index, indexs) {
				this.shapcount({index,indexs})
			},
			checkse(index){
				this.checks(index)
			},
			// //单选商品
			// checkss(index, indexs) {
			// 	this.shappings[index].goods[indexs].fas = !this.shappings[index].goods[indexs].fas
			// },
			//数量增加
			// shapcount(index, indexs) {
			// 	this.shappings[index].goods[indexs].count++;
			// },
			//一个店铺的全选
			// checks(index) {
			// 	this.shappings[index].fas = !this.shappings[index].fas
			// 	if (this.shappings[index].fas) {
			// 		this.shappings[index].goods.forEach(item => {
			// 			item.fas = true
			// 		})
			// 	} else {
			// 		this.shappings[index].goods.forEach(item => {
			// 			item.fas = false
			// 		})
			// 	}
			// },
			//单价折扣
			shapprice(price) {
				return price * 0.8
			},
			// //全选
			// checkboxAll() {
			// 	this.checkboxAlls = !this.checkboxAlls
			// 	if (this.checkboxAlls) {
			// 		this.shappings.forEach(item => {
			// 			item.fas = this.checkboxAlls
			// 			item.goods.forEach(itemss => {
			// 				itemss.fas = this.checkboxAlls
			// 			})
			// 		})
			// 	} else {
			// 		this.shappings.forEach(item => {
			// 			item.fas = this.checkboxAlls;
			// 			item.goods.forEach(itemss => {
			// 				itemss.fas = this.checkboxAlls
			// 			})
			// 		})
			// 	}
			// },
			// //结算
			// settlement() {
			// 	this.shappings.forEach(item => {
			// 		item.fas = !item.fas
			// 		item.goods.forEach(items => {
			// 			if (items.fas) {
			// 				items.fas = !items.fas
			// 			}
			// 		})
			// 	})
			// 	if (this.checkboxAlls) {
			// 		this.checkboxAlls = !this.checkboxAlls
			// 	}
			// }
		},
		computed: {
			...mapState({
				shappings:"shappings",
				checkboxAlls: "checkboxAlls",
			}),
			...mapGetters({
				shappinglength:"shappinglength",
				shappinglength2:"shappinglength2",
				shappricesum:"shappricesum"
			}),
			//商品总计数量
			// shappinglengths() {
				// var totalsum = 0;
				// this.shappings.forEach(item => {
				// 	item.goods.forEach(itemm => {
				// 		totalsum++;
				// 	})
				// })
				// return totalsum;
			// },
			//选择要订单的商品总计数量
			// shappinglength2() {
			// 	var total = 0;
			// 	this.shappings.some(item => {
			// 		item.goods.some(items => {
			// 			if (items.fas) {
			// 				total++;
			// 			}
			// 		})
			// 	})
			// 	return total;
			// },
			//选择要订单的商品的总价格
			// shappricesum() {
			// 	var sum = 0;
			// 	this.shappings.some(item => {
			// 		item.goods.some(items => {
			// 			if (items.fas) {
			// 				sum += this.shapprice(items.price) * items.count;
			// 			}
			// 		})
			// 	})
			// 	return sum;
			// }
		},
		filters: {
			//过渡价格
			currntprice(value) {
				if (!value) return "";
				value = parseFloat(value);
				return "¥" + value.toFixed(2);
			}
		}
	}
</script>

<style scope lang="less">
	@import "@/pages/messages/shopping.less";
	@import "@/pages/messages/style/info.css";
</style>
<template>
	<view>
		<view class="main" v-for="(shap,index) in shappings" :key="index">
			<view class="main-top">
				<view class="main-left">
					<checkbox class="check" @click="checks(index)" :checked="shap.fas"></checkbox>
				</view>
				<view class="main-main">
					{{shap.title}}
				</view>
				<view class="main-main-2">
					>
				</view>
				<view class="main-main-right">
					领券
				</view>
			</view>
			<view class="main-buttom" v-for="(sh,indexs) in shap.goods" :key="indexs">
				<view class="main-buttom-left">
					<checkbox class="check" :checked="sh.fas" @click="checkss(index,indexs)"></checkbox>
				</view>
				<view class="mian-buttom-img">
					<image :src="sh.imgUrl"></image>
				</view>
				<view class="main-buttom-main">
					<view class="main-buttom-main-1">
						{{sh.content}}
					</view>
					<view class="main-buttom-main-2">
						新品上新
					</view>
					<view class="main-buttom-main-3">
						<text class="price1">{{shapprice(sh.price)|currntprice}}</text>
						<text class="price2">{{sh.price|currntprice}}</text>
					</view>
				</view>
				<view class="main-buttom-right">
					<view class="iconfont icon-bianji"></view>
					<navigator url="#" @click="shapcount(index,indexs)">x{{sh.count}}</navigator>
				</view>
				<view style="clear: both;"></view>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		props: ['shappings'],
		methods: {
			//数量增加
			shapcount(index, indexs) {
				//子组件直接调用父组件的方法,并且传递参数
				// this.$parent.shapcount(index, indexs)
				this.$emit('shapcount',index,indexs)
			},
			//单选商品
			checkss(index, indexs) {
				//子组件直接调用父组件的方法,并且传递参数
				// this.$parent.checkss(index, indexs)
				this.$emit("checkss",index,indexs)
			},
			checks(index) {
				//子组件直接调用父组件的方法,并且传递参数
				// this.$parent.checks(index)
				this.$emit("checks",index)
			},
			//单价折扣
			shapprice(price) {
				//子组件直接调用父组件的方法,并且传递参数
				return this.$parent.shapprice(price)
			}
		}
	}
</script>
import Vue from 'vue'
import Vuex from 'vuex'
// import createPersistedState from "vuex-persistedstate"

Vue.use(Vuex)


export default new Vuex.Store({
	state: {
		checkboxAlls: false,
		shappings: [{
				id: 1,
				title: "阿蒙家的饭",
				fas: false,
				goods: [{
						content: "香辣牛肉入骨葱香爆炒外焦里嫩味道纯正鲜美",
						imgUrl: require('@/pages/messages/img/1.webp'),
						price: 59,
						count: 1,
						fas: false
					},
					{
						content: "香辣牛肉入骨葱香爆炒外焦里嫩味道纯正鲜美",
						imgUrl: require('@/pages/messages/img/1.webp'),
						price: 59,
						count: 1,
						fas: false
					},
					{
						content: "香辣牛肉入骨葱香爆炒外焦里嫩味道纯正鲜美",
						imgUrl: require('@/pages/messages/img/1.webp'),
						price: 59,
						count: 1,
						fas: false
					},
					{
						content: "香辣牛肉入骨葱香爆炒外焦里嫩味道纯正鲜美",
						imgUrl: require('@/pages/messages/img/1.webp'),
						price: 59,
						count: 1,
						fas: false
					},
				]
			},
			{
				id: 2,
				title: "美味一品香",
				fas: false,
				goods: [{
					content: "儒酱鸭肉香辣入骨葱香肉质佳味道纯正鲜美",
					imgUrl: require('@/pages/messages/img/1.webp'),
					price: 78,
					count: 1,
					fas: false
				}, {
					content: "儒酱鸭肉香辣入骨葱香肉质佳味道纯正鲜美",
					imgUrl: require('@/pages/messages/img/1.webp'),
					price: 78,
					count: 1,
					fas: false
				}]
			},
			{
				id: 3,
				title: "呦呦乐面包",
				fas: false,
				goods: [{
					content: "巧克力面包色香味俱全香浓巧克力蓬松奶油",
					imgUrl: require('@/pages/messages/img/1.webp'),
					price: 69,
					count: 1,
					fas: false
				}]
			},
			{
				id: 4,
				title: "川香火锅店",
				fas: false,
				goods: [{
						content: "巧克力面包色香味俱全香浓巧克力蓬松奶油",
						imgUrl: require('@/pages/messages/img/1.webp'),
						price: 69,
						count: 1,
						fas: false
					},
					{
						content: "巧克力面包色香味俱全香浓巧克力蓬松奶油",
						imgUrl: require('@/pages/messages/img/1.webp'),
						price: 69,
						count: 1,
						fas: false
					},
					{
						content: "巧克力面包色香味俱全香浓巧克力蓬松奶油",
						imgUrl: require('@/pages/messages/img/1.webp'),
						price: 69,
						count: 1,
						fas: false
					}
				]
			},

		]
	},
	//计算属性
	getters: {
		//购物车商品总数量
		shappinglength(state) {
			var sum = 0;
			state.shappings.forEach(item => {
				item.goods.forEach(items => {
					sum++;
				})
			})
			return sum;
		},
		//选择要购买的商品总数量
		shappinglength2(state) {
			var sum = 0;
			state.shappings.forEach(item => {
				item.goods.forEach(items => {
					if (items.fas) {
						sum++;
					}
				})
			})
			return sum;
		},
		//选择要订单的商品的总价格
		shappricesum(state) {
			var sum = 0;
			state.shappings.forEach(item => {
				item.goods.forEach(items => {
					if (items.fas) {
						sum += (items.price * 0.8) * items.count;
					}
				})
			})
			return sum;
		}
	},
	//方法同步
	mutations: {
		//单选商品
		//注意多个参数需要用大括号
		checkss(state, {
			index,
			indexs
		}) {
			state.shappings[index].goods[indexs].fas = !state.shappings[index].goods[indexs].fas
		},
		//一个商品的数量
		//注意多个参数需要用大括号
		shapcount(state, {
			index,
			indexs
		}) {
			state.shappings[index].goods[indexs].count++;
		},
		//一个店铺的全选
		checks(state, index) {
			state.shappings[index].fas = !state.shappings[index].fas;
			if (state.shappings[index].fas) {
				state.shappings[index].goods.forEach(item => {
					item.fas = state.shappings[index].fas
				})
			} else {
				state.shappings[index].goods.forEach(item => {
					item.fas = state.shappings[index].fas
				})
			}

		},
		//购物车的结算
		settlement(state) {
			state.shappings.forEach(item => {
				item.fas = !item.fas;
				item.goods.forEach(items => {
					if (items.fas) {
						items.fas = !items.fas;
					}
				})
			})
			if (state.checkboxAlls) {
				state.checkboxAlls = !state.checkboxAlls
			}
		},
		//全选
		checkboxAll(state) {
			state.checkboxAlls = !state.checkboxAlls;
			if (state.checkboxAlls) {
				state.shappings.forEach(item => {
					item.fas = state.checkboxAlls
					item.goods.forEach(items => {
						items.fas = state.checkboxAlls
					})
				})
			} else {
				state.shappings.forEach(item => {
					item.fas = state.checkboxAlls
					item.goods.forEach(items => {
						items.fas = state.checkboxAlls
					})
				})
			}
		}
	},
	//对mutations的包裹 异步
	actions: {
		checkses({
			commit
		}, id) {
			commit('checks', id)
		}
	},
	//模块化
	modules: {

	},
	// plugins: [createPersistedState()]
})
export function currntprice(value) {
	if (!value) return "";
	value = parseInt(value);
	return "¥" + value.toFixed(2);
}
import App from './App'
//一定要加大括号
import {currntprice} from "@/pages/filters/filters.js"
import store from '@/pages/store/index.js' 

Vue.prototype.$store = store

// #ifndef VUE3
import Vue from 'vue'
Vue.filter('currntprice',currntprice)


Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
	store,
    ...App
})
app.$mount()
// #endif

// #ifdef VUE3
import { createSSRApp } from 'vue'
export function createApp() {
  const app = createSSRApp(App)
  return {
    app
  }
}
// #endif

.shopping{
	background-color: #ececec;
	overflow: hidden;
	display: flex;
	flex-direction: column;
			// flex-wrap: nowrap;
	height: 100%;
	.header{
		background-color: rgb(255, 123, 0);
		width: 100%;
		height: 40px;
		color: white;
		line-height: 35px;
		font-size: 16px;
		position: fixed;
		top: 0;
		// flex: 0 0 100rpx;
		flex-direction: row;
		flex-wrap: nowrap;
		.header-left{
			float:left;
			width: 70%;
			text-align: center;
			padding-left: 40px;
		}
		.header-right{
			flex: 15%;
			text-align: center;
		}
	}
	.main{
		flex: 1;
		// display: flex;
		position: relative;
		top: 40px;
		// border:1px solid red;
		// overflow: auto;
		margin-bottom: 10px;
		height: 90%;
		// background-color: white;
		  // padding-bottom: calc(var(--window-bottom) + 70px);
		.main-top{
					// position: absolute;
			float: left;
			height: 30px;
			line-height: 30px;
			padding-bottom: 4px;
			border-bottom: 1px solid #ccc;
			.main-left{
				// flex: 3%;
				float: left;
				width: 30px;
				padding-left: 5px;
			}
			.main-main{
				// flex: 10%;
				float: left;
				width: 90px;
				letter-spacing: 2px;
			}
			.main-main-2{
				// flex: 10%;
				float: left;
				width: 155px;
				// border: 1px solid red;
			}
			.main-main-right{
				float:left;
				width: 30px;
				color:rgb(255, 123, 0) ;
				font-size: 13px;
			}
		}
		.main-buttom{
			background-color: white;
			.main-buttom-left{
				margin-top: 10px;
				float: left;
				width: 30px;
				padding-left: 5px;
				line-height: 80px;
				// margin-bottom: 10px;
			}
			.mian-buttom-img{
				margin-top: 10px;
				float: left;
				width: 80px;
				height: 80px;
				>image{
					width: 80px;
					height: 80px;
				}
			}
			.main-buttom-main{
				margin-bottom: 10px;
				margin-top: 10px;
				float: left;
				width: 160px;
				padding-left: 5px;
				.main-buttom-main-1{
				    font-size: 14px;
				}
				.main-buttom-main-2{
					 font-size: 10px;
					 width: 60px;
					 background-color: red;
					 border-radius: 5px;
					 text-align: center;
					 color: white;
					 margin-top: 5px;
					 margin-bottom: 5px;
				}
				.main-buttom-main-3{
					.price1{
						margin-right: 10px;
						color: rgb(255, 123, 0);
						font-weight: bold;
					}
					.price2{
						color: #ccc;
						text-decoration: line-through;
					}
				}
			}
			.main-buttom-right{
				width: 20px;
				float: left;
				padding-top: 0px;
				padding-left: 7px;
				font-size: 13px;
				color: #ccc;
				.icon-bianji{
					height: 75px;
					line-height: 80px;
					
				}
			}
		}
	}
	.footer{
		display: flex;
		line-height: 35px;
		position: fixed;
		bottom: 0;
		width: 100%;
		background-color: white;
		height: 40px;
		flex: 0 0 100rpx;
		.footer-left{
			float: left;
			width: 75px;
			padding-left: 5px;
		}
		.footer-main{
			float: left;
			width: 150px;
			text-align: right;
			font-size:12px;
			line-height: 35px;
			// border:1px solid red;
			padding-right: 20px;
			>text{
				font-size: 20px;
				color:rgb(255, 123, 0);
			}
		}
		.footer-right{
			float: left;
			width: 80px;
			height: 40px;
			background-color: rgb(255, 123, 0) ;
			color: white;
			text-align: center;
			border-radius: 20px;
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值