共计 8849 个字符,预计需要花费 23 分钟才能阅读完成。
vue-admin-chart 治理后盾登陆界面是基于 Vue3.2 vue-cli5 vue-router4 ElementPlus2.2 Pinia2.0 状态治理存储 axios 网络申请等搭建,采纳 TS(TypeScript) 脚本语言,以 Composition api 格调编写,采纳 axios 申请近程 Restful API 接口调试。
vue-admin-chart 治理后盾登陆界面
vue-admin-chart 登陆实现的步骤:
①创立 vue 组件页面
以及相干代码(template/html、ts/js、css/scss)
view/auth/login.vue 文件
html 代码局部
#目录文件名称:view/auth/login.vue 的 template html 代码
<template>
<div class="login-container">
<transition name="el-fade-in-out">
<el-form ref="formRef" :model="data.form" :rules="data.rules" :label-width="data.property.labelWidth" :size="data.property.formSize" class="login-form" v-show="!data.loginSucc">
<!-- 头像 -->
<el-form-item>
<div class="login_avatar">
<img src="/assets/images/login_avatar.jpg" alt="">
</div>
</el-form-item>
<el-form-item>
<div class="title">
TodoAdmin 管理系统 <span class="title-min">-base</span>
</div>
</el-form-item>
<el-form-item prop="username">
<el-input v-model="data.form.username" placeholder="用户名" type="text" auto-complete="on" >
<template #prepend>
<el-icon :size="20"><Avatar /></el-icon>
</template>
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input v-model="data.form.password" placeholder="明码" type="password" show-password autocomplete="off" @keyup.enter.native="loginSubmit" >
<template #prepend>
<el-icon :size="20"><Key /></el-icon>
</template>
</el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="loginSubmit" :disabled="data.isSubmit" class="btn-submit"> 登录 </el-button>
</el-form-item>
<el-form-item>
<div class="tips">
<span> 如果还没有账号?<a href="javascript:;" class="register" @click="register"> 注册 </a></span>
</div>
</el-form-item>
<el-form-item>
<div class="repo">
<span><a :href="data.table.github" class="repo-link" target="_blank">Github Repo</a></span>
<span><a :href="data.table.gitee" class="repo-link" target="_blank">Gitee Repo</a></span>
</div>
</el-form-item>
<el-form-item>
<div class="copyright">
Copyright (c) {{data.table.year}}, Todoadmin.com
</div>
</el-form-item>
</el-form>
</transition>
</div>
</template>
js/ts 代码局部
#目录文件名称:view/auth/login.vue 的 ts/js 相干代码
import {defineComponent, reactive, ref} from 'vue'
import router from '@/router'
import {cache} from '@/utils'
import type {FormInstance} from 'element-plus'
import {ElMessage,ElMessageBox} from 'element-plus'
import type {Action} from 'element-plus'
import {G} from '@/config'
import {SAuth} from '@/service'
import md5 from 'js-md5'
export default defineComponent({
name:'Login',
setup() {
// 获取组件的 ref
const formRef:any = ref<FormInstance>()
// 革除 localStorage 所有的值
cache.clearLocalStorage()
let date:any = new Date()
let year:string = date.getFullYear()
const data:any = reactive({
//Table 列表相干数据
table: {
github: G.GITHUB_REPO_URL,
gitee: G.GITEE_REPO_URL,
year:year,
},
//Form 表单相干数据
form: {
username: '',
password: '',
},
reform: {password: '',},
// 属性设置
property: {
labelWidth: '80px',
fullscreen: false,
closeModal: false,
formSize: 'default',
},
// form 表单规定
rules: {
username: [{ required: true, message: '用户名', trigger: 'blur'},
{min: 3, max: 20, message: '用户名' + '3 ~ 20', trigger: 'blur'},
],
password: [{ required: true, message: '输出明码有误', trigger: 'blur'},
{min: 6, max: 16, message: '明码长度' + '6 ~ 16', trigger: 'blur'},
],
},
// 是否显示部分 loading 成果
loading: false,
// 曾经提交过申请登陆,提交按钮变灰
isSubmit: false,
// 是否登陆胜利,如果登陆胜利,则暗藏 form 控件
loginSucc:false,
})
// 点击按钮登陆
const loginSubmit = async () => {if (!formRef.value!) return
try {
// 验证表单
await formRef.value!.validate((valid: any) => {if (valid) {
data.isSubmit = true
// 保留提交前未 md5 的值
data.reform.password = data.form.password
// 对明码进行 MD5 的加密后传输
data.form.password = md5(data.form.password)
// 提交数据到申请服务
SAuth.login(data.form).then((result : any) => {
data.form.password = data.reform.password
if (result.code === 0) {
data.loginSucc = true
ElMessage.success('登录胜利')
let timeout = setTimeout(() => {ElMessage.warning('行将跳到首页')
// 重置表单
formRef.value.resetFields()
clearTimeout(timeout)
router.push(G.HOME_URL)
}, 300)
} else {
data.isSubmit = false
ElMessage.error(result.message)
}
}).catch((err: any) => {
data.form.password = data.reform.password
data.isSubmit = false
console.log(err)
ElMessage.error(err)
})
} else {console.log('fail')
ElMessage.error('登录失败')
}
})
} catch (error) {console.log(error)
}
}
// 重置表单
const resetForm = (formEl: FormInstance | undefined) => {if (!formEl) return
formEl.resetFields()}
// 注册用户
const register = () => {
ElMessageBox.alert('注册用户通道临时不凋谢,请关注布告!', '提醒', {
confirmButtonText: '敞开',
callback: (action: Action) => {},})
}
return {
formRef,
data,
loginSubmit,
resetForm,
register
}
}
})
css/scss 代码局部
#目录文件名称:view/auth/login.vue 的 css/scss 相干代码
<style lang="scss" scoped>
:deep(.el-form .el-form-item__content) {
display: inline;
margin-left: 0px !important;
}
.login-container {
margin: 0 auto;
height: 100%;
width: 100%;
background: url('~@/assets/images/bg1.jpg') no-repeat;
overflow: hidden;
// 头像
.login_avatar {
margin: 0 auto;
width: 120px;
height: 120px;
border-radius: 50%;
border: 1px solid #409eff;
box-shadow: 0 0 10px #409eff;
img {
width: 100%;
height: 100%;
border-radius: 50%;
}
}
.login-form {
margin: 0 auto;
position: relative;
width: 600px;
max-width: 90%;
padding: 100px 0 230px 0;
overflow: hidden;
.btn-submit {
width:100%;
padding:5px 0;
color:#fff;
font-size:18px;
}
}
.title {
margin: 0 auto 20px auto;
font-size: 28px;
text-align: center;
font-weight: 600;
color:#f2f2f2;
}
.title-min {
padding-left: 3px;
color:#fff;
font-size:14px;
font-weight: 500;
}
.tips {
margin: 0 auto;
font-size: 18px;
text-align: center;
color: #666;
margin-bottom: 10px;
}
.repo {
margin: 0 auto;
font-size: 20px;
text-align: center;
margin-bottom: 10px;
span {margin: 0 15px;}
}
.repo-link {
cursor: pointer;
text-decoration: underline;
font-size:22px;
color:#1145c8;
}
.repo-link:hover {color:#f7f7fc;}
.register {
cursor: pointer;
text-decoration: none;
font-size:20px;
color:#345cc0;
}
.copyright {
color:#fff;
font-size:14px;
margin:0 auto;
text-align: center;
}
}
</style>
②创立 router 路由守卫文件
router 目录下的文件
#router\modules\routes.ts 文件
#路由 component
import LoginLayout from '@/views/auth/login.vue'
路由 router 守卫的 ts/js 代码局部
#router\modules\index.ts 文件
// 导航路由守卫
router.beforeEach((to:any, from:any, next:any) => {
try {
// 路由在白名单外面
if (existWhite(to.path)) {next()
} else {const token = cache.getLocalStorage(G.AUTHORIZATION_TOKEN)
// 如果 token 或 userInfo 为空、null、{} 则跳转到指定 login 页面进行登陆
if (!token) {
// 保留咱们所在的地位,以便当前再来
next(G.LOGIN_URL);
} else {if (to.matched.length === 0) {ElMessage.error('找不到路由 -NotFound Router...')
from.name ? next({path: from.path, query: from.query}) : next(G.NOTFOUND_URL)
} else {next()
}
}
}
} catch (error) {throw error}
})
③创立 axios 申请 restful 接口
src\service\modules\auth\auth.ts 文件
#src\service\modules\auth\auth.ts
#axios 申请 restful login 接口登陆
/**
* 用户登陆
* @param params object
* @returns json object
*/
export const login = async (params : any) => {
// 获取 setting store
const settStore = settingStore()
let data: any;
await http.post(HUrl.LOGIN_URL,params).then((result : any) => {
// 只解决 code = 0 的数据
if (result.code === 0) {
//type:0 为 ping 心跳,不需解决,WS 数据
if (result.type !== 0) {
// 设置 token,并写入到 store 中
let token = result.token || ''
//Pinia 保留一份
settStore.setToken(token)
//LocalStorage 原始也保留一份
cache.setLocalStorage(G.AUTHORIZATION_TOKEN,token)
}
// 设置用户根本信息,并写入到 store 中
let userInfo = result.data.userInfo
if (userInfo) {settStore.setUserInfo(userInfo)
}
}
data = result;
}).catch((err: any) => {http.catch(err)
});
return data;
}
其中 const settStore = settingStore() 为状态治理组件 Pinia,这里能够应用 Vuex,甚至间接应用本地 local 或 session 来代替,然而为了我的项目还是倡议应用 Pinia 作为状态的存储
vue-admin 治理后盾的登陆局部已实现,代码已上传到 github 和 gitee,供大家 clone 或下载 zip
Demo 体验 & 仓库地址
- Todoadmin-pro Pro 专业版演示地址
- Todoadmin-base 根本版演示地址
- Github 地址
- Gitee 码云地址
用户名:guest
明码:123456
克隆我的项目 拜访 Github 仓库
# 克隆我的项目
git clone -b https://github.com/todoadmin/vue-admin-chart.git
# 装置依赖
npm i
# 本地开发 启动我的项目
npm run serve
克隆我的项目 拜访 Gitee 仓库
# 克隆我的项目
git clone -b https://gitee.com/todoadmin/vue-admin-chart.git
# 装置依赖
npm i
# 本地开发 启动我的项目
npm run serve
正文完