Jacleklm's Blog

GoWhere项目总结

2019/11/10

缘起:该项目是 7 月末刚开始学 Vue 的时候,一开始看官方文档,觉得不够扎实,需要一些实战练习,所以在慕课网上看《Vue2.5 开发去哪儿网 App 从零基础入门到实战项目》做了此项目。后来又自己从头到尾把项目敲了一遍。最近复习又把这个项目的实现过了一遍,总结成此博文
后来又给这个项目搭了个基于Koa2的服务器,完善登录验证等功能

组件实现

首页

  • header 组件:用 Vuex 获取城市数据
  • 轮播效果是通过 vue-awesome-swiper 实现的

切换城市页

  • 选择城市后会且切换到首页并把城市数据更新到 Vuex 中
  • 搜索框:对 input 做 v-model=’key’, 对 key 这个变量 watch,有变化就遍历数据把复合的 push 到 result 数组中(可以设置 timer 进行防抖)。
  • 字母表的滑动效果:
    - 安装 better-scroll 实现滑动。用它的 scrollToElement( DOM 节点 ) 实现点击滑动到某个字母

详情页

评论组件的星星(虽然在这个项目里没做不过需要的话也可以讲一下怎么实现的)

数据

form 后端。部分 json 是通过自己写的一个爬虫到去哪儿网抓取生成的。不过爬虫代码太垃圾了了又没优化所以大家忘了这个事吧

后端和数据交互

后端

用 Koa2 搭建服务器,没有用数据库,数据放在 json 文件中,通过对 json 文件的读,写和查询实现需要的功能

前端

proxy 转发请求

用 proxy 转发请求到服务器接口 localhost:3000,这个功能能直接实现跨域?还是说我们服务器默认设置就是 Access-Control-Allow-Orgin: *
答:proxy 的 changeOrgin 是 true 的话,能在开发环境下虚拟一个服务端接收你的请求并代你发送该请求,不会有跨域问题;Koa2 在开发环境下似乎也不会有问题,真正想用跨域 Koa2 得在 app.js 中引入 cors 中间件并 use

1
2
3
4
5
6
7
8
9
// /config/index.js
proxyTable: {
     '/api': {//  在开发环境中(dev),当去请求api目录的时候
       target'http://localhost:3000',// 会把请求转发到当前服务器的3000端口上
       changeOrigintrue// 是否跨域
       pathRewrite: {//  不过希望把路径做一个替换
         '^/api''/'//  一旦请求的地址是以/app开头的,那么就替换请求到...中
     }
}

实现用户登录及 token 验证

  1. 本项目暂时注册和验证登录功能不完善,默认用户在登录页输入用户名和密码都是新用户。点击登录则向服务器 POST 用户名和密码;服务器收到后给新用户生成随机字符 token(暂时还无法保证是唯一性的)和 token 过期时间,把这一套用户数据都写进数据库(json)中,返回给组件用户名和 token;组件收到后把用户名和 token 存进 State 和 localStorage 中
  2. 设置导航守卫。用 router.beforeEach 这个路由钩子,对 to.path = 某些页面(eg. 购物车) 在跳转前检验时候是否有 token,没有就强制跳转到登录页面
1
2
3
4
5
6
7
8
9
10
11
12
13
// 设置导航守卫。用router.beforeEach注册一个全局守卫,判断是否有登录状态
router.beforeEach((to, from, next) => {
if (to.path === '/login') {
next()
} else {
let token = localStorage.getItem('token')
if (token === '' || token === null) {
next('/login')
} else {
next()
}
}
})
  1. 让浏览器每次请求都在头部带 token。通过请求拦截器实现,通过对 axios 的配置新增一个请求拦截让请求头带上 token
  2. axios 的响应拦截用来处理 token 过期的情况,收到服务器响应 401 就清空 localStorage 的 token 并跳转到登录页(这个 清空 localStorage 的 token 并跳转到登录页 其实也是点击 退出登录 按钮要做的事,可以把这个动作封装好放在 Vuex 的 actions 中)。所以服务器要做的事情是:收到除了注册外的请求,都会验证请求头的 token 是否存在,拿 token 去数据库(json)查这个 token 对应的过期时间,过期了则返回 401(这个实现在请求 json 数据的时候验证,现在只在 getAllCity 这个接口有这个验证);没过期则正常返回数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// /src/api/axios.js axios的配置文件
// 3.设置拦截器
Axios.interceptors.request.use(
config => {
if (localStorage.getItem('token')) {
config.headers.token = localStorage.getItem('token')
}
return config
},
error => {
console.log(error)
}
)
// 响应拦截用来检测服务器返回401,token过期
Axios.interceptors.response.use(
res => {
return res
},
error => {
if (error.response) {
switch (error.response.status) {
case 401:
// 服务器检测到token和数据库存的token的过期时间已经过期了的话返回401。跳转登录
localStorage.removeItem('token')
localStorage.removeItem('username')
}
}
}
)
1
2
3
4
5
6
7
// 随机字符token
let token = Math.random()
.toString(16)
.slice(2, 18)
// 过期时间
let expire = new Date()
expire = expire.getTime() + 604800000 // 一周的有效期

实现过程中参考的博客贴
基于 Koa2 对 json 文件进行增删改查
axios 配置
Vue 项目中实现用户登录及 token 验证
Vuex 登录验证及保持登录状态

CATALOG
  1. 1. 组件实现
    1. 1.1. 首页
    2. 1.2. 切换城市页
    3. 1.3. 字母表的滑动效果:- 安装 better-scroll 实现滑动。用它的 scrollToElement( DOM 节点 ) 实现点击滑动到某个字母
    4. 1.4. 详情页
  2. 2. 数据
  3. 3. 后端和数据交互
    1. 3.1. 后端
    2. 3.2. 前端
      1. 3.2.1. proxy 转发请求
      2. 3.2.2. 实现用户登录及 token 验证