Vue3常规登录页面模板
本文基于vue3(JavaScript),使用vue3的setup语法糖书写方式
setup语法糖也是当前各大适用Vue的框架官网都在推崇的书写方式,此外各大主流框架的源码首选是TypeScript,而不是JavaScript。
登录页面模板
以下登录页面模板,基于element-plus和scss,关于elment-plus和scss的环境准备本文不做赘述,包括element-plus图标库的引入。
效果图:

<template><div class="login-body"><div class="login-panel"><div class="login-title">用户登录</div><el-form :model="formData" :rules="rules" ref="formDataRef"><el-form-item prop="username"><el-input placeholder="请输入账号" v-model="formData.username" size="large" type="text"><template #prefix><el-icon><User /></el-icon></template></el-input></el-form-item><el-form-item prop="password"><el-input placeholder="请输入密码" v-model="formData.password" size="large" type="password"@keyup.enter.native="login()"><template #prefix><el-icon><Lock /></el-icon></template></el-input></el-form-item><!-- <el-form-item label=""><div class="check-code-panel"><el-input placeholder="请输入验证码" v-model="formData.checkCode" class="input-panel" /><img src="checkCodeUrl" class="check-code"></div></el-form-item> --><!-- <el-form-item label=""><el-checkbox label="记住密码" name="type" /></el-form-item> --><el-form-item label=""><el-button type="primary" style="width: 100%;" @click="login()" size="large">登录</el-button></el-form-item></el-form></div></div>
</template><script setup>
import { ref, reactive, } from 'vue'
import { ElMessage } from 'element-plus';
import request from '@/utils/request'; //这里使用自行封装的axios,下文已给出,照搬后修改运行端口即可
import { useRouter } from 'vue-router';// const checkCodeUrl = "api/checkCode?" + new Date().getTime();
//表单
const formDataRef = ref();
let formData = reactive({username: "",password: ""
});
const rules = {username: [{required: true,message: "请输入用户名"}],password: [{required: true,message: "请输入密码"}],// checkCode: [{// required: true,// message: "请输入验证码"// }],
}const router = useRouter();const login = () => {var form_obj = JSON.parse(JSON.stringify(formData));// console.log(form_obj);// console.log(form_obj.username);// console.log(form_obj.password);// 后端代码自行准备request.post("/user/login", form_obj).then(res => {if (res) {ElMessage({message: '登录成功',type: 'success',})let tokenObj = { token: " isLogin", startTime: new Date().getTime() };window.localStorage.setItem("isLogin", JSON.stringify(tokenObj));localStorage.setItem("username", JSON.parse(JSON.stringify(formData.username)));router.push("/");} else {ElMessage.error('账号或密码错误!!!登录失败!!!')}});
};
</script><style lang="scss" scoped >
.login-body {background: url("../assets/三门峡.png") no-repeat center center;height: 100%;width: 100%;background-size: cover;position: absolute;left: 0;top: 0;.login-panel {position: absolute;top: 0;bottom: 0;left: 0;right: 0;margin: auto;padding: 25px;width: 26%;min-width: 460px;height: 30%;min-height: 300px;background: rgba(255, 255, 255, 0.6);border-radius: 5%;box-shadow: 2px 2px 10px #ddd;.login-title {font-size: 22px;text-align: center;margin-bottom: 22px;}}
}
</style>
axios封装
utils/request.js
import axios from 'axios'//这里的端口是后端程序的运行端口
const request = axios.create({baseURL: 'http://localhost:10029', // 注意!! 这里是全局统一加上了 '/api' 前缀,也就是说所有接口都会加上'/api'前缀在,页面里面写接口的时候就不要加 '/api'了,否则会出现2个'/api',类似 '/api/api/user'这样的报错,切记!!!timeout: 5000
})
// request 拦截器
// 可以自请求发送前对请求做一些处理
// 比如统一加token,对请求参数统一加密
request.interceptors.request.use(config => {config.headers['Content-Type'] = 'application/json;charset=utf-8';// config.headers['token'] = user.token; // 设置请求头return config
}, error => {return Promise.reject(error)
});// response 拦截器
// 可以在接口响应后统一处理结果
request.interceptors.response.use(response => {let res = response.data;// 如果是返回的文件if (response.config.responseType === 'blob') {return res}// 兼容服务端返回的字符串数据if (typeof res === 'string') {res = res ? JSON.parse(res) : res}return res;},error => {console.log('' + error) // for debugreturn Promise.reject(error)}
)export default request
登录状态定时检测(全局路由守卫)
通过添加路由守卫的方式,监控登录状态,登录成功记录时间戳到本地缓存,若本地缓存的时间戳超过设定的时间则自动退出登录状态。
router/index.js 添加全局路由守卫
import { createRouter, createWebHistory } from 'vue-router'
import { ElMessage } from 'element-plus'
import { h } from 'vue';const routes = [//登录页路由{path: '/login',name: '登录页',component: () => import('../views/LoginView.vue')},// 页面找不到404 路由{path: '/404',name: 'NoPage 404',component: () => import('../views/404.vue'),hidden: true},{ path: '/:pathMatch(.*)',redirect: '/404',hidden: true},//框架布局路由{path: '/',name: "框架页",component: () => import('../views/LayoutView.vue'),redirect: '/home',children: [{path: 'home',name: '首页',component: () => import('../components/Home.vue')},]}
]const router = createRouter({history: createWebHistory(process.env.BASE_URL),routes
})// 设置登录过期时间(一天)86400000
let expire = 21600000;//路由守卫
//全局守卫,登录拦截
//进行路由拦截:当没有登陆标识,直接打回登陆页面,如何避免退回到 登陆页呢?
router.beforeEach((to, from, next) => {// 从本地缓存中获取保存的 token 信息const tokenObj = JSON.parse(window.localStorage.getItem('isLogin'))if (to.path === "/login") {next()} else {// 如果没有token,强制跳转到登录页面;如果有,则判断token时间是否过期if (!tokenObj || !tokenObj.token) {next('/login')} else {let date = new Date().getTime();// 当前时间 - token中的登录时间 > 设置的过期时间,为过期;则清除token,并强制跳转至登录页// 反之为有效期,则放行if (date - tokenObj.startTime > expire) {window.localStorage.removeItem('isLogin');next('/login')ElMessage({message: h('p', null, [h('span', null, '登录状态过期'),h('i', { style: 'color: teal' }, '请重新登录!'),]),})} else {next();}}}
});export default router
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
