🧑🎓 个人主页:SilenceLamb
📖 本章内容:【vue登录页面】
🌳Gitee仓库地址:👉🏽vue登录页面
一、路由配置
// 公共路由
export const constantRoutes = [
{
path: '/login',
name: 'Login',
component: () => import('@/views/login/login.vue')
},
{
path: '/',
name: 'Index',
redirect: '/index',
component: () => import('@/views/index/index.vue')
},
]
二、API统一管理
🍎 获取验证码
// 获取验证码
export function getCodeImage() {
return request({
url: '/captchaImage',
method: 'get'
})
}
🍎 用户登录
//用户登录
export function login(data) {
return request({
url: '/login',
headers: {
isToken: false
},
method: 'post',
data: data
})
}
三、 登录页面布局
🍒 页面布局
<template>
<div class="login">
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form">
<h3 class="title">后台管理系统</h3>
<el-form-item prop="username">
<el-input
v-model="loginForm.username"
type="text"
auto-complete="off"
placeholder="账号"
>
<svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon"/>
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
v-model="loginForm.password"
:type="passwordType"
auto-complete="off"
placeholder="密码"
@keyup.enter.native="handleLogin"
>
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon"/>
<span slot="suffix" @click="showPassword()">
<svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'"
class="el-input__icon input-icon"
></svg-icon>
</span>
</el-input>
</el-form-item>
<el-form-item prop="code" v-if="captchaEnabled">
<el-input
v-model="loginForm.code"
auto-complete="off"
placeholder="验证码"
style="width: 63%"
@keyup.enter.native="handleLogin"
>
<svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon"/>
</el-input>
<div class="login-code">
<img :src="codeUrl" @click="getCode" class="login-code-img"/>
</div>
</el-form-item>
<el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">记住密码</el-checkbox>
<el-form-item style="width:100%;">
<el-button
:loading="loading"
size="medium"
type="primary"
style="width:100%;"
@click.native.prevent="handleLogin"
>
<span v-if="!loading">登 录</span>
<span v-else>登 录 中...</span>
</el-button>
<div style="float: right;" v-if="register">
<router-link class="link-type" :to="'/register'">立即注册</router-link>
</div>
</el-form-item>
</el-form>
<!-- 底部 -->
<div class="el-login-footer">
</div>
</div>
</template>
- 🌳src/views/login:data封装的数据
data() {
return {
codeUrl: "",
loginForm: {
username: "admin",
password: "michale",
rememberMe: false,
code: "",
uuid: ""
},
loginRules: {
username: [
{required: true, trigger: "blur", message: "请输入您的账号"}
],
password: [
{required: true, trigger: "blur", message: "请输入您的密码"}
],
code: [{required: true, trigger: "change", message: "请输入验证码"}]
},
passwordType: 'password',
loading: false,
// 验证码开关
captchaEnabled: true,
// 注册开关
register: false,
redirect: undefined
};
- 🌳src/views/login:🕰️可以导入其他文件
- 例如:import 《组件名称》 from '《组件路径》';
🍒相关方法定义
import {getCodeImage} from "@/api/common/captchaImage";
import {encrypt, decrypt} from "@/utils/jsencrypt";
import Cookies from "js-cookie";
- 🍏获取验证码
//获取验证码
getCode() {
getCodeImage().then(res => {
this.captchaEnabled = res.data.captchaEnabled === undefined ? true : res.data.captchaEnabled;
if (this.captchaEnabled) {
this.codeUrl = "data:image/gif;base64," + res.data.img;
this.loginForm.uuid = res.data.uuid;
}
});
},
- 🍏从cookie中获取信息
//从cookie中获取信息
getCookie() {
const username = Cookies.get("username");
const password = Cookies.get("password");
const rememberMe = Cookies.get('rememberMe')
this.loginForm = {
username: username === undefined ? this.loginForm.username : username,
password: password === undefined ? this.loginForm.password : decrypt(password),
rememberMe: rememberMe === undefined ? false : Boolean(rememberMe)
};
},
- 🍑登陆处理
//登陆处理
handleLogin() {
this.$refs.loginForm.validate(valid => {
if (valid) {
this.loading = true;
if (this.loginForm.rememberMe) {
Cookies.set("username", this.loginForm.username, {expires: 30});
Cookies.set("password", encrypt(this.loginForm.password), {expires: 30});
Cookies.set('rememberMe', this.loginForm.rememberMe, {expires: 30});
} else {
Cookies.remove("username");
Cookies.remove("password");
Cookies.remove('rememberMe');
}
this.$store.dispatch('user/Login', this.loginForm).then(() => {
this.$router.push({path: this.redirect || "/"});
})
}
})
},
- 👑密码显示和隐藏
//密码显示和隐藏
showPassword() {
if (this.passwordType === 'password') {
this.passwordType = ''
} else {
this.passwordType = 'password'
}
},
🍒 登录页面样式
- 🌳src/views/login/login.vue:引入样式文件
<style rel="stylesheet/scss" lang="scss">
//@import url(); 引入公共 css 类
@import url("@/views/login/login.scss");
</style>
四、登录操作
- 🌳src/store/modules/user.js
import {login} from '@/api/common/login'
import {getToken, setToken, removeToken} from '@/utils/token'
🍬 初始化Token的state
//状态
state: {
token: getToken(),
},
🍬 提供修改token的mutations
//修改状态
mutations: {
SET_TOKEN: (state, token) => {
state.token = token
},
},
🍬 封装登录的Action
//异步执行
actions: {
// 登录
Login({commit}, loginForm) {
return new Promise((resolve, reject) => {
login(loginForm).then(res => {
setToken(res.data)
commit('SET_TOKEN', res.data)
resolve()
}).catch(error => {
reject(error)
})
})
},
}
🍬 对state属性进行计算
- 🌳src/store/getters.js
const getters = {
token: state => state.user.token,
}
export default getters
- 🌳src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {},
getters: {},
mutations: {},
actions: {},
modules: {
user
}
})
export default store
五、获取用户信息
🍬 初始化用户信息的state
const state = {
userName: "",
identity: "",
avatar: "",
roles: [],
permissions: [],
title: "",
logo: "",
}
🍬 提供修改token的mutations
const mutations = {
SET_NAME: (state, name) => {
state.userName = name
},
SET_AVATAR: (state, avatar) => {
state.avatar = avatar
},
SET_ROLES: (state, roles) => {
state.roles = roles
},
SET_PERMISSIONS: (state, permissions) => {
state.permissions = permissions
},
SET_TITLE: (state, title) => {
state.title = title
},
SET_LOGO: (state, logo) => {
state.logo = logo
},
SET_IDENTITY: (state, identity) => {
state.identity = identity
},
}
🍬 封装登录的action
// 获取用户信息
GetInfo({commit}) {
return new Promise((resolve, reject) => {
getInfo().then(res => {
const avatar = (res.data.sysUser.avatar === "" || res.data.sysUser.avatar == null) ? require("@/assets/images/login.gif") : res.data.user.avatar;
if (res.data.roles && res.data.roles.length > 0) { // 验证返回的roles是否是一个非空数组
commit('SET_ROLES', res.data.roles)
commit('SET_PERMISSIONS', res.data.permissions)
} else {
commit('SET_ROLES', ['ROLE_DEFAULT'])
}
commit('SET_NAME', res.data.sysUser.userName)
commit('SET_IDENTITY', res.data.sysUser.identity)
commit('SET_AVATAR', avatar)
commit('SET_LOGO', res.data.logo)
commit('SET_TITLE', res.data.title)
resolve(res)
}).catch(error => {
reject(error)
})
})
},
🍬 对state属性进行计算
const getters = {
avatar: state => state.user.avatar,
userName: state => state.user.userName,
identity: state => state.user.identity,
roles: state => state.user.roles,
permissions: state => state.user.permissions,
title: state => state.user.title,
logo: state => state.user.logo,
}
export default getters
📢🌥️如果文章对你有帮助【关注👍点赞❤️收藏⭐】