🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## 简介 ## 依赖安装 ### yarn ``` yarn install ``` ### npm ``` npm install ``` ## 项目运行 ### yarn ``` yarn serve ``` ### npm ``` npm run serve ``` ### 项目打包 ### yarn ``` yarn build ``` ### npm ``` npm run build ``` ### vue自定义配置 请参考 [Configuration Reference](https://cli.vuejs.org/config/). ## 目录结构 项目结构目录如下: ~~~ |-- web # 根项目 |-- README.md |-- babel.config.js # babel语法编译 |-- package-lock.json |-- package.json # 依赖包管理 |-- postcss.config.js # CSS预处理器(此处默认启用autoprefixer) |-- node_modules # 依赖包 |-- vue.config.js # vue配置文件 |-- dist # 发布目录 |-- public # 静态文件夹 | |-- favicon.ico | |-- index.html |-- src # 源码目录 |-- App.vue |-- configs.js # API配置文件 |-- main.js # 入口文件 |-- permission.js # 路由守卫、钩子验证 |-- api # 网络请求接口 | |-- app.js | |-- news.js | |-- store.js | |-- user.js |-- assets # 资源目录 | |-- css | |-- images | |-- scss |-- components # 组件目录 | |-- activeArea # 首页秒杀、热销商品、店铺复用页面 | |-- adSwiper # 广告页面 | |-- articleList # 文章列表 | |-- couponList # 优惠券列表 | |-- couponPopup # 优惠券弹窗 | |-- evaluateList # 评价列表 | |-- goodsList # 商品列表 | |-- goodsSpec # 商品规格弹窗 | |-- homeCoupon # 首页优惠券组件 | |-- orderGoods # 商品订单 | |-- orderList # 订单列表 | |-- postSaleList # 售后列表组件 | |-- priceSlice # 价格字符分隔组件 | |-- productSwiper # 产品介绍滑块 | |-- progressBar # 进度条 | |-- recommend # 推荐商品列表 | |-- shop # 商品详情店铺模块 | |-- trigonometry # 小三角形组件 |-- layout # 布局组件 |-- mixin |-- router # 项目路由 |-- store # 状态管理 |-- styles # 全局样式目录 |-- utils #外部方法目录 | |-- area.js | |-- relUrl.js | |-- request.js | |-- type.js | |-- utils.js | |-- wxjssdk.js # 微信jssdk |-- views # 项目页面 |-- cart |-- common # 公用页面 | |-- confirmOrder.vue # 订单确认页面 | |-- goodsDetail.vue # 商品详情页面 | |-- goodsSearch.vue # 商品搜索页面 | |-- helpCenter.vue # 帮助中心、文章 | |-- helpDetail.vue # 帮助详情页面 | |-- payResult.vue # 支付结果 | |-- serverExplain.vue # 服务协议 | |-- storeDetail.vue # 店铺简介 | |-- storeInfo.vue # 店铺详情信息 | |-- storeRank.vue # 店铺排行 |-- home # 首页进入的页面 | |-- couponCenter.vue # 优惠中心 | |-- goodsBargain.vue # 商品砍价 | |-- goodsCombination.vue # 拼团 | |-- goodsSeckill.vue # 商品秒杀 | |-- hotList.vue # 热销榜单 | |-- shopStreet.vue # 店铺街 | |-- special.vue # 规格 | |-- userVip.vue # 会员中心 |-- index # 根页面 | |-- cart.vue # 购物车 | |-- home.vue # 首页 | |-- sort.vue # 分类 | |-- user.vue # 个人中心 |-- login # 登录页面 | |-- forgetPwd.vue # 忘记密码 | |-- login.vue # 登录 | |-- register.vue # 注册页面 |-- sort |-- user # 个人中心进入的页面 |-- addressEdit.vue # 地址编辑 |-- afterSalesDetail.vue # 售后详情 |-- afterSalesDetailForm.vue # 填写售后表单 |-- applyAfterSales.vue # 申请售后 |-- commodityEvaluation.vue # 评价商品 |-- goodsEvaluate.vue # 商品评价列表页面 |-- goodsLogistics.vue # 商品订单逻辑 |-- myCoupon.vue # 我的优惠券 |-- orderDetails.vue # 订单详情 |-- postSale.vue # 售后列表页面 |-- signDetail.vue # 签到详情 |-- signRule.vue # 签到规则 |-- userAddress.vue # 用户地址 |-- userBill.vue # 用户消费记录 |-- userCollection.vue # 用户收藏 |-- userEvaluate.vue # 商品全部评价 |-- userOrder.vue # 用户订单 |-- userPayment.vue # 用户充值 |-- userProfile.vue # 用户信息 |-- userSgin.vue # 用户签到 |-- userWallet.vue # 用户钱包 ~~~ ### 项目路由说明 | 页面 | 名字 | 路径 | 带参路径地址 | 参数解释 | | :----------------- | :---------------- | :--------------------- | :------------------------ | :----------------------------------- | | <div style="width:100px">首页</div> | home | /index/home | - | - | | 购物车 | cart | /index/cart | - | - | | 分类 | sort | /index/sort | - | - | | 个人中心 | user | /index/user | - | - | | 店铺街 | shopStreet | /home/shopstreet | - | - | | 限时秒杀 | goodsSeckill | /home/goodsseckill | - | - | | 领券中心 | couponCenter | /home/couponcenter | - | - | | 拼团活动 | goodsCombination | /home/goodscombination | - | - | | 积分签到 | userSign | /home/usersign | - | - | | 会员中心 | userVip | /home/uservip | - | - | | 砍价活动 | goodsBargain | /home/goodsbargain | - | - | | 我的收藏 | userCollection | /home/usercollection | - | - | | 商城咨询or帮助中心 | helpCenter | /common/helpcenter | /common/helpcenter?type=1 | type为1帮助中心不传或者传0位商城咨询 | | 热销榜单 | hotList | /home/hotlist | - | - | | 店铺排行 | storeRank | /common/storerank | - | - | | 商品详情 | goodsDetail | /common/goodsdetail | /common/goodsdetail?id=8 | id 为 商品id | | 商品全部评价 | userEvaluate | /user/userevaluate | /user/userevaluate?id=8 | id 为 商品id | | 店铺简介 | storeDetail | /common/storedetail | /common/storedetail?id=9 | id 为店铺id | | 店铺详情信息 | storeInfo | /common/storeinfo | /common/storeinfo?id=9 | id 为店铺id | | 商品查询 | goodsSearch | /common/goodssearch | /common/goodssearch?id=26&name=文具3 | 入口为分类页面<br>id为分类id<br>name为分类名 | | 个人信息 | userProfile | /user/userProfile | - | - | | 服务协议及隐私政策 | serverExplain | /common/serverExplain | /common/serverExplain?type=0 | type为枚举类型<br> 0 ==> 服务协议<br> 1 ==> 隐私政策 | | 订单列表 | userOrder | /user/userorder | /user/userorder?type=pay | type为枚举类型<br>pay ==> 待付款<br>delivery ==> 待收货<br>finish ==> 已完成<br>close ==> 已关闭<br>all ==> 全部 | | 评价列表 | goodsEvaluate | /user/goodsevaluate | /user/goodsevaluate?type=1 | type为枚举类型<br>1 ==> 已评价<br>不传或者0 ==> 默认 | | 售后列表 | postSale | /user/postsale | /user/postsale?active=apply | active为枚举类型<br>normal ==> 售后申请<br>apply ==> 处理中<br>finish ==> 已处理 | | 我的优惠券 | myCoupon | /user/mycoupon | - | - | | 我的钱包 | userWallet | /user/userwallet | - | - | | 收货地址 | userAddress | /user/useraddress | - | - | | 订单详情 | orderDetails | /user/orderdetails | /user/orderdetails?id=863 | id为订单id | | 查看物流 | goodsLogistics | /user/goodsLogistics | /user/goodsLogistics?id=863 | id为订单id | | 商品评价 | commodityEvaluation | /user/commodityevaluation | /user/commodityevaluation?id=223 | id为商品订单id | | 申请售后 | applyAfterSales | /user/applyaftersales | /user/applyaftersales?order_id=80&item_id=5&after_sale_id=7 | order_id为订单id<br>item_id为商品规格id<br>after_sale_id为售后id(若无可不传) | | 售后详情 | afterSalesDetail | /user/aftersalesdetail | /user/aftersalesdetail?after_sale_id=2&order_id=20 | after_sale_id为售后id<br>order_id为订单id | | 填写快递单号 | afterSalesDetailForm | /user/aftersalesdetailform | /user/aftersalesdetailform?id=3 | id为售后id | | 积分详情 | signDetail | /user/signDetail | - | - | | 签到规则 | signRule | /user/signRule | - | - | | 编辑收货地址 | addressEdit | /user/addressedit | /user/addressedit?id=143 | id为地址列表的id | | 登录 | login | /login | - | - | | 忘记密码 | forgetPwd | /forgetpwd | - | - | | 注册账号 | register | /register | - | - | | 确认订单 | confirmOrder | /common/confirmorder | /common/confirmorder?goods=%5B%7B"item_id"%3A32,"num"%3A3%7D%5D | goods为json字符串结构为:<br>[{<br>item_id:32<br>num:3}]<br>一个商品 为一个对象内存规格id以及数量 | | 支付结果 | p a yResult | /common/payresult | /common/payresult?id=5&type=trade | id为订单id或者trade_id<br>type为枚举类型<br>trade ==> 交易<br>order ==> 普通 | ## 分页说明 ​ 在某些接口请求下往往会有分页数据列表,此时前端需要配置分页变量,page默认从1开始,page_size默认为15个数据为一页,可向接口传入page_no,page_size来配置分页信息,并且需要有一些变量判断分页数据是否已经加载完毕。例子如下: ```vue <template> <div class="article-list"> <van-list v-model="loading" :finished="finished" :finished-text="finishedText" v-show="!isEmpty" @load="$getArticleList()" > <div class="article-item bg-white" v-for="(item, index) in articleList" :key="index" v-show="!isEmpty" @click="visitArticle(item.id)"> <div class="article-info row-between"> <div class="column" style="align-self:flex-start"> <div class="lg two-txt-cut" style="font-weight:500;">{{item.title}}</div> <div class="two-txt-cut nr mt10">{{item.synopsis}}</div> </div> <div class="info-cover ml10"> <van-image :src="item.image" width="100%" height="100%" radius="5px" /> </div> </div> <div class="article-bottom row-between"> <div class="xs muted">发布时间: {{item.create_time}}</div> <div class="row mt10"> <div style="height: 15px;width: 15px;"> <img src="@A/images/icon_see.png"/> </div> <div class="xs muted ml5">{{item.visit}}人浏览</div> </div> </div> </div> </van-list> <div class="data-null column-center bg-white" v-show="isEmpty"> <img src="@A/images/null_notice.png" class="img-null" /> <div class="muted">{{emptyText}}</div> </div> </div> </template> <script> import {getArticleList} from "@API/news" export default { name: "articleList", props: { categoryId: { type: Number, default: 0 }, type: { type: Number | String, default: 0 }, finishedText: { type: String, default: "" }, emptyText: { type: String, default: "暂无任何内容..." }, }, data() { page: 1, finished: false, // 配合vant_ui的list组件使用变量 loading: true, articleList: [], // 判断是否为空数组 isEmpty: false, }, methods: { $getArticleList() { this.loading = true; if (this.finished == true) return; // page_no为页码, page_size可不传,默认15条信息为一页 getArticleList({type: this.type, page_no: this.page, id: this.categoryId || ""}).then((res) => { if (res.code == 1) { this.loading = false; let { more, list } = res.data; this.articleList.push(...list); this.page ++; this.$nextTick(() => { if (!more) { this.finished = true; } if (this.articleList.length <= 0) { this.isEmpty = true; } return; }); } }); }, } mounted() { this.$getArticleList({type: this.type}) } } </script> ``` **注意:当页面有进行相关数据更新的情况下请务必注意清理状态比如page页数清为1,已经加载分页的数组清为空数组[],完成状态清为false等等,这种情况通常为一个tab页共用一个数组变量的情况下需要这样做** ## 路由钩子以及守卫说明 ### 守卫 路由守卫(beforeEach)的作用除了更改网页的标题,还有检测登录状态,若没有登录以及不为跳转白名单页面则自动跳转到登录页面,如果是微信环境下将自动获取微信授权 ### 钩子 路由钩子主要为每个页面配置微信分享。 ## axios说明 ### 请求拦截 请求类于目录下的utils文件夹的request.js中配置。请求接口前,配置默认超时时间,并将用户token保存到请求头上,以便于后台识别。 该项目下请求的接口格式统一如下: ```json { code: 1, msg: '', data: [], debug: {}, time: "0.063771" } ``` 当接口请求成功时请求数据的code为1,请求异常时code将不为1,请求自动拦截异常情况,并打印请求异常信息