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
本文仅提供参考,是本人闲时所写笔记,如有错误,还请赐教,作者:阿蒙不萌,大家可以随意转载