这篇文章主要介绍“Vue项目中Api的组织以及返回数据处理的操作”,在日常操作中,相信很多人在Vue项目中Api的组织以及返回数据处理的操作问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Vue项目中Api的组织以及返回数据处理的操作”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
项目中的所有Api配置放在一个文件中,便于查找和修改,Api的版本从配置文件(config.js)中读取,采用 apiPrefix + url 的形式组成。
在配置文件中,Api 的配置采用 Http请求方式 url 的方式,默认情况下 GET 可以不写,请求方式统一采用大写形式,动态参数采用 : 占位符 的形式。
// services/api.js export default { login: 'POST /login', logout: '/logout', queryUser: '/user/:id' }
然后需要一个方法在解析上面的Api配置
// services/index.js import request from '../utils/request' import api from './api' const gen = params => { let url = params let method = 'GET' const paramsArr = params.split(' ') if (paramsArr.length === 2) { method = paramsArr[0] url = paramsArr[1] } return data => { return request({ url, data, method }) } } const apiFunc = {} for (const key in api) { apiFunc[key] = gen(api[key]) } export default apiFunc
上面代码中的 request 是封装 axios 后暴露出来的方法,代码如下:
// utils/request.js import axios from 'axios' import store from '../store' import { apiPrefix } from './config' import { Message, MessageBox } from 'element-ui' let cancel const CancelToken = axios.CancelToken const service = axios.create({ baseURL: apiPrefix, timeout: 3000, cancelToken: new CancelToken(c => cancel = c) }) service.interceptors.response.use( response => { const resType = response.config.responseType const res = response.data // 二进制文件 if (resType && resType !== 'json') { const filename = response.headers['content-disposition'].split('filename=')[1] return { filename, blob: res } } if (res.code !== 200) { // 登录失效 if (res.code === 401) { let timer = null // 取消后续请求 cancel(res.msg) // 更新store及localStorage状态 store.commit('user/RESET_LOGIN_STATE', false) MessageBox.confirm('登录已失效,请重新登录', '提示', { confirmButtonText: '确定', showClose: false, showCancelButton: false, type: 'warning' }).then(() => { clearTimeout(timer) reload() }) timer = setTimeout(reload, 1000) } const errMsg = res.msg || '服务器返回错误' popupMsg(errMsg) return Promise.reject(errMsg) } return res }, error => { // 超时 if (error.message.includes('timeout')) { const errMsg = '网络请求超时, 请稍后重试' popupMsg(errMsg) cancel(errMsg) } } ) function reload() { window.location.href = `${window.location.origin}/#/login` window.location.reload() } function popupMsg(msg, sec = 5000) { Message({ message: msg, type: 'error', duration: sec }) } export default service
在封装的过程中处理了 网络请求超时 、 下载表数据时后端直接返回二进制文件的情况 、 登录失效后取消后续接口请求 。
在开发后台管理系统项目时,基本都会用到Vuex。在实际的开发过程中通常会按功能进行分 module ,在 xx.vue 文件中直接通过 mapActions 来注入带副作用的方法。
// store/common.js import service from '../services' const actions = { async login(data) { const res = await service.login(data) return Promise.resolve(res) } } export default { namespaced: true, state: {}, getters: {}, mutations: {}, actions }
其实在上面的 apiFunc 方法中是可以直接调用返回结果,为什么在这里还多此一举呢?是因为有些时候一个接口的参数需要加工处理,在每个页面处理明显代码冗余,修改不方便,同时也会出现获取同样的数据但是不同的页面后端给到的是不同的接口,这里就可以做到根据参数来明确需要哪个接口。
在封装的 action 中,有些时候是不需要返回数据(Promise),因为完全可以整个页面的数据状态全部放在state中,接收到数据后直接通过 commit 一个 mutation 来修改 state ,在页面中直接把所有的数通过 mapState 或者直接 this.$store.state.xx 来访问。如果想要绑定state中的状态到 v-model ,可以在 computed 中定义 get 和 set 来实现,例如:
export default { computed: { dateType: { get() { return this.$store.state.device.dateType }, set(val) { // 一些处理,比如根据日、周、月来动态改变`el-datep-icker`的配置 } } } }
在项目中不建议把页面中的所有状态全部放在vuex中处理,除了一些全局状态和一些组件之间具有联动效应的。因为在当前路由切换到其它路由, vuex中 state 的数据是没有被重置的,再切回来会发现原有的数据并没有变化等问题。而且一旦在定义 state 时嵌套太多,重置就很麻烦了。
还有一个问题在使用 echarts 时,根据一些筛选来动态改变图表绘制时,会发现从 mapState 和 getters 中并不能获取到最新的数据,还得手动写一长串的 this.$store.state.moduleA.moduleB.xxx.state
,当然我们也可以使用vuex提供的便捷映射方法 const { mapState } = createNamespacedHelper('some/nested/module')
,但是有一个问题是一旦同一个页面引用的 module 很多,就涉及到取多个不同的别名问题了。
在项目中使用方式如下:
import { mapActions } from 'vuex' import apiFunc from '../services' export default { methods: { ...mapActions('common', [ 'login' ]), async onLogin() { const params = {} const res = await apiFunc.login(params) } } }
注意在使用 async/await 时如果外层的错误没有捕捉到,最好加一层 try...catch... 。
到此,关于“Vue项目中Api的组织以及返回数据处理的操作”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。