Vue項(xiàng)目中Api的組織和返回?cái)?shù)據(jù)處理的操作
項(xiàng)目中的所有Api配置放在一個(gè)文件中,便于查找和修改,Api的版本從配置文件(config.js)中讀取,采用 apiPrefix + url 的形式組成。
在配置文件中,Api 的配置采用 Http請(qǐng)求方式 url 的方式,默認(rèn)情況下 GET 可以不寫,請(qǐng)求方式統(tǒng)一采用大寫形式,動(dòng)態(tài)參數(shù)采用 : 占位符 的形式。
// services/api.js
export default {
login: 'POST /login',
logout: '/logout',
queryUser: '/user/:id'
}
然后需要一個(gè)方法在解析上面的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
// 二進(jìn)制文件
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
// 取消后續(xù)請(qǐng)求
cancel(res.msg)
// 更新store及l(fā)ocalStorage狀態(tài)
store.commit('user/RESET_LOGIN_STATE', false)
MessageBox.confirm('登錄已失效,請(qǐng)重新登錄', '提示', {
confirmButtonText: '確定',
showClose: false,
showCancelButton: false,
type: 'warning'
}).then(() => {
clearTimeout(timer)
reload()
})
timer = setTimeout(reload, 1000)
}
const errMsg = res.msg || '服務(wù)器返回錯(cuò)誤'
popupMsg(errMsg)
return Promise.reject(errMsg)
}
return res
},
error => {
// 超時(shí)
if (error.message.includes('timeout')) {
const errMsg = '網(wǎng)絡(luò)請(qǐng)求超時(shí), 請(qǐng)稍后重試'
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
在封裝的過程中處理了 網(wǎng)絡(luò)請(qǐng)求超時(shí) 、 下載表數(shù)據(jù)時(shí)后端直接返回二進(jìn)制文件的情況 、 登錄失效后取消后續(xù)接口請(qǐng)求 。
在開發(fā)后臺(tái)管理系統(tǒng)項(xiàng)目時(shí),基本都會(huì)用到Vuex。在實(shí)際的開發(fā)過程中通常會(huì)按功能進(jìn)行分 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
}
其實(shí)在上面的 apiFunc 方法中是可以直接調(diào)用返回結(jié)果,為什么在這里還多此一舉呢?是因?yàn)橛行r(shí)候一個(gè)接口的參數(shù)需要加工處理,在每個(gè)頁面處理明顯代碼冗余,修改不方便,同時(shí)也會(huì)出現(xiàn)獲取同樣的數(shù)據(jù)但是不同的頁面后端給到的是不同的接口,這里就可以做到根據(jù)參數(shù)來明確需要哪個(gè)接口。
在封裝的 action 中,有些時(shí)候是不需要返回?cái)?shù)據(jù)(Promise),因?yàn)橥耆梢哉麄€(gè)頁面的數(shù)據(jù)狀態(tài)全部放在state中,接收到數(shù)據(jù)后直接通過 commit 一個(gè) mutation 來修改 state ,在頁面中直接把所有的數(shù)通過 mapState 或者直接 this.$store.state.xx 來訪問。如果想要綁定state中的狀態(tài)到 v-model ,可以在 computed 中定義 get 和 set 來實(shí)現(xiàn),例如:
export default {
computed: {
dateType: {
get() {
return this.$store.state.device.dateType
},
set(val) {
// 一些處理,比如根據(jù)日、周、月來動(dòng)態(tài)改變`el-datep-icker`的配置
}
}
}
}
在項(xiàng)目中不建議把頁面中的所有狀態(tài)全部放在vuex中處理,除了一些全局狀態(tài)和一些組件之間具有聯(lián)動(dòng)效應(yīng)的。因?yàn)樵诋?dāng)前路由切換到其它路由, vuex中 state 的數(shù)據(jù)是沒有被重置的,再切回來會(huì)發(fā)現(xiàn)原有的數(shù)據(jù)并沒有變化等問題。而且一旦在定義 state 時(shí)嵌套太多,重置就很麻煩了。
還有一個(gè)問題在使用 echarts 時(shí),根據(jù)一些篩選來動(dòng)態(tài)改變圖表繪制時(shí),會(huì)發(fā)現(xiàn)從 mapState 和 getters 中并不能獲取到最新的數(shù)據(jù),還得手動(dòng)寫一長串的 this.$store.state.moduleA.moduleB.xxx.state ,當(dāng)然我們也可以使用vuex提供的便捷映射方法 const { mapState } = createNamespacedHelper('some/nested/module') ,但是有一個(gè)問題是一旦同一個(gè)頁面引用的 module 很多,就涉及到取多個(gè)不同的別名問題了。
在項(xiàng)目中使用方式如下:
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 時(shí)如果外層的錯(cuò)誤沒有捕捉到,最好加一層 try...catch... 。
- vue設(shè)置全局訪問接口API地址操作
- vue項(xiàng)目接口管理,所有接口都在apis文件夾中統(tǒng)一管理操作
- VUE使用axios調(diào)用后臺(tái)API接口的方法
- Vue3新特性之在Composition API中使用CSS Modules
- Vue.js中Line第三方登錄api的實(shí)現(xiàn)代碼
- 使用Vue Composition API寫出清晰、可擴(kuò)展的表單實(shí)現(xiàn)
- 精讀《Vue3.0 Function API》
- 淺談Vue3.0新版API之composition-api入坑指南
- vue 使用外部JS與調(diào)用原生API操作示例
- vue 更改連接后臺(tái)的api示例
- 淺析 Vue 3.0 的組裝式 API(一)
相關(guān)文章
vuex根據(jù)不同的用戶權(quán)限展示不同的路由列表功能
最近接到一個(gè)新的需求,要求將系統(tǒng)的用戶進(jìn)行分類,用戶登陸后根據(jù)不同的用戶權(quán)限展示不同的功能列表。這篇文章主要介紹了vuex根據(jù)不同的用戶權(quán)限展示不同的路由列表,需要的朋友可以參考下2019-09-09
Ant?Design?Vue?修改表格頭部樣式的詳細(xì)代碼
這篇文章主要介紹了Ant?Design?Vue?修改表格頭部樣式,首先用到的是customHeaderRow這個(gè)API,類型是一個(gè)函數(shù),本文通過完整代碼給大家詳細(xì)講解,需要的朋友可以參考下2022-10-10
Vue實(shí)現(xiàn)父子組件頁面刷新的幾種常用方法
很多時(shí)候我們?cè)诓僮鬟^頁面時(shí)候,特別是增刪改操作之后,數(shù)據(jù)會(huì)有所改變,本文主要介紹了Vue實(shí)現(xiàn)父子組件頁面刷新的幾種常用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04
vue-seamless-scroll 實(shí)現(xiàn)簡單自動(dòng)無縫滾動(dòng)且添加對(duì)應(yīng)點(diǎn)擊事件的簡單整理
vue-seamless-scroll是一個(gè)基于Vue.js的簡單無縫滾動(dòng)組件, 基于requestAnimationFrame實(shí)現(xiàn),配置多滿足多樣需求,目前支持上下左右無縫滾動(dòng),單步滾動(dòng),及支持水平方向的手動(dòng)切換功能,本節(jié)介紹,vue添加 vue-seamless-scroll實(shí)現(xiàn)自動(dòng)無縫滾動(dòng)的效果,并對(duì)應(yīng)添加點(diǎn)擊事件2023-01-01
vue時(shí)間戳和時(shí)間的相互轉(zhuǎn)換方式
本文通過示例代碼介紹了vue時(shí)間戳和時(shí)間的相互轉(zhuǎn)換方式,通過場(chǎng)景分析介紹了vue3使用組合式api將時(shí)間戳格式轉(zhuǎn)換成時(shí)間格式(2023年09月28日 10:00),感興趣的朋友一起看看吧2023-12-12
vue data對(duì)象重新賦值無效(未更改)的解決方式
這篇文章主要介紹了vue data對(duì)象重新賦值無效(未更改)的解決方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-07-07
使用vue2.6實(shí)現(xiàn)抖音【時(shí)間輪盤】屏保效果附源碼
前段時(shí)間看抖音,有人用時(shí)間輪盤作為動(dòng)態(tài)的桌面壁紙,一時(shí)間成為全網(wǎng)最火的電腦屏保,后來小米等運(yùn)用市場(chǎng)也出現(xiàn)了【時(shí)間輪盤】,有點(diǎn)像五行八卦,感覺很好玩,于是突發(fā)奇想,自己寫一個(gè)網(wǎng)頁版小DEMO玩玩,需要的朋友可以參考下2019-04-04
Vue使用vm.$set()解決對(duì)象新增屬性不能響應(yīng)的問題
這篇文章主要介紹了Vue使用vm.$set()解決對(duì)象新增屬性不能響應(yīng)的問題,為了解決這個(gè)問題,Vue提供了一個(gè)特殊的方法vm.$set(object, propertyName, value),也可以使用全局的Vue.set(object, propertyName, value)方法,需要的朋友可以參考下2023-05-05

