这个购物车功能相对简单,路由控制进入home页(商品列表页),添加商品后,cart页(购物车页)链接后会显示加入商品数量。进入cart页会列出添加的商品,可加减数量、删除单个商品、清空购物车。

vue购物车


  • 项目目录
    这里写图片描述

router.js 路由引入…/page/目录下页面

import App from '../App'
import Home from '../page/home'
import Cart from '../page/cart'

export default [{
    path: '/',
    component: App,
    children: [{
        path: '/',
        component: Home
    }, {
        path: '/cart',
        component: Cart
    }]
}]

layout.vue

<template>
  	<div>
  		<el-container>
		  	<el-aside width="200px">
		  		<el-menu router :default-active="$route.path" class="el-menu-vertical-demo nav">
		      		<el-menu-item index="/">
			        	<i class="el-icon-menu"></i>
			        	<span slot="title">home</span>
			      	</el-menu-item>
			      	<el-menu-item index="/cart">
			        	<i class="el-icon-goods"></i>
			        	<span slot="title">
			        		cart
			        		<el-badge class="mark" v-if="totalNum" :value="totalNum" />
			        	</span>
			      	</el-menu-item>
			    </el-menu>
		  	</el-aside>
		  	<el-main>
		  		<el-tag v-if="page == 'home'">商品列表</el-tag>
		  		<el-tag v-if="page == 'cart'">购物车</el-tag>
				<Goods v-if="page == 'home'"></Goods>
				<Cart v-if="page == 'cart'"></Cart>
		  	</el-main>
		</el-container>
    </div>
</template>
<script>
	import { mapState, mapGetters, mapActions } from 'vuex'
	import Goods from './goods'
	import Cart from './cart'
	
	export default {
		name: 'layout',
		props:['page'],
		components: {
	    	Goods,
	    	Cart
	  	},
		computed:{
			...mapGetters([
				'goodList','totalNum'
			])
		},
		methods: {
			...mapActions(['addToCart'])
	    }
	}
</script>

<style scoped>
</style>
  • 通过 <el-menu> 组件的 router 和 :default-active="$route.path" 属性加上路由功能
  • 通过 <el-menu-item> 组件的 index 映射 url 地址
  • <el-main> 组件部分通过 layout 父组件的 page 参数值进行 v-if 条件渲染

goods.vue
<template>
	<el-table :data="goodList" style="width: 100%">
	    <el-table-column prop="id" label="商品ID" width="180"></el-table-column>
	    <el-table-column prop="name" label="商品名称" width="180"></el-table-column>
	    <el-table-column prop="price" label="单价" width="180"></el-table-column>
	    <el-table-column label="操作">
	    	<template slot-scope="scope">
		        <el-button size="mini" type="primary" icon="el-icon-plus" @click="addToCart( scope.row )">加入购物车</el-button>
		    </template>
	    </el-table-column>
	</el-table>
</template>

<script>
	import { mapState, mapGetters, mapActions } from 'vuex'
	export default {
		name: 'goods',
		computed:{
			...mapGetters([
				'goodList','totalNum'
			])
		},
		methods: {
			...mapActions(['addToCart'])
	    }
	}
</script>

<style scoped>
</style>
  • 商品列表页面,加入购物车按钮的事件 addToCart 绑定的是 action.js 中 注册的 ADD_TO_CART 事件,这里传的参数 (scope.row) 是对应这一行的数据,包括这一条商品id,商品名称,单价
  • 这里的 <el-badge class="mark" v-if="totalNum" :value="totalNum" /> 绑定的是点击加入购物车按钮后的购物车商品数量总数

