最近在做公司的一個后台管理項目,用了vue admin來搭建項目的前端,本人也是個vue的新手,很多都不太理解,各種百度,才搞懂了整個登陸流程接口的替換,因此在此記錄一下。
所有的重點我都會在代碼中的注釋里說明。
一、登陸接口的替換
//這段代碼是src/api/user.js中的代碼
import request from '@/utils/request'
export function login(data) {
return request({
// 這里替換成自己的登陸接口,下面的也是一樣
url: '/login',
method: 'post',
data
})
}
export function getInfo(otherQuery) {
return request({
url: '/getInfo',
method: 'get',
params: otherQuery
})
}
export function logout() {
return request({
url: '/vue-admin-template/user/logout',
method: 'post'
})
}
login()方法那里,url只需要替換成自己登陸接口地址就行,不要帶上接口的IP地址或者域名。然后,頂部我們注意到,有一個import request from '@/utils/request'
,這是request文件,也就是我們request方法的定義,讓我們來看下文件里的一段代碼:
const service = axios.create({
// 這里替換成自己接口的服務器地址,並且把.env.development中的VUE_APP_BASE_API參數置為空
baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
timeout: 5000 // request timeout
})
可以看到,baseURL那里需要換成自己的接口地址才算全部替換完成。
二、接口調用以及response的處理
可能有些小伙伴會覺得奇怪,怎么換了接口還是登陸不進去頁面呢?這是因為還沒調用接口方法。
整個登陸流程的接口調用,包括登陸、獲取用戶信息、登出等步驟,都在@/store/modules/user中進行了調用,而各種登陸信息的存儲,也都在此文件中操作。我們來看下代碼:
import { login, logout, getInfo } from '@/api/user'//這里便引用了我們說的接口方法文件,即第一點登陸接口替換那部分文件代碼
import { getToken, setToken, removeToken } from '@/utils/auth'//這個文件不用管,是已經封裝好的關於token的幾個方法
import router, { resetRouter } from '@/router'
//state和mutations里按需進行刪除和添加,比如說,如果你需要存儲一個用戶id字段用於后續接口,直接添加進來,用this.$store.state.user.id便可在后續文件中引用
const state = {
token: getToken(),
name: '',
avatar: '',
introduction: '',
roles: []
}
const mutations = {
SET_TOKEN: (state, token) => {
state.token = token
},
SET_INTRODUCTION: (state, introduction) => {
state.introduction = introduction
},
SET_NAME: (state, name) => {
state.name = name
},
SET_AVATAR: (state, avatar) => {
state.avatar = avatar
},
SET_ROLES: (state, roles) => {
state.roles = roles
}
}
const actions = {
login({ commit }, userInfo) {
const { username, password } = userInfo
return new Promise((resolve, reject) => {
//此處的login()方法便是@/api/user中的login()方法,username和password根據后台提供的接口進行參數替換
login({ username: username.trim(), password: password }).then(response => {
const { data } = response
commit('SET_TOKEN', data.token)
setToken(data.token)
resolve()
}).catch(error => {
reject(error)
})
})
},
getInfo({ commit, state }) {
return new Promise((resolve, reject) => {
getInfo(state.token).then(response => {//如果前期不需要用戶信息,可直接把大括號外部注釋掉,留大括號里的內容(即const開頭那部分內容),data用假數據
const { data } = response
if (!data) {
reject('Verification failed, please Login again.')
}
const { roles, name, avatar, introduction } = data
if (!roles || roles.length <= 0) {
reject('getInfo: roles must be a non-null array!')
}
commit('SET_ROLES', roles)
commit('SET_NAME', name)
commit('SET_AVATAR', avatar)
commit('SET_INTRODUCTION', introduction)
resolve(data)
}).catch(error => {
reject(error)
})
})
},
logout({ commit, state, dispatch }) {
return new Promise((resolve, reject) => {
logout(state.token).then(() => {//這里也是同理,不需要便注釋,留下大括號內的內容同樣可以清除token登出
commit('SET_TOKEN', '')
commit('SET_ROLES', [])
removeToken()
resetRouter()
dispatch('tagsView/delAllViews', null, { root: true })
resolve()
}).catch(error => {
reject(error)
})
})
},
resetToken({ commit }) {
return new Promise(resolve => {
commit('SET_TOKEN', '')
commit('SET_ROLES', [])
removeToken()
resolve()
})
},
}
export default {
namespaced: true,
state,
mutations,
actions
}
登陸流程的接口調用流程改完之后,我們便可以進去首頁了。
如果還是進不去,便到login.vue和@/utils/validate中修改驗證信息即可。
接下來是返回數據response的處理。我們先來看看request文件的剩余部分:
service.interceptors.request.use(
config => {
// 這里是將獲取到的token放在請求頭里
if (store.getters.token) {
// 每一個request都將帶上token,這里的X-Token可根據后端的設定或者瀏覽器的要求來改
config.headers['X-Token'] = getToken()
}
return config
},
error => {
console.log(error)
return Promise.reject(error)
}
)
service.interceptors.response.use(
response => {
const res = response.data
// 這里記得將code改為自己的code
if (res.code !== 20000) {
Message({
message: res.message || 'Error',
type: 'error',
// 這是請求的時長,可以設置的長一些,不然請求時間久的話,超過這個時長就會報錯
duration: 5 * 1000
})
// 這里也可按自己的需要去更改
if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', {
confirmButtonText: 'Re-Login',
cancelButtonText: 'Cancel',
type: 'warning'
}).then(() => {
store.dispatch('user/resetToken').then(() => {
location.reload()
})
})
}
return Promise.reject(new Error(res.message || 'Error'))
} else {
return res
}
},
error => {
console.log('err' + error)
Message({
message: error.message,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
}
)
需要注意的是,上述代碼中的response是包含了請求頭在內的response,而res只是取了數據部分,如果不進行修改,后續接口的調用是獲取不到headers的。如果后續需要獲取請求頭,也要在這里按需修改。
三、其他接口的調用及axios踩坑
上面已經將登陸部分接口相關的內容全部講完,接下來是講述除登陸以外的接口我們要怎么去調用。
其實看完整的vue-element-admin模版便可以發現,所有的接口信息都儲存在@/api之下的js文件中,而vue文件中如果要調用的話,則可按以下步驟來:
//@/api/article是api文件夾下的article.js文件,存放了fetchList這個接口方法,用import引入這個方法
import { fetchList } from '@/api/article'
methods: {
getList() {
this.listLoading = true
//這里便可引用fetchList方法進行接口調用
fetchList(this.listQuery).then(response => {
this.list = response.data.items
this.total = response.data.total
this.listLoading = false
})
}
}
看完接口調用步驟之后,我要說一下新手容易踩的一個axios坑,拿登陸和用戶信息接口為例來講:
export function login(data) {
return request({
url: '/vue-element-admin/user/login',
method: 'post',
data
})
}
export function getInfo(token) {
return request({
url: '/vue-element-admin/user/info',
method: 'get',
params: { token }
})
}
我們可以看到,登陸接口是post方法,而參數傳遞如果只是一個data的話,其實是相當於用data:data這樣的形式來傳遞的參數。
而在axios中,data:xxx是表示傳遞的參數不采用拼接的方式傳遞,params:xxx則相反。
這點讓還是新手的我踩了不少坑,因為我在這里特別標注以下,以防有像我這樣的新手再踩坑。