vue项目之购物车
简单的完成一个购物车项目,满足基本功能
安装创建好项目以后需要引入安装elementui和vuex
项目目录如下:(home.vue为主页面)

### ~home.vue
<template>
<div>
<!-- <div>我是默认显示页面</div> -->
<!-- 绑定自定义事件,事件函数里面执行操作 -->
<Nav v-if="see" :NavActiveIndex="activeIndex" @fromNavVal='fromNavValfn'></Nav>
<div v-else>折叠以后{{activeIndex2}}</div>
<router-view />
</div>
</template>
<script>
import Nav from './Nav.vue'
export default {
name: 'home',
components: {
//nav是home的子组件
Nav
},
data() {
return {
activeIndex: '/buycar',
activeIndex2: '1',
see: true,
};
},
methods: {
fromNavValfn(val) {
//此时的val为子组件中$emit中发射过来的参数
// console.log(val)
this.activeIndex2 = val;
this.see = !this.see;
}
}
}
</script>
<style>
</style>
###~About.vue
<template> <div> This is an about page </div> </template> <script> </script> <style> </style>
###~Nav.vue
<template>
<div>
<!-- {{NavActiveIndex}} -->
<!-- 父子组件之间通讯用props和emit,无关系组件之间需要用eventbus和vuex -->
<!-- 要传入默认绑定激活的路由 default-active 此处在父组件home中 activeIndex: '/about' 默认绑定根路由下的about-->
<el-menu
:default-active="NavActiveIndex"
class="el-menu-demo"
mode="horizontal"
@select="handleSelect"
background-color="#545c64"
text-color="#fff"
router
active-text-color="#ffd04b">
<el-menu-item index="/buycar">购物车{{buycarCount}}</el-menu-item>
<el-submenu index="2">
<template slot="title">我的工作台</template>
<el-menu-item index="/about">about</el-menu-item>
<el-menu-item index="/test">test</el-menu-item>
<el-menu-item index="/test2">test2</el-menu-item>
</el-submenu>
<el-menu-item index="3"><a href="https://www.ele.me" target="_blank">订单管理</a></el-menu-item>
</el-menu>
<button @click="click">折叠导航栏</button>
</div>
</template>
<script>
import bus from '@/assets/bus.js'
export default {
name: 'nav',
props:{
NavActiveIndex:String
},
data() {
return {
activeIndex: '1',
activeIndex2: 'nav的123',
buycarCount : 0,
};
},
created(){
//非父子组件之间接受方法
//$on监听事件
//数量改变的时候触发这个事件
bus.$on('buycarCountChange',(num) => {
this.buycarCount = num ;
})
},
methods: {
handleSelect(key, keyPath) {
console.log(key, keyPath);
},
click(){
//第一个参数为父组件绑定的自定义事件名字,第二个为携带的参数
this.$emit('fromNavVal',this.activeIndex2)
}
}
}
</script>
<style>
</style>
###~router/index.js
import Vue from 'vue' import Router from 'vue-router' import home from '../views/Home.vue' import test from '../views/test.vue' // import about from '../views/About.vue' Vue.use(Router) export default new Router({ mode:'history', routes: [ { path: '/', name: 'home', component: home, children:[ { path:'buycar', name:'buycar', component: () => import('@/components/buycar.vue') }, { path: 'about', name: 'about', component: () => import ('../views/About.vue') }, { path: 'test2', name: 'test', component: () => import ('../views/test2.vue') }, ] }, { path:'/test', component:test, } ] })
###~assets /bus.js
import Vue from 'vue'; const EventBus = new Vue(); // console.log(1) export default EventBus; //事件注册中心 //所有的事件共同使用的 //所有的组件都可以向这个中心注册或者接受事件
###~main.js
// The Vue build version to load with the `import` command // (runtime-only or standalone) has been set in webpack.base.conf with an alias. import Vue from 'vue' import App from './App' import router from './router' // import store from './store' import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' Vue.use(ElementUI) Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', router, // store, components: { App }, template: '<App/>' })
###~store.js
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) // export default new Vuex.store({ // state:{ // buycarCount: 10 // }, // mutations:{ // changebuyCarCount(state,num){ // state.buycarCount = num ; // } // }, // actions:{ // // } // // // }) //
###~buycar.vue
<template>
<div>
<div v-if='list.length>0'>
<div>
<el-col :span="6">商品信息</el-col>
<el-col :span="3">尺码/颜色</el-col>
<el-col :span="3">吊牌价</el-col>
<el-col :span="3">数量</el-col>
<el-col :span="3">折扣</el-col>
<el-col :span="3">总金额</el-col>
<el-col :span="3">删除</el-col>
</div>
<div>
<ul>
<li v-for="item in list">
<el-col :span="6">
<el-checkbox v-model="selectArrCloth" :label="item.id" @change="item.checked = ! item.checked">{{item.name}}</el-checkbox>
<img src="../assets/logo.png" style="width: 20px; height: 20px;">
</el-col>
<el-col :span="3">{{item.size}} {{item.color}}</el-col>
<el-col :span="3">{{item.price}}</el-col>
<el-col :span="3">
<span @click="pre(item)">-</span>
{{item.count}}
<span @click="add(item)">+</span>
</el-col>
<el-col :span="3">{{item.active}}</el-col>
<el-col :span="3">{{item.price * item.count * item.active}}</el-col>
<el-col :span="3">
<img src="../assets/logo.png" @click="del(item)" style="width: 30px; height: 30px;">
</el-col>
</li>
</ul>
</div>
</div>
<div v-else>购物车没有商品,快去逛逛</div>
<div>
<div class="cls">
<!-- {{selectArrCloth}} -->
<el-checkbox v-model="allCheck" @change="getAllChecked">全选</el-checkbox>
</div>
<div class="cls">合计 {{totalPrice}} 元</div>
<div class="cls">已选商品 {{totalCount}} 件</div>
</div>
</div>
</template>
<script>
import bus from '@/assets/bus.js'
export default {
data() {
return {
selectArrCloth: [],
totalCount: 0,
totalPrice: 0,
allCheck: false,
list: []
}
},
created() {
this.getList()
},
methods: {
getAllChecked(val) {
let selectArrCloth = [];
if (val) {
this.list.forEach(item => {
//根据状态来添加价格,所以需要点击全选的时候循环给数组中数据给true反之给false
item.checked = true;
selectArrCloth.push(item.id)
})
this.selectArrCloth = selectArrCloth;
} else {
this.list.forEach(item => {
item.checked = false;
})
this.selectArrCloth = [];
}
this.getTotalCount();
},
getTotalCount: function() {
let totalCount = 0;
let totalPrice = 0;
//循环添加属性
this.list.forEach(item => {
if (item.checked) {
totalPrice = totalPrice + (parseFloat(item.price).toFixed(2) * parseFloat(item.active) * item.count)
totalCount = totalCount + parseInt(item.count)
}
})
this.totalCount = totalCount;
this.totalPrice = totalPrice;
},
getList() {
//ajax
let arr = [{
name: '款式1',
count: '2',
size: 'L',
color: '红色',
price: '120',
active: '0.5',
id: '1'
},
{
name: '款式2',
count: '2',
size: 'L',
color: '红色',
price: '103',
active: '0.5',
id: '2'
},
{
name: '款式3',
count: '2',
size: 'L',
color: '红色',
price: '150',
active: '0.5',
id: '3'
},
{
name: '款式4',
count: '2',
size: 'L',
color: '红色',
price: '160',
active: '0.5',
id: '4'
},
]
//循环给数组中元素增加一个默认checked为false的属性
arr.forEach(item => {
item.checked = false;
})
this.list = arr;
},
pre: function(item) {
if (item.count == 0) return;
item.count--;
this.getTotalCount();
},
add: function(item) {
item.count++;
this.getTotalCount();
},
del: function(item) {
//当点击这个图片的下标与数组中下标一致清除这个数据返回新数组
let index = this.list.findIndex(cloth => {
return cloth.id == item.id
})
// console.log(index)
this.list.splice(index, 1)
this.getTotalCount();
},
},
watch: {
//当id状态数组发生改变的时候会执行这个方法
selectArrCloth: function() {
this.getTotalCount();
if (this.selectArrCloth.length == this.list.length) {
this.allCheck = true;
} else {
this.allCheck = false;
}
},
//监听list
//此时list为一个对象
list:{
//当值为函数的时候不会进行深度遍历
//需要让其数组进行深度遍历用handler方法
//当deep为true的时候就会深度监听
handler:function(){
let count = 0;
this.list.forEach(item => {
count += parseInt(item.count)
})
bus.$emit('buycarCountChange', count)
},
deep: true
}
}
}
</script>
<!-- 加上scoped为本组件生效 -->
<style scoped>
.cls {
display: inline-block;
margin-top: 50px;
margin-left: 400px;
color: red;
}
</style>
以上为购物车demo
本文仅提供参考,是本人闲时所写笔记,如有错误,还请赐教,作者:阿蒙不萌,大家可以随意转载

浙公网安备 33010602011771号