cart.vue
<template>
	<div>
		<el-table :data="cartProducts" style="width: 100%">
		    <el-table-column prop="id" label="商品ID" width="180"></el-table-column>
		    <el-table-column prop="name" label="商品名称" width="180"></el-table-column>
		    <el-table-column label="数量" width="180">
		    	<template slot-scope="scope">
					<el-input-number size="mini" :min="1" :value="scope.row.num" v-on:input="handleBlur" @change="handleChange( scope.row )"></el-input-number>
		    	</template>
		    </el-table-column>
		    <el-table-column prop="price" label="单价" width="180"></el-table-column>
		    <el-table-column prop="total_num" label="总价" width="180"></el-table-column>
		    <el-table-column label="操作" width="180">
		    	<template slot-scope="scope">
			        <el-button type="danger" plain icon="el-icon-delete" size="mini" @click="dialogVisibleTrue( scope.row )">删除</el-button>
			    </template>
		    </el-table-column>
		</el-table>

		<Info v-if="totalNum"></Info>

		<el-dialog title="注意" :visible.sync="dialogVisible" width="20%">
		  	<span>确定要删除这个商品吗?</span>
		  	<span slot="footer" class="dialog-footer">
		    	<el-button @click="dialogVisible = false">取 消</el-button>
		    	<el-button type="primary" @click="dialogSure">确 定</el-button>
		  	</span>
		</el-dialog>
	</div>
  	
</template>

<script>
	import { mapState, mapGetters, mapActions } from 'vuex'
	import Info from './info'
	
	export default {
		name: 'cart',
	  	data() {
			return {
				dialogVisible : false,
				result : null,
				input_number_value:1
			}
		},
		computed:{
			...mapGetters([
				'cartProducts','totalNum'
			])
		},
		components: {
	    	Info
	  	},
		methods: {
			...mapActions(['delProduct','numChange']),
			dialogVisibleTrue( data ){
				this.dialogVisible = true;
				this.result = data;
			},
			dialogSure(){
				this.delProduct( this.result );
	        	this.dialogVisible = false;
	      	},
	      	handleBlur(value){
	      		this.input_number_value = value
	      	},
	      	handleChange( data ) {
	        	data.value = this.input_number_value;
	        	this.numChange( data );
	      	}
	    }
	}
</script>

<style scoped>
	.el-table th>.cell{text-align: center;}
	.el-table td>.cell{text-align: center;}
</style>

  • <el-input-number>是控制单个商品数量加减的组件, :value=“scope.row.num” 属性绑定value值,v-on:input=“handleBlur” 属性通过handleBlur方法将数量单独存储在 data 的 input_number_value 值中,@change=“handleChange( scope.row )” 将change事件绑定handleChange方法,而 handleChange 方法里调用 action.js 中注册的 numChange 事件,给 numChange 传的参数中,data.value 是 data 中临时存放的 input_number_value 的值。
  • 删除按钮是删除对应的一条数据,实现上,类似加入购物车的功能,这里加了一个弹出层<el-dialog>,询问是否要删除
  • 这个页面引入一个组件 info.vue 用来显示购物车商品总数量、总价和清空购物车按钮



    info.vue
<template>
	<div>
		<el-row :gutter="20">
		  	<el-col :span="6">总数:{{totalNum}}</el-col>
		  	<el-col :span="6">合计价格:{{totalPrice}}</el-col>
		  	<el-col :span="6">
		  		<el-button type="danger" size="medium" icon="el-icon-delete" @click="dialogDeleteAll">清空购物车</el-button>
		  	</el-col>
		  	<el-col :span="6"></el-col>
		</el-row>

		<el-dialog title="注意" :visible.sync="dialogVisible" width="20%">
		  	<span>要清空购物车吗?</span>
		  	<span slot="footer" class="dialog-footer">
		    	<el-button @click="dialogVisible = false">取 消</el-button>
		    	<el-button type="primary" @click="dialogSure">确 定</el-button>
		  	</span>
		</el-dialog>
	</div>
  	
</template>

<script>
	import { mapState, mapGetters, mapActions } from 'vuex'
	
	export default {
		name: 'info',
	  	data() {
			return {
				dialogVisible : false
			}
		},
		computed:{
			...mapGetters(['totalPrice','totalNum'])
		},
		methods: {
			...mapActions(['clearAllCart']),
			dialogDeleteAll( data ){
				this.dialogVisible = true;
			},
			dialogSure(){
				this.clearAllCart();
	        	this.dialogVisible = false;
	      	}
	    }
	}
</script>

<style scoped>
	.el-col-6{padding: 20px; text-align: center;}
</style>
  • 清空购物车按钮就是清空 vuex 中 added 数组

项目地址: https://github.com/sonicwater/vue-element-ul-cart

Logo

前往低代码交流专区

更多推荐