vue + vuex + element-ui 购物车

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

vue + vuex + element-ui 购物车_第1张图片


  • 项目目录
    vue + vuex + element-ui 购物车_第2张图片

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">homespan>
			      	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>
  • 通过 组件的 router 和 :default-active="$route.path" 属性加上路由功能
  • 通过 组件的 index 映射 url 地址
  • 组件部分通过 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,商品名称,单价
  • 这里的 绑定的是点击加入购物车按钮后的购物车商品数量总数

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>

  • 是控制单个商品数量加减的组件, :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 的值。
  • 删除按钮是删除对应的一条数据,实现上,类似加入购物车的功能,这里加了一个弹出层,询问是否要删除
  • 这个页面引入一个组件 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

你可能感兴趣的:(vue)