一个基于vuecli3和vue-admin-template改造的响应式后台管理系统
一、使用mockjs
运用mock来模拟后台接口能更加便捷高效的进行前端开发,在这里我只是简单的模拟后台接口,返回一些简单的数据,更多功能可以参考mockjs官网,写的很详细的噢~
1.1 引入mockjs
npm install --save-dev mockjs 复制代码
1.2 在mainjs引入
import '@/assets/mock' 复制代码
1.3 定义mock文件
在assets文件夹下创建mock文件夹,并创建index.js
import Mock from 'mockjs' // 获取 mock.Random 对象 const Random = Mock.Random // mock一组数据 const loginData = () => { const data = { token: Random.string(10) } return { data: data, resultCode: 1, resultMessage: 'success' } } Mock.mock('/apiReplace/login', 'post', loginData) Mock.mock('/apiReplace/loginByVin', 'post', loginData) 复制代码
二、Api地址的统一定义和处理
在assets目录下新建http文件夹,用来存放请求后端接口的一些配置文件。
后台的接口地址需要一个文件进行统一的定义,然后全局声明之后,可以在项目里任意使用
2.1 定义接口url
根目录新建http/apiUrl.js,定义接口url
/* 全局定义接口url */ // host头,这里我们要使用代理,所以定义的字符串apiReplace是用来进行反向代理时的标记字符串。 const apiHost = '/apiReplace/' // 密码登录 const Login = `${apiHost}login` // 短信登录 const LoginByVin = `${apiHost}loginByVin` export default { Login, LoginByVin } 复制代码
2.2 在mainjs引入
import Api from '@/assets/http/apiUrl' Vue.prototype.API = Api 复制代码
这样我们就能在项目里通过this.API.xxx去获取相应的接口url了
三、axios工具类的封装
当业务逻辑复杂的时候,写起来会比较繁琐,后期维护更加不方便,每次都要定位到具体位置去一个个替换修改。所以在axios请求时再封装一层就显得尤为重要。
3.1 axios拦截器
我们经常需要在发起请求之前,修改请求头或者是在接口请求成功之后进行数据的预处理,axios给我们提供了request和response的拦截器,让我们可以在这里头进行一些业务操作。
在http文件夹下新建service.js文件
- 在文件头引入需要的模块并创建axios实例
import axios from 'axios' import { Message } from 'element-ui' import { getToken } from '@/assets/utils/token' import router from '@/router' import store from '@/store' // 创建axios实例 const service = axios.create({ baseURL: process.env.BASE_API, // api 的 base_url timeout: 10000 // 请求超时时间 }) 复制代码
- request拦截器,设置请求头参数,如用户标识token等
// request拦截器 service.interceptors.request.use( config => { // 在此处设置请求头参数 const token = getToken() if (token != null) { config.headers['Authorization'] = token } return config }, error => { // Do something with request error console.log(error) // for debug return Promise.reject(error) } ) 复制代码
- response 拦截器,请求接口得到相应后,需要进行一些预处理
service.interceptors.response.use( response => { return response // 返回请求成功结果,status=200 }, err => { // 请求失败时,即status!=200 if (err && err.response) { switch (err.response.status) { case 400: err.message = '错误请求' break case 401: err.message = '未授权,请重新登录' break case 403: err.message = '禁止访问' break case 404: err.message = '请求错误,未找到该资源' break case 405: err.message = '请求方法未允许' break case 408: err.message = '请求超时' break case 413: err.message = '上传文件过大' break case 500: err.message = '服务器端出错' break case 501: err.message = '网络未实现' break case 502: err.message = '网络错误' break case 503: err.message = '服务不可用' break case 504: err.message = '网络超时' break case 505: err.message = 'http版本不支持该请求' break default: err.message = `连接错误,${err.response.msg}` } } else { err.message = '当前网络状态不佳' } Message.closeAll() Message({ message: err.message || '数据解析出错', type: 'error', customClass: 'errorloginwidth', duration: '3000' }) // 如果是token过期的状况,退出登陆重定向到登陆页 if (err.response && err.response.status === 401) { store.dispatch('FedLogOut') // 前端登出,移除token router.replace({ path: `/login?redirect=${window.location.href.split(/[#]/g)[1]}` }) } return Promise.reject(err) } ) 复制代码
- 导出模块
export default service 复制代码
3.2 axios请求封装
3.2-1 引入Qs库来格式化数据
npm install --save-dev qs 复制代码
3.2-2 分别处理get和post请求,get和post请求携带参数的方式是不同的,所以要分开定义
3.2-3 提供请求成功和失败后的回调函数,以便页面里进行相关逻辑的书写
直接贴上我定义的文件:
这里我只定义了一个基本的httpRequest方法,后期如果需要定义并发调用、或者其他情景下的方法,都可以自行增加。
/* 封装axios请求 */ /* 用法示例:(*)为必须参数 this.$request.httpRequest({ headers: false, // 是否格式化参数 (*)method: 'post', // 请求方式,post或get (*)url: this.API.ResetPassword, // 请求地址,请求地址的配置在@/api/apiUrl.js noLoading: true, // 是否显示全局Loading遮罩,默认每个请求都显示遮罩,即默认不设置该参数。如果需要某个请求不加遮罩,就设置noLoading: true即可 returnFullData: true, // 是否返回完整数据,例如接口返回的数据格式为{ code:0, data: [], meaasge:''},则默认请求成功之后的回调函数的参数为data:[],如果设置returnFullData: true,则回调参数为{ code:0, data: [], meaasge:''} hideErrorMsg: true, // 是否展示错误提示 (*)params: {}, // 请求参数,object类型 (*)success: (data) => { // 请求成功之后的回调函数,data是回调参数 // 在这里写请求成功后的逻辑 }, error: (err) => { 请求不成功之后的回调函数,data是回调参数 // 在这里写请求报错后的逻辑 } }) */ import service from 'http://www.toutiao.com/a6734644873128837644/service' import { Message, Loading } from 'element-ui' import Qs from 'qs' function requestMethods(options) { return new Promise((resolve, reject) => { try { switch (options.method) { case 'post': if (options.headers) { resolve( service({ url: options.url, method: 'post', data: options.params }) ) } else { resolve( service({ url: options.url, method: 'post', data: Qs.stringify(options.params) }) ) } break case 'get': resolve( service({ url: options.url, method: 'get', params: options.params }) ) break default: // 默认是get调用 resolve( service({ url: options.url, method: 'get', params: options.params }) ) break } } catch (e) { Message({ message: 'HTTP请求方法出错!', type: 'error', duration: 3 * 1000 }) reject('methods error!') } }) } function httpRequest(options = {}) { let loading if (!options.noLoading) { // 启用全局loading loading = Loading.service({ lock: true, text: '加载中...', spinner: 'el-icon-loading', background: 'rgba(0, 0, 0, 0.7)' }) } requestMethods(options).then(response => { // 成功返回结果的逻辑。根据接口定义的数据返回格式 修改判断条件 const data = response.data if (data.resultCode === '1' || data.resultCode === 1) { // 成功 const result = options.returnFullData ? data : data.data // 返回完整数据结构还是只返回有效数据 options.success(result) } else { if (!options.hideErrorMsg) { // 失败 let errorMsg = data.hasOwnProperty('resultMessage') ? data.resultMessage : '数据解析错误' switch (data.resultCode) { case '401': errorMsg = '暂无操作权限' break } Message.closeAll() Message({ message: errorMsg, type: 'error', customClass: 'errorloginwidth', duration: 3000 }) } options.error(data) } if (!options.noLoading) { // loading完毕 loading.close() } }).catch(e => { options.error(e.response) }) } export default { httpRequest } 复制代码
3.3 在mainjs引入
import Request from '@/assets/http' Vue.prototype.$request = Request 复制代码
这样就可以在项目中通过this.$request去调用接口啦~ 基础调用很简单,只用酱紫:
this.$request.httpRequest({ url: this.API.SendSms, params: {}, success: (data) => { // 在这里写成功调用接口后的逻辑 } }) 复制代码
点击发送验证码,开始一分钟倒计时并调用发送短信验证码的接口
<!--html部分--> <el-form-item prop="code" class="login-input-item"> <span class="svg-container"> <svg-icon icon-class="password" /> </span> <el-input v-model="loginForm.code" autocomplete="off" type="number" name="code" placeholder="验证码" maxlength="4" style="padding-left: 45px" @keyup.enter.native="handleLogin" /> <span :style="{ cursor: isOvertime ? 'default' : 'pointer'}" class="code" @click="sendMessage"> {{ word }} </span> </el-form-item> // js部分 sendMessage() { if (this.isOvertime) { return false // 还在倒计时,不往下执行 } const params = { 'phone': this.loginForm.phoneNumber } if (!params.phone) { this.$message.closeAll() this.$message.error('请先输入手机号码') return } if (!isvalidPhoneNumber(params.phone)) { this.$message.closeAll() this.$message.error('手机号格式不正确') return } this.loading = true this.$request.httpRequest({ method: 'post', url: this.API.SendSms, returnFullData: true, noLoading: true, hideErrorMsg: true, params: params, success: (data) => { this.loading = false this.$message.closeAll() this.$message.success('验证码发送成功,请留意手机短信') const sendTimer = setInterval(() => { this.isOvertime = true this.word = `${this.time}s后重新获取` this.time-- if (this.time <= 0) { this.isOvertime = false this.time = 60 clearInterval(sendTimer) this.word = '获取验证码' } }, 1000) }, error: (e) => { this.loading = false const errorMsg = e.hasOwnProperty('resultMessage') ? e.resultMessage : '获取验证码失败' this.$message({ message: errorMsg, type: 'error', customClass: 'errorloginwidth', duration: 3000 }) } }) }
点赞+转发,让更多的人也能看到这篇内容(收藏不点赞,都是耍流氓-_-)
关注 {我},享受文章首发体验!
每周重点攻克一个前端技术难点。更多精彩前端内容私信 我 回复“教程”!
2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/15097.html