vue-admin-template-master项目学习
github地址https://github.com/PanJiaChen/vue-admin-template新手踩坑https://www.jianshu.com/p/290cd0060d04项目目录项目中有如下目录build:编译用到的脚本mock:模拟后台服务器接口,可以产生数据node_modules:node第三方包,这个目录可以删掉,通过npm/cnpm install命令可以下载p
github地址
https://github.com/PanJiaChen/vue-admin-template
新手踩坑
https://www.jianshu.com/p/290cd0060d04
项目目录
项目中有如下目录
- build:编译用到的脚本
- mock:模拟后台服务器接口,可以产生数据
- node_modules:node第三方包,这个目录可以删掉,通过npm/cnpm install命令可以下载
- public:暂时没学习到
- src:源代码文件,这里通常是我们写代码的地方
- tests:测试文件
跨域问题
https://zhuanlan.zhihu.com/p/53545472
前端
在vue.config.js中添加如下代码
proxy: {
'/api': {
target: 'process.env.VUE_APP_BASE_API',
changeOrigin: true,
pathRewrite: {
'^/api': 'api'
}
}
},
然后在.env.development中
VUE_APP_BASE_API = 'http://localhost:8080/'
后端
在config包下配置
@Configuration
public class MyConfiguration {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
};
}
}
登录功能
在src/views/login下的index.js中可以发现,点击登录所绑定的事件click.native.prevent="handleLogin"
<el-button
:loading="loading"
type="primary"
style="width:100%;margin-bottom:30px;"
@click.native.prevent="handleLogin">Login
</el-button>
在下方的脚本中找到handleLogin()
// views/login
handleLogin() {
this.$refs.loginForm.validate(valid => {
if (valid) {
this.loading = true
this.$store.dispatch('user/login', this.loginForm).then(() => {
this.$router.push({ path: this.redirect || '/' })
this.loading = false
}).catch(() => {
this.loading = false
})
} else {
console.log('error submit!!')
return false
}
})
}
this.$refs.loginForm 调用了loginForm的validate方法,传入了一个回调函数,参数为valid,代表是否验证成功
this.$store.dispatch(‘user/login’, this.loginForm) 中第一个参数本应该是action的方法名,但是由于store/index.js使用了命名空间
关于命名空间https://vuex.vuejs.org/zh/guide/modules.html#命名空间
// store/index.js
const store = new Vuex.Store({
modules: {
app,
settings,
user
},
getters
})
user下的login()方法被映射为user/login,所以这句代码将转交给vuex的user下的action : login()处理
// store/modules/user
// user login
import { login, logout, getInfo } from '@/api/user'
import { getToken, setToken, removeToken } from '@/utils/auth'
import { resetRouter } from '@/router'
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)
})
})
}
}
login({ commit }, userInfo) 接收两个参数,第一个commit是vuex的固定语法,用于调用mutation方法,第二个参数为loginForm
const { username, password } = userInfo
这里把userInfo中的参数解包,用两个新的变量接收
这里用了Promise对象https://www.jianshu.com/p/b16e7c9e1f9f,类似于try,catch的体系
login({ username: username.trim(), password: password }) 调用了api请求(封装过的axios请求,可在utils/request.js中查看)
传入了一个json对象
{
'username': username.trim(),
'password':password
}
SpringMVC可以接收这个参数,当然这里用的mock模拟服务器,首先在api/user中找到login方法
export function login(data) {
return request({
url: '/vue-admin-template/user/login',
method: 'post',
data
})
}
然后在mock/user中发现这个请求对应的处理方法
const tokens = {
admin: {
token: 'admin-token'
},
editor: {
token: 'editor-token'
}
}
module.exports = [
// user login
{
url: '/vue-admin-template/user/login',
type: 'post',
response: config => {
const { username } = config.body
const token = tokens[username]
// mock error
if (!token) {
return {
code: 60204,
message: 'Account and password are incorrect.'
}
}
return {
code: 20000,
data: token
}
}
}
]
这里的config个人猜测,应该是requset请求,config.body为请求体,前面分析传入了一个json对象,这里config.body就是那个json对象
可以看出,返回的是一个json对象
const tokens = {
admin: {
token: 'admin-token'
},
editor: {
token: 'editor-token'
}
}
{
code: 123456,
message: 'Account and password are incorrect.'
date: {token}
}
通过这里的分析,在后端Controller对象中返回一个token,结果发现一直报错,然后打开utils/request.js
这里是用axios拦截器对请求和响应进行处理,然后发现如下代码
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
})
在这里console.log(response)发现问题
{
"data": {
"token": "admin-token"
},
"status": 200,
"statusText": "",
"headers": {
"content-type": "application/json"
},
"config": {
"transformRequest": {},
"transformResponse": {},
"timeout": 5000,
"xsrfCookieName": "XSRF-TOKEN",
"xsrfHeaderName": "X-XSRF-TOKEN",
"maxContentLength": -1,
"headers": {
"Accept": "application/json, text/plain, */*",
"Content-Type": "application/json;charset=utf-8"
},
"method": "post",
"baseURL": "http://localhost:8080/",
"url": "http://localhost:8080/api/user/login",
"data": "{\"username\":\"admin\",\"password\":\"111111\"}"
},
"request": {}
}
response.data应该具有如下格式
{
code: 123456,
message: 'Account and password are incorrect.'
date: {token}
}
于是自定义了一个CommonResult类如下
@Data
public class CommonResult<T> {
private Integer code;
private String message;
private T data;
}
@RequestMapping(value = "/login")
public CommonResult<Object> login(){
System.out.println("login了");
UserLogin userLogin = new UserLogin();
userLogin.setToken("admin-token");
CommonResult<Object> result = new CommonResult<>();
result.setCode(20000);
result.setData(userLogin);
return result;
}
从这里可以了解到,controller通过@ResponseBody或者@RestController返回一个对象时,对象首先被转换为json格式,然后封装在response中的data属性里面
随后遇到的问题与上面差不多,同样的思路可以解决
更多推荐
所有评论(0)