3.请求处理
项目中使用mock-server开启本地服务API接口,使得前端与后端项目都可单独进行开发;模拟后端接口的配置文件统一放置在@/mock/
文件夹下面
3.1使用mockjs模拟后端API
Copy index.js ##mock配置文件
mock-server.js ##mock本地服务配置
table.js
user.js ##用户的后端API响应数据
utils.js
3.2模拟后端接口
Copy module.exports = [
// user login
{
url: "/vue-admin-template/user/login",
type: "post",
response: config => {
const { username } = config.body; //获取req.body.username
const token = tokens[username]; //获取用户的tookens
// mock error
if (!token) {
return {
code: 60204,
message: "Account and password are incorrect."
};
}
return {
code: 20000,
data: token //验证成功,返回token数据
};
}
}]
3.3axios发起ajax请求
使用vuex进行状态管理,配置了请求拦截器
getToken
在auth.js
中配置好了,这个文件中还配置了一系列的对token的操作函数
Copy // request interceptor
service.interceptors.request.use(
config => {
// do something before request is sent
if (store.getters.token) {
// let each request carry token
// ['X-Token'] is a custom headers key
// please modify it according to the actual situation
config.headers['X-Token'] = getToken() //设置header中的token
}
return config
},
error => {
// do something with request error
console.log(error) // for debug
return Promise.reject(error)
}
)
配置响应拦截器
当后端正常响应,并且返回错误代码时,使用Promise返回一个reject,在路由处用catch进行捕获
Copy service.interceptors.response.use( response => {
const res = response.data
// if the custom code is not 20000, it is judged as an error.
if (res.code !== 20000) {
Message({
message: res.message || 'Error',
type: 'error',
duration: 5 * 1000
})
// 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
// to re-login
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) // for debug
Message({
message: error.message,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
}
)
export default service
4.前端路由跳转
@/src/layout/
目录下配置了页面的布局,因为vue-element-admin是一个后台管理系统,因此也仅仅只含有一个布局;
在@/src/router/
目录下配置了整个前端路由;在路由跳转时,采用transition
动画特效
Copy <section class="app-main">
<transition name="fade-transform" mode="out-in">
<router-view :key="key" />
</transition>
</section>
5.组件使用封装好的API
在@/src/api/table 目录下就封装了一个
getlsit()`函数,用于直接操作request的请求
Copy export function getList(params) {
return request({
url: "/vue-admin-template/table/li1st1",
method: "get",
params
});
}
错误的处理,在错误到达组件之前就已经被axios响应拦截器给处理掉了,但是在组件那会返回一个Promise.reject对象;不对它进行处理也没有关系,但是会在后台打印一个Promise错误
Copy createError.js?2d83:16 Uncaught (in promise) Error: Request failed with status code 404
at createError (createError.js?2d83:16)
at settle (settle.js?467f:18)
at XMLHttpRequest.handleLoad (xhr.js?b50d:59)
6.Vuex用于组件间的通信
Copy const getDefaultState = () => {
return {
token: getToken(),
name: '',
avatar: ''
}
}
const state = getDefaultState()
定义mutations方法
这些数据都是从cookie中获得的
Copy const mutations = {
RESET_STATE: (state) => {
Object.assign(state, getDefaultState())
},
SET_TOKEN: (state, token) => {
state.token = token
},
SET_NAME: (state, name) => {
state.name = name
},
SET_AVATAR: (state, avatar) => {
state.avatar = avatar
}
}
定义异步操作
使用action进行异步操作,例如登录操作;这个操作在发起Ajax请求得到数据后返回一个Promise对象
Copy const actions = {
// user login
login({ commit }, userInfo) {
const { username, password } = userInfo
return new Promise((resolve, reject) => {
login({ username: username.trim(), password: password }).then(response => {
const { data } = response
commit('SET_TOKEN', data.token)
setToken(data.token)
resolve()
}).catch(error => {
reject(error)
})
})
},
组合多个module
在getters中指定封装在根store的state
Copy const store = new Vuex.Store({
modules: {
app,
settings,
user
},
getters
})
参考