vue-router和axios的优化和封装

本地目录:

  • 1.router优化之路由懒加载
  • 2.router优化之token验证和动态设置路由
  • 3.axios优化之请求拦截器
  • 4.axios优化之封装通用api
  • 5.axios优化之基地址的环境适配

1.router优化之路由懒加载

修改router文件夹中的index.js文件
第一种方式,在引入组件的时候做出改变
原本的写法:
import Login from '@/components/Login'
懒加载的写法:
const Login = () => import(/* webpackChunkName: "Login" */ '../views/Login.vue')
第二种方式:在挂载路由的时候做出改变
原本的写法:

  {
    path: '/login',
    name: 'Login',
    meta: {
      title: '登录'
    },
    component: Login
  },

懒加载的写法:

  {
    path: '/login',
    name: 'login',
    meta: {
      title: '登录'
    },
    component: () => import(/* webpackChunkName: "login" */ '@/components/login')
  },

2.router优化之token验证和动态设置路由

这里我们用到了路由守卫

router.beforeEach((to, from, next) => {
  if (to.meta.title) {
    document.title = to.meta.title
  }
  if (to.path.startsWith('/login')) {
    window.localStorage.removeItem('access-token')
    next()
  } else if (to.path.startsWith('/index')) {
    next()
  } else {
    let user = window.localStorage.getItem('access-token');
    if (!user) {
      next({ path: '/login' })
    } else {
      next()
    }
  }
})

3.axios优化之请求拦截器

api文件夹是我们在项目的根目录文件夹下新建的,方便我们对axios进行深层的封装,这样我们就不在入口文件main.js中引用axios了,而是在需要发送请求的单独引入。
在api文件夹中新建一个index.js,然后先引用axios
import axios from 'axios'
添加请求拦截器(在请求头中添加token)

axios.interceptors.request.use(
  config => {
    let token = window.localStorage.getItem('access-token')
    if (token) {
      config.headers.Authorization = token;
    }
    return config
  },
  error => {
    return Promise.reject(error)
  }
);

添加响应拦截器(对指定的响应码进行统一的处理)

axios.interceptors.response.use(
  function(res) {
    // console.log('header: ', res)
    // token 快过期,交换
    if (res.headers['new-token']) {
      const newToken = res.headers['new-token']
      localStorage.setItem('token', newToken)
    }
    if (
      res.data.code === '200' ||
      res.data.code === '201' ||
      res.data.state === 'SUCCESS'
    ) {
      return res
    } else if (res.data.code === '400') {
      localStorage.removeItem('token')
      router.push('/login')
    } else {
      // Toast.fail(res.data.message)
      return Promise.reject(res)
    }
  },
  function(error) {
    // console.log(error.response.data.code)
    if (error.response) {
      const code = error.response.status
      const innerCode = error.response.data.code

      switch (code) {
        // 400 token 校验不通过,402 用户没权限, 401 token 过期
        case 400:
          localStorage.removeItem('token')

          if (router.currentRoute.name !== 'Login') {
            router.push('/login')
          }
          if (innerCode === '402') {
            // 402 的提示语会不一样
          }
          if (innerCode === '401' || innerCode === '402') return
      }
    }
    // 对响应错误做点什么
    error.message && Toast.fail(error.message)
    return Promise.reject(error)
  }
)

4.axios优化之封装通用api

还是在index.js文件中
首先需要一个基地址的变量base,因为项目从开发到上线,往往有多个环境,所以这个base需要根据不同的环境去进行自动改变。(适配方法接下来会讲),如果不懂这个base的设置,可以在一开始的时候把base写死
const base = 'xxxxx'
后面再根据实际情况进行改变

export const POST = (url, params) => {
  return axios.post(`${base}${url}`, params).then(res => res.data)
}
export const GET = (url, params) => {
  return axios.get(`${base}${url}`, {
    params: params
  }).then(res => res.data)
}
export const PUT = (url, params) => {
  return axios.put(`${base}${url}`, params).then(res => res.data)
}
export const DELETE = (url, params) => {
  return axios.delete(`${base}${url}`, {
    params: params
  }).then(res => res.data)
}
export const PATCH = (url, params) => {
  return axios.patch(`${base}${url}`, params).then(res => res.data)
}

