Vue+element搭建后台管理系统-五、网络请求封装-vue封装axiaos
上一章我们详解了项目的架构目录,这一章主要学习对接口的封装。
网络请求封装是每个前端项目必不可少的一项,有利于方便统一管理,比如在请求头统一加上后台校验数据,这样就没必要在每个接口中都写一遍了嘛,这也是面向对象编程的一个好的提现。
我们这次选用的是axios插件,这个插件优点还是蛮多的,支持promise,可以拦截请求和拦截响应,客户端支持防御XSRF攻击等等,那么我们就开始吧。
一、安装axios
老规矩,在控制台中输入:
npm install axios -S
二、对axiaos做封装
我们在request目录的index.js文件中,
导入axiaos插件,主角。
导入用到的element-ui中的Message弹窗组件,主要用作提示报错,如:接口请求报错了,可以在响应拦截中弹窗提示相应信息。
导入store,用于设置全局的状态管理,比如常用到的用户信息,站点管理这些。
导入auth,封装有获取token方法的插件,如:获取浏览器缓存中的token信息。
导入路由router,用于路由跳转,如:后台返回登录信息过期,那么我们在请求响应拦截捕获到了,然后我们就可以直接做路由跳转到登录页面了。
并写入相应的请求拦截和响应拦截。
import axios from 'axios' import { Message } from 'element-ui' //element弹窗 import store from '@/store' //登录信息 import { getToken } from '@/utils/helper/auth.js' //获取token import Router from '@/router/index.js' //路由对象 const service = axios.create({ timeout: 10000, }) // request interceptor //请求拦截 service.interceptors.request.use( (config) => { //header存放token-一般接口要求 config.headers['token'] = getToken() //设置请求接口 service.prototype.requestUrl = config.url return config }, (error) => { // do something with request error console.log(error) // for debug return Promise.reject(error) } ) // response interceptor //响应拦截 service.interceptors.response.use( /** * 这里会返回http请求的信息,如数据、状态码 */ (data) => { data = data.data let res = {} if (data.code == '0') { console.log('接口请求数据正常') } else if (data.code == 201 || data.code == '9001') { Message({ message: '账号信息已过期,请重新登录', type: 'warning', }) //清空用户信息 store.commit('user/logout') Router.push({ path: '/login' }) } else { Message({ message: data.msg, type: 'error', }) } // 处理返回格式-自定义返回所有数据或数据包裹指定数据 // eslint-disable-next-line no-prototype-builtins if (data.hasOwnProperty('data') && data.data != null && !data.total && service.prototype.requestUrl.indexOf('auth') == -1) { res = data.data } else { res = data } return res }, (error) => { console.log('err' + error) // for debug Message({ message: error.message, type: 'error', duration: 5 * 1000, }) return Promise.reject(error) } ) export default service
加好上面的内容后,补充一下需要导入的内容。在utils文件夹下创建helper文件夹,然后新建auth.js文件,加入下面获取token的方法。
utils/helper/auth.js内容:
const TokenKey = 'token' export function getToken() { return localStorage.getItem(TokenKey) } export function setToken(token) { return localStorage.setItem(TokenKey, token) } export function removeToken() { return localStorage.removeItem(TokenKey) }
补充一下store中的内容:
store/modules/user.js内容:
export default { namespaced: true, state: { userInfo: { id: null, account: '', realName: '', companies: '', sites: null, }, }, mutations: { setUserInfo(state, param) { state.userInfo = param }, logout(state, param) { state.userInfo = param }, }, }
补充好上面的内容后,然后做一下全局配置,这样可以在vue文件中通过this调用了。
三、全局配置
api目录下创建index.js文件
导入Vue,通过原型继承,实现全局注册。
导入string的toLowerCaseBar,这个方法是用来将小写驼峰的字符串转成小写横杆的字符串,比如:getDataApi转成get-data-api,主要的作用是做一个请求方法的统一管理。
并写入下面内容:
import Vue from 'vue' import { toLowerCaseBar } from '@/utils/helper/string.js' // 格式(小写驼峰)转 格式(小写横杠) /** * 页面调用API目录方法 * @func ajax * @param {String} route 请求路径 * @param {Object} param 接口参数 */ const ajax = (route, param) => { let arr = route.split('/') // 目录 -> 文件 -> 方法 // 获取组s件 let components = require('./' + toLowerCaseBar(arr[0]) + '/' + toLowerCaseBar(arr[1]) + '.js')[arr[2]] return components(param) } /** * 页面调用API目录方法 * @func ajax * @param {String} route 请求路径 * @param {Object} param 接口参数 */ Vue.prototype.$ajax = ajax export default ajax
补充一下上述导入的string.js文件,同样在utils文件夹下的helper文件夹,创建string.js,为啥叫string.js呢?
主要类似一个类吧,主要应用于字符串类型的操作,字符串截取,字符串转换等等。
然后添加以下代码:
/** * 格式(小写驼峰)转 格式(小写横杠) * @func toLowerCaseBar */ export const toLowerCaseBar = (data) => { let res = '' if (data) { res = data.replace(/[A-Z]/g, (item) => `-${item.toLowerCase()}`) } return res }
封装的工作做好了,然后在main.js文件中做一下全局导入,通过import 导入api下的index.js文件即可。
.... import 'element-ui/lib/theme-chalk/index.css' //样式文件一定要引入 import './api/index.js' //载入路由 ....
四、添加mock数据-测试
现在我们在搭建框架的过程中,后台应该还没出接口供我们测试,那么就需要我们去造数据。
打开cmd,安装我们所用到的工具,mockJS
npm install --save-save mockjs
然后我们在src目录下创建service文件夹,创建两个文件,index.js,test.mock.js主要用来存放虚拟接口数据的。
index.js文件代码如下:
import Mock from 'mockjs' //入口文件 Mock.setup({ timeout: '500-800', }) const context = require.context('./', true, /\.mock.js$/) context.keys().forEach((key) => { Object.keys(context(key)).forEach((paramKey) => { Mock.mock(...context(key)[paramKey]) }) }) export default context
这个文件的作用将service下的每个数据模块导入然后再全局导出,这样我们在开发的时候,就可以做虚拟数据的按模块独立出来。例如下面的test.mock.js文件,可以作为一部分接口数据。
test.mock.js代码如下:
import Mock from 'mockjs' const { Random } = Mock export default [ RegExp('/login.*'), 'get', { 'range|50-100': 50, 'data|10': [ { // 唯一 ID id: '@guid()', // 生成一个中文名字 cname: '@cname()', // 生成一个 url url: '@url()', // 生成一个地址 county: Mock.mock('@county(true)'), // 从数组中随机选择一个值 'array|1': ['A', 'B', 'C', 'D', 'E'], // 随机生成一个时间 time: '@datetime()', // 生成一张图片 image: Random.dataImage('200x100', 'Mock Image'), }, ], }, ]
做好之后,在main.js文件中导入:
做好全局导入之后,我们就可以通过请求来做测试了。
简单写一个请求数据的方法,在api文件夹下创建login文件夹,然后在login文件夹下创建auth-api.js,添加下面内容:
导入request,前面封装的网络请求方法
导入url,全局配置文件中的请求域。config.index.js代码如下:(域名记得换成自己本机nodeJS运行服务的域名)
/* eslint-disable no-undef */ const CONFIG = { //开发环境 development: { url: 'http://192.168.0.101:8080', //本机ip地址域名 }, //生产环境 production: { url: 'https://getman.cn/mock', //生产环境的请求域名 } } export default CONFIG[process.env.NODE_ENV]
auth-api.js代码入下:
import request from '@/utils/request/index.js' import config from '@/config/config.index.js' /** * @description 登录 * @param {JSON} param * @returns */ export const loginApi = (param) => { return request({ method: 'post', // 请求方式: GET、POST url: config.url + '/login', data: param, // 请求参数 }).then((res) => { return new Promise((resolve) => { resolve(res) }) }) }
然后我们在App.vue中添加一个点击方法,用作调起请求用的。
<template> <div id="app"> <img alt="Vue logo" src="./assets/logo.png"> <el-button type="primary" @click="getData">测试按钮</el-button> <HelloWorld msg="Welcome to Your Vue.js App"/> </div> </template> <script> import HelloWorld from './components/HelloWorld.vue' export default { name: 'App', components: { HelloWorld }, methods: { getData() { this.$ajax('login/authApi/loginApi', {}).then(res => { console.log(res) }).catch(rej => { console.log(rej) }) } } } </script> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
点击测试按钮,就可以正常调用网络请求的方法。
本章内容就到这里结束吧,下一章为大家讲一下如何去实现权限管理。