前面写的了解了一下vue这个框架,所有的框架都要在实际应用里感受一下好坏.
这里用vue+vuex+Ts+elementEI来做一个项目

git地址:
https://github.com/544076724/...

首先下载vue-cli 这里用的版本是4.5.9

首先创建项目

vue create edu-boss-fed

然后来回答一些问题
image.png
这里我们自己配置要的选项
image.png
然后第一个不选默认是2.0版本的vue,这里我们用2.0。
然后把babel,ts,router,vuex,css预处理器,和lint都选上.
image.png
然后勾选ts之后,我们把使用类样式的组件语法 也勾选上(可以写jsx语法了)
image.png
这个也是yes,我们让ts只处理类型注解,然后语法的转换还是交给babel来处理(ts处理不够完善).
image.png
这里我们选的no,我们这个项目用hash模式路由,如果后期需要history模式再配置.
image.png
这里用第一个,最新的sass
image.png
这里我们用Standard规则,这个规则相对比较松,比较适合个人或小团队使用.

image.png
这里我们都勾选上,保存save和commit提交时都对代码进行修复.
image.png
然后第一个,把eslint以及其他配置都用单独文件配置.
image.png
最后看个人需要,是否要储存我们之前选择的这一套来生成个模板,方便下次使用.

这个代码里主要有个需要关注的地方是在请求的封装,拦截器这里

贴一下代码

// 请求拦截器
request.interceptors.request.use(function (config) {
  // 我们就在这里通过改写 config 配置信息来实现业务功能的统一处理
  const { user } = store.state
  if (user && user.access_token) {
    config.headers.Authorization = user.access_token
  }

  // 注意:这里一定要返回 config,否则请求就发不出去了
  return config
}, function (error) {
  // Do something with request error
  return Promise.reject(error)
})

// 响应拦截器
let isRfreshing = false // 控制刷新 token 的状态
let requests: any[] = [] // 存储刷新 token 期间过来的 401 请求
request.interceptors.response.use(function (response) { // 状态码为 2xx 都会进入这里
  // console.log('请求响应成功了 => ', response)
  // 如果是自定义错误状态码,错误处理就写到这里
  return response
}, async function (error) { // 超出 2xx 状态码都都执行这里
  // console.log('请求响应失败了 => ', error)
  // 如果是使用的 HTTP 状态码,错误处理就写到这里
  // console.dir(error)
  if (error.response) { // 请求发出去收到响应了,但是状态码超出了 2xx 范围
    const { status } = error.response
    if (status === 400) {
      Message.error('请求参数错误')
    } else if (status === 401) {
      // token 无效(没有提供 token、token 是无效的、token 过期了)
      // 如果有 refresh_token 则尝试使用 refresh_token 获取新的 access_token
      if (!store.state.user) {
        redirectLogin()
        return Promise.reject(error)
      }

      // 刷新 token
      if (!isRfreshing) {
        isRfreshing = true // 开启刷新状态
        // 尝试刷新获取新的 token
        return refreshToken().then(res => {
          if (!res.data.success) {
            throw new Error('刷新 Token 失败')
          }

          // 刷新 token 成功了
          store.commit('setUser', res.data.content)
          // 把 requests 队列中的请求重新发出去
          requests.forEach(cb => cb())
          // 重置 requests 数组
          requests = []
          return request(error.config)
        }).catch(err => {
          console.log(err)
          Message.warning('登录已过期,请重新登录')
          store.commit('setUser', null)
          redirectLogin()
          return Promise.reject(error)
        }).finally(() => {
          isRfreshing = false // 重置刷新状态
        })
      }

      // 刷新状态下,把请求挂起放到 requests 数组中
      return new Promise(resolve => {
        requests.push(() => {
          resolve(request(error.config))
        })
      })
    } else if (status === 403) {
      Message.error('没有权限,请联系管理员')
    } else if (status === 404) {
      Message.error('请求资源不存在')
    } else if (status >= 500) {
      Message.error('服务端错误,请联系管理员')
    }
  } else if (error.request) { // 请求发出去没有收到响应
    Message.error('请求超时,请刷新重试')
  } else { // 在设置请求时发生了一些事情,触发了一个错误
    Message.error(`请求失败:${error.message}`)
  }

  // 把请求失败的错误对象继续抛出,扔给上一个调用者
  return Promise.reject(error)
})

在这里我们的 token 无效(没有提供 token、token 是无效的、token 过期了)的话,会尝试刷新token然后再次发送之前失败的请求.
token过期时间比较短(为了安全), 刷新token接口(还失败就让重新登陆)只能执行一次

这里的实现是 刷新 token状态时,把 其他请求都储存起来并 返回 promise 等待未来 刷新成功后 重新请求 并且请求结果 返回 决议 promise状态

这是 实现。上面是简化版本

      let r;

      let p = new Promise(resolve => {
        r = resolve //储存决议函数 
      })
      requests.push({
        r,config:error.config //储存决议函数和对应请求配置,方便后续调用
      })

      requests.forEach(item => item.r(request(item.config)));

其他的就是一些常见的需求,有兴趣可以下载下来跑跑看

登陆账号:18201288771

密码:111111


Charon
57 声望16 粉丝

世界核平


« 上一篇
Vue3.0