购物车的完整实现
1 需要提前了解的基础知识
本项目完全使用的是前端开发,没有使用到服务器,(前端开发的小伙伴可以放心看),前端使用到: vue, vue-cli, vuex, vue-router, axios,ES6,ES Module等技术
2 目录部署
- 最终实现目录
2 public目录
因为本项目没有使用到服务器,我们这里将数据放在本地,方便获取,list.json是待会页面需要获取的json文件,static/img/list下的是图片资源(也可以放在scr/assets/img下),我后面会把相关资源上传,大家下载即可
3 src目录
components 组件(支付组件,商品组件)
views 页面(首页面,商品列表页面)
router.js 路由
store.js store
App.vue 应用程序组件
main.js 入口文件
style/iconfot存放的是阿里的字体图标文件,使用方法请戳()
3 效果
1 列表页
2 购物车页面
3 实现整体效果
4 实现的具体功能
-
(加入购物车)在列表页选择商品加入购物车,加入购物车后不能再次加入,再次点击按钮就是从购物车中删除该商品
-
(路由转换)在列表页加入购物车后点击下方的‘进入购物车页面’,即可以看到加入购物车的商品,如果购物车中没有商品,则无法进入购物车页面,在购物车页面点击头部‘购物车’,即可返回到商品列表页面
-
(全选,单选)在购物车页面,当点击商品左上角的圆圈即表示要购买的商品,再次点击即取消购买,点击底部的全选即表示购物车页面的所有商品都要购买,再次点击,则取消全选
-
(价钱计算)只有加入购物车后并且点击购买的商品才能结算价钱
-
(数量添加,数量减少)在购物车页面,点击+号,即添加该商品,点击-号,即减少该商品在购物车中数量,当数量为1时,再点击-号即表示从购物车中删除该商品
-
(移出购物车)在购物车页面点击每个商品右上角的垃圾桶图标,即表示从购物车中将该商品移出
-
(本地存储)使用本地存储,以至于刷新页面或者重新打开该页面,之前加入购物车的商品依旧在,不能用重新选择
5 实现的完整代码
因为代码内容和页面比较多,为了方便大家理解,我把每一个文件里的代码全部都显示出来,里面有详细的注释供大家阅读,如果还有不明白的可以留言哦
(1) main.js
注意:
- 阿里矢量字体图标的使用可以戳
- element-ui中文官网:可以戳 element-ui中文官网
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import axios from 'axios'
// 引入element-ui
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
// 引入阿里字体图标
import '@/assets/style/iconfont/iconfont.css'
// 安装
Vue.prototype.$http = axios
Vue.use(ElementUI)
import {
Message } from 'element-ui';
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
// 路由跳转之前拦截,不能在购物车为空的情况下进入购物车页面
router.beforeEach((to, from, next) => {
if( to.path === '/') {
next()
} else {
let carList = JSON.parse(localStorage.getItem('car'))
if (carList.length > 0) {
next()
} else {
Message({
message: "购物车空空如也,赶紧去添加吧!",
type: 'error'
})
next('/')
}
}
})
(2) Router.js
import Vue from 'vue'
import Router from 'vue-router'
import List from '@/views/List.vue'
Vue.use(Router)
export default new Router({
routes: [
// List页面
{
path: '/',
component: List
},
// 购物车页面
{
path: '/home',
name: 'home',
// 异步引入
component: () => import('@/views/Home')
},
]
})
(3)store.js
注意: 这里store.js是本项目中比较复杂的一个页面,主要是因为里面有很多同步消息和变量
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
// 购物车 本地存储,防止数据丢失
car: localStorage["car"] ? JSON.parse(localStorage["car"]) : [],
// 总价
totlePrice: 0,
// 全选状态
all_selected: false,
// 购物车中购买的数量
payNum: 0,
// list页面控制‘加入购物车按钮’的样式 本地存储,防止数据丢失
isShow: localStorage["isShow"] ? JSON.parse(localStorage["isShow"]) : []
},
getters: {
// 时时监听car的变化
carList(state) {
// 初始化全选状态
if (state.all_selected) {
state.car.forEach(item => item.isBuy = true)
}
return state.car;
},
// 购买的总价钱
allPrice(state) {
let totlePrice = 0
state.car.forEach(item => {
// 如果加入购物车后点击了购买按钮
if (item.isBuy) {
totlePrice += item.num * item.price
}
})
return state.totlePrice = totlePrice
},
// 购买的商品的总数量
payLength(state) {
let paylength = 0
state.car.forEach(item => {
if (item.isBuy) {
paylength += item.num
}
})
return state.payNum = paylength;
}
},
// 同步消息
mutations: {
// 从购物车中删除该商品
deleteProduct(state, id) {
// 商品在购物车中索引值
let index = state.car.findIndex(item => item._id === id)
// 商品在isShow中的索引值
let indexShow = state.isShow.findIndex(item =>item.id === id)
// 将购物车中该商品的selected属性改成false
state.car[index].selected = false;
// 从购物车中删除该商品
state.car.splice(index, 1)
// 从本地存储的购物车中删除该商品(即将删除了该商品的购物车赋值给本地存储)
localStorage.setItem('car', JSON.stringify(state.car))
// console.log(5555,state.car, state.isShow[index].show)
// 将isShow中该商品的show属性改成相反的值
state.isShow[indexShow].show =