3.shiro-Springboot-vue简单登录demo

1.components创建一个login.vue
2.搭建一个单页面组件的框架

1
2
3
<template></template> 写html代码,注意template标签内一定要有一个html标签包裹所写的内容,例如下面的例子就用<div id="login">包裹住
<script></script> 编写脚本
<style></style> 样式

用element-ui组件先编写一个基本的页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<template>
<div class="login-container">
<el-form autoComplete="on" :model="loginForm" :rules="loginRules" ref="loginForm" label-position="left"
label-width="0px"
class="card-box login-form">
<h3 class="title">后台管理系统</h3>
<el-form-item prop="username">
<span class="svg-container svg-container_login">
<svg-icon icon-class="user"/>
</span>
<el-input v-model="loginForm.username" autoComplete="on"/>
</el-form-item>
<el-form-item prop="password">
<span class="svg-container">
<svg-icon icon-class="password"></svg-icon>
</span>
<el-input type="password" @keyup.enter.native="handleLogin" v-model="loginForm.password"
autoComplete="on"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" style="width:100%;" :loading="loading" @click.native.prevent="handleLogin">
登录
</el-button>
</el-form-item>
</el-form>
</div>
</template>
1
2
3
4
5
6
7
8
9
10
11
export default {
name: 'login',
data() {
return {

}
},
methods:{

}
}

3.给form,两个input框绑定数据,给表单控件绑定用v-model

1
2
<el-input v-model="loginForm.username" name="username" placeholder="请输入用户名/手机号" auto-complete="on"></el-input>
<el-input v-model="loginForm.password" name="password" placeholder="请输入密码" auto-complete="on"></el-input>

在data里面,同样要创建数据模型

1
2
3
4
5
6
7
8
9
10
11
12
13
data() {
return {
loginForm: {
username: 'admin',
password: '123456'
},
loginRules: {
username: [{required: true, trigger: 'blur', message: "请输入用户名"}],
password: [{required: true, trigger: 'blur', message: "请输入密码"}]
},
loading: false
}
}

4.表单验证:使用loginRules,用于表单验证

1
2
3
4
loginRules: {
username: [{required: true, trigger: 'blur', message: "请输入用户名"}],
password: [{required: true, trigger: 'blur', message: "请输入密码"}]
}

与组件绑定

5.创建api.js,用于处理在apis下创建login.js,是定义登录所需的请求服务器的接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import axios from 'axios'
import {Message, MessageBox} from 'element-ui'
import {getToken} from '@/utils/auth'
import store from '../store'
// 创建axios实例--封装了axios,结合业务封装了axios
const service = axios.create({
baseURL: process.env.BASE_URL, // api的base_url
timeout: 15000 // 请求超时时间2
})
// request拦截器
service.interceptors.request.use(config => {
/*if (store.getters.token) {
config.headers['X-Token'] = getToken() // 让每个请求携带token--['X-Token']为自定义key 请根据实际情况自行修改
}*/
return config
}, error => {
// Do something with request error
console.error(error) // for debug
Promise.reject(error)
})
// respone拦截器
service.interceptors.response.use(
response => {
//通过response自定义code来标示请求状态,当code返回如下情况为权限有问题,登出并返回到登录页
//* 如通过xmlhttprequest 状态码标识 逻辑可写在下面error中
const res = response.data;
if (res.returnCode == '1000') {
return res;
}
if (res.returnCode == '100') {
return res.returnData;
} else if (res.returnCode == "20011") {
Message({
showClose: true,
message: res.returnMsg,
type: 'error',
duration: 500,
onClose: () => {
store.dispatch('FedLogOut').then(() => {
location.reload()// 为了重新实例化vue-router对象 避免bug
})
}
});
return Promise.reject("未登录")
} else {
Message({
message: res.returnMsg,
type: 'error',
duration: 3 * 1000
})
return Promise.reject(res)
}
},
error => {
console.error('err' + error)// for debug
Message({
message: error.message,
type: 'error',
duration: 3 * 1000
})
return Promise.reject(error)
}
)
export default service

6.login.js调用api.js,token是包含用户名和密码的对象

1
2
3
4
5
6
7
8
9
import api from '@/utils/api'

export function getInfo(token) {
return api({
url: '/login/testGetInfo',
method: 'get',
params: {token}
})
}

7.创建好之后,在login.vue调用此login.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
methods: {
handleLogin() {
this.$refs.loginForm.validate(valid => {//账号密码的输入验证
if (valid) {
this.loading = true
this.$store.dispatch('Login', this.loginForm).then(data => {//登录操作,判断密码是否正确
this.loading = false
if ("success" === data.result) {
this.$router.push({path: '/'})//密码正常,进入首页
} else {
this.$message.error("账号/密码错误");
}
}).catch(() => {
this.loading = false
})
} else {
return false
}
})
}
}

8.关于跨域处理问题,可见上一篇博客。即在config/index.js中修改api值。

1
2
3
4
5
6
7
8
proxyTable: {
'/api': {
target: 'http://localhost:8080',
pathRewrite: {
'^/api': '/'
}
}
}