## 简介
## 依赖安装
### 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,请求自动拦截异常情况,并打印请求异常信息