1. vue前端实战注意事项
1.1. 预备
1.1.1. Eslint
- 这是个语法检查工具,我用webstorm作为开发的ide,这个语法检查还是太严格了,一个空格啥的都会报错,对新手来讲还是建议关闭,需要关闭的地方主要有两个,webstorm自身设置,在settings里搜Eslint,如下
代码里找到webpack.base.conf.js
文件,注掉如下
1.1.2. 接口基地址
- 因为我的基础代码是代码生成器生成,里面有easymock的测试地址,这里需要替换成我们实际项目后台地址,找打
dev.env.js
文件
1.1.3. config/index.js
- 找到
index.js
文件,如果项目在开发阶段,建议devtool: 'source-map'
设置成这样,否则可能会造成你的调试困难
1.2. 权限
- 前后端分离通常要设置权限,也就是用前端来限制访问,不允许不经过登录页就访问其它界面
- 这个由路由的切面来完成,代码如下,提供一种思路
import router from './router'
import store from './store'
import NProgress from 'nprogress' // Progress 进度条
import 'nprogress/nprogress.css'// Progress 进度条样式
import { Message } from 'element-ui'
import { getToken } from '@/utils/auth' // 验权
const whiteList = ['/login'] // 不重定向白名单
router.beforeEach((to, from, next) => {
NProgress.start()
if (getToken()) {
if (to.path === '/login') {
next({ path: '/' })
} else {
if (store.getters.roles.length === 0) {
store.dispatch('GetInfo').then(res => { // 拉取用户信息
next()
}).catch(() => {
store.dispatch('FedLogOut').then(() => {
Message.error('验证失败,请重新登录')
next({ path: '/login' })
})
})
} else {
next()
}
}
} else {
if (whiteList.indexOf(to.path) !== -1) {
next()
} else {
next('/login')
NProgress.done()
}
}
})
router.afterEach(() => {
NProgress.done() // 结束Progress
})
1.3. token
- token通常有cookie来保存,这里由axios的拦截器来验证token,代码如下
import axios from 'axios'
import { Message, MessageBox } from 'element-ui'
import store from '../store'
import { getToken,setToken } from '@/utils/auth'
// 创建axios实例
const service = axios.create({
baseURL: process.env.BASE_API, // api的base_url
timeout: 15000 // 请求超时时间
})
// request拦截器
service.interceptors.request.use(config => {
if (store.getters.token) {
config.headers['X-Token'] = getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
}
return config
}, error => {
// Do something with request error
console.log(error) // for debug
Promise.reject(error)
})
// respone拦截器
service.interceptors.response.use(
response => {
/**
* code为非200是抛错 可结合自己业务进行修改
*/
const res = response.data
if (res.code !== 200) {
Message({
message: res.message,
type: 'error',
duration: 5 * 1000
})
setToken('')
// 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了;
if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
MessageBox.confirm('你已被登出,可以取消继续留在该页面,或者重新登录', '确定登出', {
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
store.dispatch('FedLogOut').then(() => {
location.reload()// 为了重新实例化vue-router对象 避免bug
})
})
}
return Promise.reject('error')
} else {
return response.data
}
},
error => {
console.log('err' + error)// for debug
Message({
message: error.message,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
}
)
export default service
1.4. 后端配置
- 跨域配置加token请求头配置,不配这个会遇到跨域问题和header获取不到问题,特别是这个
Access-Control-Allow-Headers
,你前端header里传的key值需要在这个配置,否则后端接收不到
/**
* filter 接口的自定义实现
*/
@Component
@WebFilter(urlPatterns = "/**", filterName = "corsFilter")
public class CorsFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException,
ServletException {
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "*");
// or *
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with,X-Token,x-token, Content-Type, " +
"MUserAgent, " +
"MToken, " +
"UID"); // or *
HttpServletRequest request = (HttpServletRequest) req;
if(request.getMethod().equals("OPTIONS")) {
response.setStatus(HttpServletResponse.SC_OK);
}else{
chain.doFilter(req, res);
}
}
@Override
public void destroy() {
}
}