有些朋友说,一个交互过程东一下,西一下的,不知所以然,所以在此补一下vue-element-admin的整体框架结构,并细说一下交互的过程,包括跨域问题!
一:首先是整体框架结构:
├── build // 构建相关(build.js/webpack等)
├── config // 配置相关 (代理环境配置/local端口配置等等)
├── dist //打包后的dist文件 (供发布到线上使用)
├── src // 源代码
│ ├── api // 所有请求
│ ├── service //请求(和api相同,我习惯写到这里,更语义化)
│ ├── assets // 主题 字体等静态资源
│ ├── components // 全局公用组件
│ ├── directive // 全局指令
│ ├── filters // 全局 filter
│ ├── icons // 项目所有 svg icons
│ ├── lang // 国际化 language
│ ├── mock // 项目mock 模拟数据
│ ├── router // 路由
│ ├── store // 全局 store管理
│ ├── styles // 全局样式
│ ├── utils // 全局公用方法 (可以封装一下cookie或者request的一些函数)
│ ├── vendor // 公用vendor
│ ├── views // views 所有页面 (一般要和api/service起名相同,方便迭代)
│ ├── App.vue // 入口页面
│ ├── main.js // 入口文件 加载组件 初始化等
│ └── permission.js // 权限管理 (根据权限配置路由)
├── static // 第三方不打包资源
│ └── Tinymce // 富文本
├── .babelrc // babel-loader 配置
├── .eslintrc.js // eslint 配置项
├── .gitignore // git 忽略项
├── .travis.yml // 自动化CI配置
├── favicon.ico // favicon图标
├── index.html // html模板
└── package.json // package.json
ok,我想框架结构上在上面已经写的很详细了,下面说一下一个交互的具体实现流程吧
1.首先是在view页面进行交互提交,这个就不多说了,页面级的
2.点击提交后会调用api/service里的请求函数
3.请求函数会调用之前封装好的axsio请求函数
4.接收后端返回的response然后进行view的data渲染
下面附代码细说一下
// views/ceshi
<button @click="ceshia">举例测试</button>
import { ceshi } from '@service/ceshi'
export default {
data() {
list: '',
tokon: 'suibian'
},
methods: {
ceshia() {
ceshi(this.tokon).then(res => {
this.list = res.data.list
})
}
}
}
其中的from的ceshi.js函数里如下写
import request from '@utils/request' //引入request中封装的请求函数,包括请求拦截器,response,error等操作
export function ceshi(data) {
return ruquest ({
url: 'i/suibian/suibian/suibian',
method: 'post',
data
})
}
之后是调用utils/request,里面这样写
import store form '@store' //引入vuex,因为需要在这里根据角色获取路由id,并在store中进行更改
// create an axios instance
const service = axios.create({
baseURL: process.env.BASE_API, // api的base_url
timeout: 5000 // request timeout
})
// request interceptor
service.interceptors.request.use(
config => {
// Do something before request is sent
return config
},
error => {
// Do something with request error
console.log(error) // for debug
Promise.reject(error)
}
)
// respone interceptor
service.interceptors.response.use(
// response => response,
/**
* 下面的注释为通过在response里,自定义code来标示请求状态
* 当code返回如下情况则说明权限有问题,登出并返回到登录页
* 如想通过xmlhttprequest来状态码标识 逻辑可写在下面error中
* 以下代码均为样例,请结合自生需求加以修改,若不需要,则可删除
*/
response => {
const res = response.data
if (res.error_code !== 0) {
Message({
message: res.error_msg,
type: 'error',
duration: 2 * 1000
})
// 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了;
if (res.error_code === 10009) {
// 请自行在引入 MessageBox
// import { Message, MessageBox } from 'element-ui'
MessageBox.confirm('你已被登出,可以取消继续留在该页面,或者重新登录', '确定登出', {
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
store.dispatch('FedLogOut').then(() => {
location.reload() // 为了重新实例化vue-router对象 避免bug
})
})
}
return Promise.reject(response.data)
} else {
return response.data
}
},
error => {
const reg = new RegExp(/504|503|500|400/)
if (reg.test(error.message) || error.message === 'Network Error') {
Message({
message: '网络断了,请检查网络!',
type: 'error',
duration: 5 * 1000
})
} else {
Message({
message: error.message,
type: 'error',
duration: 5 * 1000
})
}
return Promise.reject(error)
}
)
下面来说一下跨域问题:利用vue-element-admin已安装的proxy来处理
1.在config/index.js里配置dev的proxyTable参数
proxyTable: {
'/lizi': { //这个是公共部分http://aaa.bbb.com/lizi
target: 'http://aaa.bbb.com', //真实的服务器地址1
target: 'http://ccc.ddd.com', //真实的服务器地址2
changeOrigin: true //开启代理
}
},
2.在编写请求实例的时候注释掉BASE_API,utils/request.js
const service = axios.create({
//baseURL: process.env.BASE_API, // api的base_url
timeout: 5000 // request timeout
})
3.在api的封装请求函数中如此写
//封装一个例子
export function lizi(data) {
return request({
url: '/lizi/aaa/bbb/ccc',
method: 'post',
data
})
}
备注:如果不用moke.js的话记得在main.js中把引用moke的给注释掉
版权声明:本文为wangle_style原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。