index.js的代码已经写好,接下来在api文件夹下新建一些其他的文件,用来写页面中用到的具体请求

import * as API from './'
export default {
  list: params => {
    return API.GET('/api-base/log', params)
  },
  updateList: params => {
    return API.POST('/api-base/updatelist', params)
  }
}

在要用到这个list请求的页面首先引入api
import API from "../../api/api_log";
发送get请求示例

let params = {
  limit: that.limit,
  page: val
};
API.list(params).then(res => {
  if (res.code === 0) {
    that.rows = res.page.rows;
    that.total = res.page.total;
  }
});

post等其他方式的请求的发送方式和get一样,虽然在api文件夹的index.js文件夹中我们已经定义了所有请求的一些返回状态码的统一处理方式,但是我们也可以为单独请求定制错误处理代码,代码示例:

API.list(params)
  .then(
      function(result) {
        if (res.code === 0) {
        that.rows = res.page.rows;
        that.total = res.page.total;
      }else{
        //some code
       }
     },
    function(err) {
      _this.$message.error({
        showClose: true,
        message: err.toString(),
        duration: 2000
      });
    }
  )
  .catch(function(error) {
    console.log(error);
    _this.$message.error({
      showClose: true,
      message: "请求出现异常",
      duration: 2000
    });
  });

5.axios优化之基地址的环境适配

vue-cli3以前的版本生成的项目,根目录下会有build文件夹和config文件夹,存放的是关于webpack的配置,但是vue-cli3以后的版本,不再显示此文件,所有修改webpack只能通过添加代码去覆盖默认配置。
在根目录下新建一个vue.config.js文件,用来写相应的代码,如常用的配置css以及设置代理,代码示例:

module.exports = {
  // px转rem
  css: {
    extract: false,
    loaderOptions: {
      postcss: {
        plugins: [
          require('postcss-plugin-px2rem')({
            rootValue: 37.5, // 换算基数, 默认100  ,这样的话把根标签的字体规定为1rem为50px,这样就可以从设计稿上量出多少个px直接在代码中写多上px了。
            exclude: /(node_module)/, // 默认false,可以(reg)利用正则表达式排除某些文件夹的方法,例如/(node_module)\/如果想把前端UI框架内的px也转换成rem,请把此属性设为默认值
            mediaQuery: false, // (布尔值)允许在媒体查询中转换px。
            minPixelValue: 3 // 设置要替换的最小像素值(3px会被转rem)。 默认 0
          })
        ]
      }
    }
  },
  devServer: {
    open: true,
    host: '192.168.1.102',
    port: 8080,
    https: false,
    // 以上的ip和端口是我们本机的;下面为需要跨域的
    proxy: 'http://xxx.xx.xxx.xxx:8088'
  }
}

这里我们重点讲下基地址的环境适配的方法。
第一步
在项目的根目录建立额外的环境配置文件,一个文件一个环境,如我要配置test(测试环境)
.evn.test内容
NODE_ENV = 'test'
第二步
在项目根目录添加 config.js文件(此文件是配置各环境的url)

let BASE_URL = ""; //这里是一个默认的url,可以没有
switch (process.env.NODE_ENV) {
    case 'development':
        BASE_URL = "http://0.0.0.222:8080" //这里是本地的请求
        break
    case 'test':
        BASE_URL = "http://www.xxx.com.cn/test" // 测试环境
        break
    case 'production':
        BASE_URL = "http://www.xxx.com.cn/" //生产环境
        break
}

export default BASE_URL;

第三步
在package.json文件中,添加启动命令

// ...
"scripts": {
     "serve": "vue-cli-service serve",
     "test": "vue-cli-service build --mode test",  // 这一行
     "build": "vue-cli-service build"
},
// ...

用法:
在需要用到请求前缀的地方,导入config文件,就可以了(比如封装的axios)
此方法配置后:
1、如果是本地环境,就运行npm run serve。此时对应的baseUrl就是config里配置的development项
2、如要打包到测试环境,就运行npm run test。此时对应的baseUrl就是config里配置的test项
3、如要打包到正式环境,就行动npm run build。此时对应的baseUrl就是config里配置的production项

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。