开发初衷:
一直在学习vue.js,之前学习构建工具搭建的项目都是从github下载的,学习着就想自己通过vue-cli搭建一个简易的水果商城项目.该项目系本人首次发布于github,有诸多问题需要修正,目前项目还会继续更新,还请各位大神多多指点,轻喷,谢谢了。项目比较简单,适合新手学习项目布局,一些简单的数据交互,如果觉得能通过项目学到一点东西,麻烦再github上给个star,先在这里谢过了。
项目结构:
组件结构:
需求分析:
提示:本项目中调用本地json数据后,数据会被存到localstorage,减少多次接口调用
- 实现各种水果产品的展示 home.vue 请求statci/fruit.json获取所有数据,fruit.json包含水果数据、收货地址列表数据、 水果文章数据.将fruitData与addressList存入localstorage。
- 点击水果产品进入对应的详情页 Detail.vue 此组件旨在渲染对应水果的具体数据:轮播图、价格、名称、介绍,对水果的数量进行修 改。并且可以将水果添加到购物车,也可以直接进行结算。
- 如果在详情页直接点击结算,则直接跳转到结算页面 如果点击购物车,则进入购物车组件,在购物车组件可以修改水果购买数量以及选择结算那 些水果。 购物车组件 Car.vue 结算组件 Pay.vue PaySuccess.vue
- 进入结算页面后 可以设置发票抬头、支付方式、留言信息
- 结算成功后进入PaySuccess.vue 在支付成功页可以进入订单详情页面和订单列表页面 Order.vue 订单列表 OrderDetail.vue 订单详情
- 个人中心My.vue 我的收藏 Collection.vue 我的收货地址:(列表)AddressList.vue (新增编辑)AddressEdit.vue
- 水果相关文章 文章详情:Article.vue 文章详情:ArticleDetail.vue
- 文章和水果都有收藏功能,收藏成功后可以在个人中心的我的收藏里面看到
项目页面截图:
vuex:
index.js
import Vue from 'vue'import Vuex from 'vuex'import state from './state'import mutations from './mutations'import actions from './actions'Vue.use(Vuex)export default new Vuex.Store({ state, mutations, actions})
state.js
const state={ fruitData:localStorage["fruitData"]?JSON.parse(localStorage["fruitData"]): [], //水果数据 addressList:localStorage["addressList"]?JSON.parse(localStorage["addressList"]): [], //地址列表 addressEdit:localStorage.getItem("addressEdit")?JSON.parse(localStorage.getItem("addressEdit")):{}, //当前编辑地址对象 carts:localStorage["carts"]?JSON.parse(localStorage["carts"]): [], //购物车 orders:localStorage["orders"]?JSON.parse(localStorage["orders"]): [], //本次结算订单 ordersList:localStorage["ordersList"]?JSON.parse(localStorage["ordersList"]): [], //全部订单 payStyles:[ { id:"1", name:"在线支付", introduce:"支持支付宝支付、微信支付、银行卡支付、财付通等" }, { id:"2", name:"蚂蚁花呗", introduce:"花呗分期是花呗联合天猫淘宝推出的,面向互联网的赊购服务,通过支付宝轻松还款,0首付" }, { id:"3", name:"货到付款", introduce:"货到再付款,支持现金交易" } ], currentOrder:localStorage.getItem("currentOrder")?JSON.parse(localStorage.getItem("currentOrder")):{}, //当前操作订单 nowIndex:localStorage.getItem("nowIndex")?JSON.parse(localStorage.getItem("nowIndex")):0, articles:localStorage["articles"]?JSON.parse(localStorage["articles"]): [], //全部文章 articlesCollect:localStorage["articlesCollect"]?JSON.parse(localStorage["articlesCollect"]): [], //收藏文章 goodsCollect:localStorage["goodsCollect"]?JSON.parse(localStorage["goodsCollect"]): [], //收藏商品}export default state
action.js
const actions={ //水果数据 setFruit({commit},data){ commit('SET_FRUIT',data) }, //地址列表 setAddresslist({commit},data){ commit('SET_ADDRESSLIST',data) }, //添加到购物车 addCar({commit},data){ commit('ADD_CARTS',data) }, //购物车结算 setOrders({commit},data){ commit('SET_ORDERS',data) }, //全部订单 getAllOrders({commit},data){ commit('GET_ORDERS',data) }, //当前订单 setCurrentorder({commit},data){ commit('SET_CURRENTORDER',data) }, //设置当前导航索引 setIndex({commit},data){ commit('SET_INDEX',data) }, //设置当前地址编辑对象 setAddressedit({commit},data){ commit('SET_ADDRESSEDIT',data) }, //设置当前收货地址 defaultAddress({commit},data){ commit('DEFAULT_ADDRESS',data) }, //新增时清空当前编辑地址,避免新增输入框里面有编辑地址时的内容 emptyAddress({commit}){ commit('EMPTY_ADDRESS') }, //获取全部文章 getArticle({commit},data){ commit('GET_ARTICLE',data) }, //文章收藏 setArticle({commit},data){ commit('SET_ARTICLE',data) }, //文章点赞 praiseArticle({commit},data){ commit('SET_ARTICLE',data) }, //商品收藏 collectGoods({commit},data){ commit('COLLECT_GOODS',data) }}export default actions
type.js
export const PRAISE_ARTICLE ='PRAISE_ARTICLE' //文章收藏export const SET_FRUIT ='SET_FRUIT' //水果数据export const SET_ADDRESSLIST ='SET_ADDRESSLIST' //地址列表export const ADD_CARTS = 'ADD_CARTS' //加入购物车export const GET_ORDERS='GET_ORDERS' //所有订单export const SET_ORDERS='SET_ORDERS' //本次结算订单export const SET_CURRENTORDER='SET_CURRENTORDER' //当前操作订单export const SET_INDEX='SET_INDEX' //设置当前导航索引export const SET_ADDRESSEDIT='SET_ADDRESSEDIT' //设置当前地址编辑对象export const DEFAULT_ADDRESS='DEFAULT_ADDRESS' //设置当前地址export const EMPTY_ADDRESS='EMPTY_ADDRESS' //新增时清空当前编辑地址,避免新增输入框里面有编辑地址时的内容export const GET_ARTICLE ='GET_ARTICLE' //获取全部文章export const SET_ARTICLE ='SET_ARTICLE' //文章收藏export const COLLECT_GOODS='COLLECT_GOODS' //商品收藏
mutations
import state from './state'import * as type from './type.js' import { Dialog } from 'vant';const matutaions={ //水果数据 [type.SET_FRUIT](state,data){ state.fruitData = data; localStorage.setItem("fruitData",JSON.stringify(state.fruitData)); }, //地址列表 [type.SET_ADDRESSLIST](state,data){ state.addressList = data; localStorage.setItem("addressList",JSON.stringify(state.addressList)); }, //购物车 [type.ADD_CARTS](state,data){ state.carts.push(data); localStorage.setItem("carts",JSON.stringify(state.carts)); }, //购物车删除 shanchu:(state,index)=>{ Dialog.confirm({ title: '确认删除', message: '您确认删除嘛?' }).then(() => { state.carts.splice(index,1) localStorage.setItem("carts",JSON.stringify(state.carts)); }).catch(() => { }); }, //订单 [type.SET_ORDERS](state,data){ //本次结算订单 state.orders = data localStorage.setItem("orders",JSON.stringify(state.orders)); }, //获取全部订单 [type.GET_ORDERS](state,data){ state.ordersList.push(data); localStorage.setItem("ordersList",JSON.stringify(state.ordersList)); }, //当前操作订单 [type.SET_CURRENTORDER](state,data){ state.currentOrder = data localStorage.setItem("currentOrder",JSON.stringify(state.currentOrder)); }, //设置当前导航索引 [type.SET_INDEX](state,data){ state.nowIndex = data localStorage.setItem("nowIndex",JSON.stringify(state.nowIndex)); }, //设置当前地址编辑对象 [type.SET_ADDRESSEDIT](state,data){ state.addressEdit = data localStorage.setItem("addressEdit",JSON.stringify(state.addressEdit)); }, //设置当前地址 [type.DEFAULT_ADDRESS](state,data){ state.defaultAddress = data //先将地址列表的默认地址都设置为false state.addressList.forEach((item,index)=>{ item.is_default = false }); var addressId = data.id; //再讲当前选中地址设置为true state.addressList.forEach((item,index)=>{ if(item.id === addressId){ item.is_default = true } }); console.log(state.addressList); localStorage.setItem("addressList",JSON.stringify(state.addressList)); }, //新增时清空当前编辑地址,避免新增输入框里面有编辑地址时的内容 [type.EMPTY_ADDRESS](state){ state.addressEdit = {}; localStorage.setItem("addressEdit",JSON.stringify(state.addressEdit)); }, //获取全部文章 [type.GET_ARTICLE](state,data){ state.articles = data localStorage.setItem("articles",JSON.stringify(state.articles)); }, //收藏文章 [type.SET_ARTICLE](state,data){ var collectId = data.id; if(data.isCollected){ state.articles.forEach((item)=>{ if(item.id === collectId){ item.isCollected = false } }); state.articlesCollect.forEach((item,index)=>{ if(item.id === collectId){ state.articlesCollect.splice(index,1); } }) } else { state.articles.forEach((item)=>{ if(item.id === collectId){ item.isCollected = true } }); state.articlesCollect.push(data); } localStorage.setItem("articles",JSON.stringify(state.articles)); localStorage.setItem("articlesCollect",JSON.stringify(state.articlesCollect)); }, //点赞文章 [type.PRAISE_ARTICLE](state,data){ }, //收藏商品 [type.COLLECT_GOODS](state,data){ var collectId = data.id; if(data.isCollected){ state.fruitData.forEach((item,index)=>{ if(item.id === collectId){ item.isCollected = false } }) state.fruitData.forEach((item,index)=>{ if(item.id === collectId){ state.goodsCollect.splice(index,1); } }) }else{ state.fruitData.forEach((item,index)=>{ if(item.id === collectId){ item.isCollected = true } }); state.goodsCollect.push(data); } localStorage.setItem("goodsCollect",JSON.stringify(state.goodsCollect)); localStorage.setItem("fruitData",JSON.stringify(state.fruitData)); }, //文章删除 del:(state,index)=>{ MessageBox.confirm('确定取消收藏该文章么?').then(action=>{ state.article.splice(index,1) localStorage.setItem("article",JSON.stringify(state.article)); }) }, //商品删除 cancel:(state,index)=>{ MessageBox.confirm('确定取消收藏该商品么?').then(action=>{ state.collections.splice(index,1) localStorage.setItem("collections",JSON.stringify(state.collections)); }) }, laji:(state,index)=>{ MessageBox.confirm('确定删除收货地址么?').then(action=>{ state.address.splice(index,1) localStorage.setItem("address",JSON.stringify(state.address)); }) }, //订单删除 delOrders:(state,index)=>{ Dialog.confirm({ title: '确认删除', message: '确定删除该订单么?' }).then(() => { state.ordersList.splice(index,1) localStorage.setItem("ordersList",JSON.stringify(state.ordersList)); }).catch(() => { }); }, //数量加 add(state,index){ state.carts[index].value++ }, //数量减 reduce(state,index){ state.carts[index].value==1?state.carts[index].value=1: state.carts[index].value-- }, settlement:(state,data)=>{ state.carts=[]; localStorage.setItem("carts",JSON.stringify(state.carts)); },}export default matutaions
总结:
该项目开发的初衷是熟悉vuex以及练习商城vant-ui框架。本项目是参考github一个vivo商城项目,地址为 参考该项目思路,在这里对原作者表示感谢。 数据图片来源于中国水果网,再次表示感谢,侵权联系便删。
有任何问题意见建议可以在 这里给我留言,大家一起分享学习讨论。如果觉得能通过项目学到一点东西,麻烦再github上给个star,先在这里谢过了。
技术参考网站: vue官网
技术栈:vue全家桶 vue+vuex+vue-router+axios+vant-ui+localstorage+sass
相关链接:van-ui官网