手机网站判断跳转,静态网站可以做留言板,网站建设可行性的分析,猎头公司全称天行健#xff0c;君子以自强不息#xff1b;地势坤#xff0c;君子以厚德载物。 每个人都有惰性#xff0c;但不断学习是好好生活的根本#xff0c;共勉#xff01; 文章均为学习整理笔记#xff0c;分享记录为主#xff0c;如有错误请指正#xff0c;共同学习进步。… 天行健君子以自强不息地势坤君子以厚德载物。 每个人都有惰性但不断学习是好好生活的根本共勉 文章均为学习整理笔记分享记录为主如有错误请指正共同学习进步。 仰天大笑出门去我辈岂是蓬蒿人。 ——《南陵别儿童入京》 文章目录 19. 登录优化记住用户名和密码19.1 api/api.ts19.2 store/index.ts19.3 index/HomeIndex.vue19.4 PhoneCodeForm.vue19.5 QcodeForm.vue19.6 UsernameForm.vue19.7 App.vue19.8 页面效果展示19.8.1 使用短信验证码登录的展示19.8.2 使用账号密码登录的展示19.8.3 使用二维码登录的展示 先进行上一篇最后一部分登录问题进行优化 优化内容如下 1.部分警告虽然不影响项目正常使用但控制台输出的警告看着还是比较难受的 2.取消勾选记住用户名和密码操作用户名密码依旧显示该问题是因为当记住用户名密码对应的值移除后其值变为undefined而代码中的判断在其为undefined时依旧满足条件执行需要将其值与ture进行比较
19. 登录优化记住用户名和密码
部分其他代码也进行了优化以下代码基于上一篇最后下载的项目进行改动 改动如下
19.1 api/api.ts
src/api/api.ts 注掉了一部分无用代码
// 引入axios
import axios from axios
// 引入store
import store from /store;
import { useRouter } from vue-router;// 数据请求自定义配置实例
// console.log(import.meta.url,------------);
const api axios.create({// baseURL: https://mo_sss.blog.csdn.net.cn,// baseURL: import.meta.BaseURL,// baseURL: https://hanshanlibai.gms.com,baseURL: http://127.0.0.1:8888/,timeout: 1000,headers: {// X-Custom-Header: foobarContent-Type: application/json;charsetUTF-8}// withCredentials 表示跨域请求时是否需要使用凭证默认是true// withCredentials: true,// responseType 表示浏览器将要响应的数据类型包括arraybuffer、document、json、text、stream// 浏览器专属类型: blob// 默认值就是json// responseType: json,// responseEncoding 表示用于解码响应的编码Node.js专属注意忽略responseType值为stream或者客户端请求// 默认值为utf-8// responseEncoding: utf-8
});// const router useRouter();// 添加请求拦截器
api.interceptors.request.use(function (config) {console.log(request-------------------)// 在发送请求之前做些什么// 获取缓存中的tokenconst token store.getters.getToken;if(token){// 如果token为真值则将其赋值赋给请求头config.headers.token token;}return config;}, function (error) {// 对请求错误做些什么return Promise.reject(error);});// 添加响应拦截器
api.interceptors.response.use(function (response) {console.log(response------------------- code,response.status)// 2xx 范围内的状态码都会触发该函数。// 对响应数据做点什么// store.commit(logout);// router.push(/UserLogin)return response;}, function (error) {// 超出 2xx 范围的状态码都会触发该函数。// 对响应错误做点什么if(error.response){console.log(error.response.status)switch(error.response.status){case 401:// case 200:store.commit(logout);// router.replace({// path: /UserLogin,// query: {// redirect: router.currentRoute.value.fullPath// }// })break;default:store.commit(logout);// router.replace({// path: /UserLogin,// query: {// redirect: router.currentRoute.value.fullPath// }// })}}return Promise.reject(error);});export default api;19.2 store/index.ts
src/store/index.ts 新增了登出时清除缓存数据的代码此处为缓存校验时使用
// 引入 用于存储全局的状态数据可供其他地方调用
import { createStore } from vuex;
// 引入工具方法
import utils from /utils/utils;// 创建一个新的store实例
const store createStore({state() {return{// count: 0// 当前登录的用户信息userInfo: {},// 当前登录的标识tokentoken: null,}},getters: {getUserInfo(state:any){return state.userInfo;},getToken(state:any){return state.token;}},mutations: {// 登出清除缓存中的数据logout: function(state:any){console.log(---111---)state.userInfo null;utils.removeData(userInfo);utils.removeData(token);// utils.removeData(username);// utils.saveData(username,);// utils.removeData(saveUsername);// utils.removeData(password);// utils.removeData(savePassword);},// 存储用户信息setUserInfo: function(state:any, userInfo:any){state.userInfo userInfo;utils.saveData(userInfo, userInfo);},// 存储tokensetToken: function(state:any, token:any){state.toekn token;utils.saveData(token, token);}}})export default store;19.3 index/HomeIndex.vue
src/views/index/HomeIndex.vue 未做改变但也列出来看一下
script setup langtsimport utils from /utils/utils;
import { onMounted } from vue;/scripttemplate后台主页
/templatestyle scoped
/style19.4 PhoneCodeForm.vue
src/views/login/components/PhoneCodeForm.vue 对登录缓存校验进行了优化
script setup langts
import { ref, reactive, onMounted, onUnmounted } from vue// 引入状态存储工具store
import {useStore} from vuex// 引入工具方法
import utils from ../../../utils/utils
import api from ../../../api/api
// 路由引入
import { useRoute, useRouter } from vue-router;// 登录表单的实例
// let loginFormRef ref(null);
let loginFormRef ref()
// 登录表单的数据
const loginForm reactive({// 用户名username: ,// 手机验证码smscode: ,// 图片验证imgcode: ,// 记住用户名默认否saveUsername: false
})// 登录验证规则
const rules {username: [{required: true,message: 请输入用户名,trigger: blur}],smscode: [{required: true,message: 请输入短信验证码,trigger: blur}],imgcode: [{required: true,message: 请输入图片验证码,trigger: blur}]
}const formSize ;// 图片验证码路径
let imgCodeSrc new URL(../../../assets/code.png, import.meta.url).href
// const imgCodeSrc ../../../assets/code.png;// 刷新图片验证码
const getImgCode () {// 后续改为从服务器上获取动态图片imgCodeSrc new URL(../../../assets/code.png, import.meta.url).href
}// 定时器
let timer: any null
// 获取短信验证码的间隔时间
let curTime 0
// 获取短信验证码按钮的文本显示内容
let smsCodeBtnText ref(获取验证码)// 获取短信验证码
const getSmsCode () {// 当点击获取短信验证码时如果其他信息没填则提示输入if (!loginForm.username) {utils.showError(请输入用户名)return}// if(!loginForm.smscode){// utils.showError(请输入短信验证码);// return;// }// TODO 从后台获取短信验证码// 调用接口生成短信验证码// 1 直接使用axios请求后端完整地址请求
// axios({
// method: post,
// url: http://127.0.0.1:8888/login/redis/setMessageCode,
// // url: login/redis/setMessageCode,
// // 这里需要注意不管请求方式是什么这里是根据后端传参方式来定的如果后端使用RequestParam则这里使用params作为key
// params: {
// username: loginForm.username
// }
// });// 2 使用axios实例传参请求后端接口地址的用法 api({method: post,url: /login/redis/setMessageCode,params: {username: loginForm.username}})curTime 60timer setInterval(() {curTime--;smsCodeBtnText.value curTime 秒后重新获取;if (curTime 0) {smsCodeBtnText.value 获取验证码clearInterval(timer)// 清除时值为空防止重复点击触发多次timer null}}, 1000)
}// 状态存储的store
const store useStore();
// 路由转到指定页面使用push
// const route useRoute();
const router useRouter();// 登录提交事件
const onSubmit () {// form表单中的值校验loginFormRef.value.validate((valid: string, fileds: any) {// 如果valid值为假则遍历输出报错if (!valid) {for (let key in fileds) {// 获取报错信息中的字段对应的key的索引为0的信息utils.showError(fileds[key][0].message)}return}// 登录表单的记住用户名如果被勾选if (loginForm.saveUsernametrue) {console.log(短信验证登录1,loginForm.saveUsername);// 保存输入的用户名utils.saveData(username, loginForm.username)// 保存被勾选的操作utils.saveData(saveUsername, loginForm.saveUsername)} else {console.log(短信验证登录2,loginForm.saveUsername);// 如果记住用户名的勾选取消则移除这两个存储的内容utils.removeData(username)utils.removeData(saveUsername)}// TODO 调用接口登录// 因为太快了所以可能看不到效果可以将下方的hideLoading方法注掉可以看到效果utils.showLoadding(正在加载中)api({method: get,url: /login/redis/getMessageCode,params: {username: loginForm.username,smscode: loginForm.smscode// imgcode: loginForm.imgcode}}).then((res) {utils.hideLoadding()console.log(res)// console.log(res.status)// if (!res || res.status ! 200 || !res.data || res.data.result ! 200 || !res.data.data) {if (res.status ! 200 || res.data.result ! 200 || !res.data.msgCode) {utils.showError(登录失败-请求数据返回有误);return;}// console.log(res.data.data, loginForm.smscode);if(res.data.msgCode loginForm.smscode){utils.showSuccess(登陆成功)// 存储用户token信息并转到主页// let userInfo res.data.datalet userInfo res.datalet token res.data.token// 状态数据存储store.commit(setUserInfo, userInfo);store.commit(setToken, token);// 登录成功后将页面转到主页router.push(/HomeIndex)}else if(res.data.msgCode ! loginForm.smscode){utils.showError(登录失败-验证码错误);return;}// utils.showError(登录失败)}).catch((error) {// utils.hideLoadding();console.log(error);utils.showError(登录失败-出现异常)})// api.post(/api/login/code,{// username: loginForm.username,// smscode: loginForm.smscode,// imgcode: loginForm.imgcode// }).then((res){// utils.hideLoadding();// console.log(res);// console.log(res.status);// if(!res || res.status ! 200 || !res.data || res.data.code ! 8888 || !res.data.data){// if(res.data.message){// utils.showError(res.data.message);// return;// }// utils.showError(登录失败);// return;// }// // 存储用户token信息并转到主页// let userInfo res.data.data;// let token res.data.token;// utils.showSuccess(登陆成功);// }).catch((error){// // utils.hideLoadding();// utils.showError(登录失败);// });// 登录成功信息提示// utils.showSuccess(登录成功);})
}// 挂载
onMounted(() {// 获取记住用户名的值loginForm.saveUsername utils.getData(saveUsername)// 如果记住用户名被勾选则获取用户名显示(saveUsername可能会是undefined当为undefined时也是真故这里不能直接使用saveUsername而是要判断是否为true)if (loginForm.saveUsernametrue) {loginForm.username utils.getData(username)}
})// 清空定时器
onUnmounted(() {timer clearInterval(timer)
})
/scripttemplate!-- 手机验证码登录 --div classphoneCodeLoginBoxel-formrefloginFormRefstylemax-width: 600px:modelloginForm:rulesruleslabel-width0classloginFrom:sizeformSizestatus-icon!-- 用户名 --el-form-item propusername!-- 图标设置动态绑定username提示信息设置输入框大小 --el-inputprefix-iconUserFilledv-modelloginForm.usernameplaceholder请输入用户名sizelarge//el-form-item!-- 短信验证 --el-form-item propsmscode!-- 使用两个div块来左右布局验证码输入和获取验证码按钮的实现 --div classflex loginLinediv classflexItemel-inputprefix-iconIphonev-modelloginForm.smscodeplaceholder请输入验证码sizelarge//divdiv classcodeBtnel-button typeprimary sizelarge clickgetSmsCode :disabledcurTime 0{{smsCodeBtnText}}/el-button/div/div/el-form-item!-- 图片验证 --el-form-item propimgcode!-- 使用两个div块来左右布局验证码输入和获取验证码按钮的实现 --div classflex loginLinediv classflexItemel-inputprefix-iconPicturev-modelloginForm.imgcodeplaceholder请输入图片验证码sizelarge/!-- el-input prefix-iconIphone v-modelloginForm.smscode placeholder请输入验证码 sizelarge / --/divdiv classcodeBtnel-image :srcimgCodeSrc sizelarge clickgetImgCode/el-image!-- el-button typeprimary sizelarge clickgetSmsCode class 获取验证码/el-button --/div/div/el-form-item!-- 记住用户名 --el-form-item propsaveUsernameel-checkbox v-modelloginForm.saveUsername记住用户名/el-checkbox/el-form-item!-- 登录按钮 --el-form-itemel-button classloginBtn typedanger sizelarge clickonSubmit登录/el-button/el-form-item/el-form/div
/templatestyle scoped
/* 按钮宽度设为最大 */
.loginBtn {width: 100%;/* 登录按钮圆角边框 */border-radius: 20px;
}/* 验证码按钮样式配置 */
.codeBtn {width: 100px;margin-left: 10px;
}
/* 按钮和图片宽度100px */
.codeBtn:deep(.el-button),
.codeBtn:deep(img) {width: 100px;/* height: 40px; */
}
/* 验证码图片高度 */
.codeBtn:deep(img) {height: 40px;/* 鼠标移上去会变成手型 */cursor: pointer;
}/* 这一行宽度占满 */
.loginLine {width: 100%;
}
/style
19.5 QcodeForm.vue
src/views/login/components/QcodeForm.vue 对二维码生成部分进行了优化
script setup langtsimport { ref,reactive, onMounted, onUnmounted } from vue// 引入工具方法
import utils from ../../../utils/utils
import api from ../../../api/api// 引入store
import {useStore} from vuex
// 引入router
import {useRouter} from vue-routerconst store useStore();const router useRouter();// 二维码// let qcodePath:any null;// 二维码对应的token 用于判断当前二维码是否已经被扫码登录let qrToken:string ;// 第一次获取验证码// api({// method: post,// url: login/qr/generateQrCodeAsFile// }).then((res){// if(res.data.result ! 200){// utils.showError(登录失败);// }// utils.showSuccess(登录成功);// qcodePath res.data.data// qrToken res.data.token// });// qcodePath E:\\WORKPROJECTS\\MySelfPro\\hslb-general-management-system\\src\\main\resources\\login_qr_pngs\\QRCode.png;// 二维码let qcodeSrc new URL(../../../assets/hslb-qcode.png, import.meta.url).href;// let qcodeSrc new URL(qcodePath, import.meta.url).href;// let qcodeSrc qcodePath;const qcodeToken ref();// 当前定时器事件const curTime ref(0);let timer:any null;let username:string utils.getData(username);const qrString 100100100222;// 后台更新获取二维码const loadQcode () {// 后续改为从服务器上获取动态图片// const qrString 100100100222;console.log(9999999 qrString);// let username:string utils.getData(username);api({method: post,url: login/qr/generateQrCodeAsFile,params: {username: username,qrContent: qrString}}).then((res){// if(res.data.result ! 200){// utils.showError(登录失败);// }// utils.showSuccess(登录成功);// qcodePath res.data.dataqrToken res.data.token});qcodeSrc new URL(../../../assets/hslb-qcode.png, import.meta.url).href;// qcodeSrc new URL(qcodePath, import.meta.url).href;// qcodeSrc qcodePath;// 初始化token的值qcodeToken.value qrToken;// 设定定时时间// curTime.value 60;// 为了让二维码失效的效果及时这里暂时设置10秒后续改回60秒即可curTime.value 10;// 定义定时器倒计时timer setInterval(() {curTime.value--;// 这里获取toekn校验是否已经被登陆过checkLogin();if(curTime.value0){// 事件为0则清空定时器clearInterval(timer);timer null;}}, 1000);};// 登录提交事件// const onSubmit () {// };// 挂载onMounted(() {// 获取二维码loadQcode();});// 清空计时器onUnmounted((){timer clearInterval(timer);});// 使用qcodeToken判断当前二维码是否已经被扫码登录const checkLogin () {// TODOapi({method: post,url: login/qr/generateQrCodeAsFile,params: {username: username,qrContent: qrString}}).then((res){if(res.data.token){utils.showSuccess(登录成功);store.commit(setUserInfo,res.data);store.commit(setToken,res.data.token);router.push(/HomeIndex);}// res.data.token;}).catch((error){console.log(error);// utils.showError(登录失败)});}/scripttemplate!-- 扫码登录 --div classqcodeLoginBoxdiv classqcodeBox img classqcodeImg :class{endImg:curTime0} :srcqcodeSrc alt无法获取二维码请联系客服解决div v-ifcurTime0 classendBox clickloadQcode 当前二维码失效点击重新加载{{ curTime }}秒/div/divdiv classtipInfo 使用微信或移动端扫码登录 此二维码将在{{ curTime }}秒后刷新/div/div/templatestyle scoped/* 二维码窗口样式 */.qcodeBox{width: 80%;height: 80%;position: relative;/* 边框自动 */margin: 0 auto; }/* 二维码图片样式 */.qcodeBox .qcodeImg{width: 100%;height: 100%;}.qcodeBox .endBox{width: 100%;height: 100%;/* 悬浮显示 */position: absolute;/* 靠左 *//* left: 0%; *//* 靠上 */top: 0;/* 居中 *//* text-align: center; *//* 字体大小 */font-size: 14px;/* 字体颜色 */color: red;display: flex;/* 上下居中 */align-items: center;/* justify-items: center; *//* 左右居中 */justify-content: center;/* 背景色为灰色 */background-color: #00000055;}/* .endImg{filter: brightness(10%);} *//* 提示信息样式 */.tipInfo{/* 行高 */line-height: 30px;/* 字体大小 */font-size: 14px;/* 居中 */text-align: center;/* 颜色 */color: var(--el-text-color-placeholder);}/style19.6 UsernameForm.vue
src/views/login/components/UsernameForm.vue 对登录缓存校验进行了优化
script setup langtsimport { ref,reactive, onMounted } from vue
// 引入状态存储store
import { useStore } from vuex
// 引入路由工具router
import { useRouter } from vue-router// 引入工具方法
import utils from ../../../utils/utils
import api from ../../../api/api// 登录表单的实例// let loginFormRef ref(null);let loginFormRef ref();// 登录表单的数据const loginForm reactive({// 用户名username: ,// 密码password: ,// 图片验证imgcode: ,// 记住用户名默认否saveUsername: false,// 记住用户名默认否savePassword: false});// 登录验证规则const rules ({username:[{required: true,message: 请输入用户名,trigger: blur}],password:[{required: true,message: 请输入密码,trigger: blur}],imgcode:[{required: true,message: 请输入图片验证码,trigger: blur}]});const formSize ;// 图片验证码路径let imgCodeSrc new URL(../../../assets/code.png, import.meta.url).href;// const imgCodeSrc ../../../assets/code.png;// 刷新图片验证码const getImgCode () {// 后续改为从服务器上获取动态图片imgCodeSrc new URL(../../../assets/code.png, import.meta.url).href;};// 全局状态存储const store useStore();// 路由调用const router useRouter();// 登录提交事件const onSubmit () {// form表单中的值校验loginFormRef.value.validate((valid:string, fileds:any){// 如果valid值为假则遍历输出报错if(!valid){for(let key in fileds){// 获取报错信息中的字段对应的key的索引为0的信息utils.showError(fileds[key][0].message);}return;}// 登录表单的记住用户名如果被勾选if(loginForm.saveUsername){// 保存输入的用户名utils.saveData(username, loginForm.username);// 保存被勾选的操作utils.saveData(saveUsername, loginForm.saveUsername);}else{// 如果记住用户名的勾选取消则移除这两个存储的内容utils.removeData(username);utils.removeData(saveUsername);}// 登录表单的记住用户名如果被勾选if(loginForm.savePassword){// 保存输入的用户名utils.saveData(password, loginForm.password);// 保存被勾选的操作utils.saveData(savePassword, loginForm.savePassword);}else{// 如果记住用户名的勾选取消则移除这两个存储的内容utils.removeData(password);utils.removeData(savePassword);}// TODO 调用接口登录utils.showLoadding(正在加载中);api({method: get,url: /login/login,params: {username: loginForm.username,password: loginForm.password}}).then((res){utils.hideLoadding();if(res.status ! 200 || res.data.result ! 200){utils.showError(登录失败-请求数据返回有误);return;}if(res.data.login 1){utils.showSuccess(登录成功);// 存储用户信息// let userInfoLogin res.data.login;let userInfoLogin res.data;let token res.data.token;console.log(usernamelogin:, token);store.commit(setUserInfo, userInfoLogin);store.commit(setToken, token);console.log(----------------token: , token);// 登录成功后跳转主页router.push(/HomeIndex);}else if(res.data.login 0){utils.showError(登录失败-用户不存在);return;}else if(res.data.login 2){utils.showError(登录失败-密码错误);return;}// utils.showError(登录失败-返回数据错误)}).catch((error){console.log(error);utils.showError(登录失败-发生异常);});// 登录成功提示// utils.showSuccess(登录成功);});};// 挂载onMounted(() {// 获取记住用户名的值loginForm.saveUsername utils.getData(saveUsername);// 如果记住用户名被勾选则获取用户名显示if(loginForm.saveUsernametrue){loginForm.username utils.getData(username);}// 获取记住密码的值loginForm.savePassword utils.getData(savePassword);// 如果记住密码被勾选则获取密码if(loginForm.savePasswordtrue){loginForm.password utils.getData(password);}});/scripttemplate!-- 用户密码登录 --div classusernameLoginBoxel-form refloginFormRefstylemax-width: 600px:modelloginForm:rulesruleslabel-width0classloginFrom:sizeformSize status-icon!-- 用户名 --el-form-item propusername!-- 图标设置动态绑定username提示信息设置输入框大小 --el-input prefix-iconUserFilled v-modelloginForm.username placeholder请输入用户名 sizelarge //el-form-item!-- 密码 --el-form-item proppassword!-- 密码 --div classflexItem !-- show-password 属性表示是否显示切换显示密码的图标true为显示 --!-- el-input prefix-iconLock show-passwordoff typepassword v-modelloginForm.password placeholder请输入密码 sizelarge / --el-input prefix-iconLock show-password typepassword v-modelloginForm.password placeholder请输入密码 sizelarge //div/el-form-item!-- 图片验证 --el-form-item propimgcode!-- 使用两个div块来左右布局验证码输入和获取验证码按钮的实现 --div classflex loginLinediv classflexItem el-input prefix-iconPicture v-modelloginForm.imgcode placeholder请输入图片验证码 sizelarge /!-- el-input prefix-iconIphone v-modelloginForm.smscode placeholder请输入验证码 sizelarge / --/divdiv classcodeBtn el-image :srcimgCodeSrc sizelarge clickgetImgCode /el-image!-- el-button typeprimary sizelarge clickgetSmsCode class 获取验证码/el-button --/div/div/el-form-item!-- el-form-item propsaveUsername --el-form-item !-- 记住账号密码的勾选 --div classflex loginLine !-- 记住用户名 --div classflexItem el-form-item propsaveUsernameel-checkbox v-modelloginForm.saveUsername记住用户名/el-checkbox/el-form-item/div!-- 记住密码 --div classflexItem el-form-item propsavePasswordel-checkbox v-modelloginForm.savePassword记住密码/el-checkbox/el-form-item/div/div/el-form-item!-- el-form-item propsavePassword --!-- /el-form-item --!-- 登录按钮 --el-form-itemel-button classloginBtn typedanger sizelarge clickonSubmit登录/el-button/el-form-item/el-form/div/templatestyle scoped/* 按钮宽度设为最大 */.loginBtn{width: 100%;/* 登录按钮圆角边框 */border-radius: 20px;}/* 验证码按钮样式配置 */.codeBtn{width: 100px;margin-left: 10px;}/* 按钮和图片宽度100px */.codeBtn:deep(.el-button),.codeBtn:deep(img){width: 100px;/* height: 40px; */}/* 验证码图片高度 */.codeBtn:deep(img){height: 40px;/* 鼠标移上去会变成手型 */cursor: pointer;}/* 这一行宽度占满 */.loginLine{width: 100%}/style19.7 App.vue
src/App.vue 对登录缓存校验进行了优化
script setup langts
import { onMounted } from vue;
import { useStore } from vuex;
import { useRouter } from vue-router;
import utils from ./utils/utils;
import api from ./api/api;// // // 引入暗黑主题的动态切换
// import { useDark, useToggle } from vueuse/core// const isDark useDark()
// // // 切换主题函数
// const toggleDark useToggle(isDark)// 状态存储
let store useStore();// 路由使用
const router useRouter();onMounted((){// let tt localStorage.getItem(token);// console.log(tt: ,tt);console.log( );let token ;// 由于token可能返回undefined报错需要进行报错处理try {token utils.getData(token);} catch (error) {error;}console.log(store-token,token);let userInfo utils.getData(userInfo);console.log(userInfoL: userInfo)console.log(userInfoL: tokenuserInfo)if(token userInfo){console.log(token userInfo :,token, -- , userInfo);// 登录成功验证utils.showLoadding(正在加载)const username utils.getData(username);if(!username){// 登录失败跳转到登录页if(usernameundefined){utils.saveData(username,);}// token验证失败utils.showError(用户名过期-请重新登录);router.push(/UserLogin);utils.hideLoadding();}else{console.log(username-, username);api.get(/login/tokenCheck,{params:{username}}).then((res){console.log(res.data.token,res.data);utils.hideLoadding();if(res.data.tokentoken){// 登陆成功// store.commit(setUserInfo, userInfo);// store.commit(setToken, token);router.push(/HomeIndex);utils.showSuccess(登录成功);}else{// if(usernameundefined){// utils.saveData(username,);// }// 登录失败utils.showError(Token已过期请重新登录);// 登录失败跳转到登录页router.push(/UserLogin);}});utils.hideLoadding();}}else{// 登录失败跳转到登录页utils.showError(用户登录缓存过期请重新登录);router.push(/UserLogin);utils.hideLoadding();}});/scripttemplate!-- 暗黑主题动态切换按钮实现 --!-- button clicktoggleDark()i inline-block align-middle idark:carbon-moon carbon-sun/span classml-2{{ isDark ? Dark : Light }}/span/button --RouterView/RouterView/templatestyle scoped/style
19.8 页面效果展示
19.8.1 使用短信验证码登录的展示
登录前
不勾选记住用户名登录
输入用户名点击获取验证码按钮获取验证码后填入redis中查看并填写图片验证码此项随机填写即可不勾选记住用户名
登录成功界面 60秒内刷新页面如下
等待60秒后刷新界面token设定的是60秒过期故过期后需要重新登录
勾选记住用户名登录
输入用户名点击获取验证码按钮获取验证码后填入redis中查看并填写图片验证码此项随机填写即可勾选记住用户名
登录成功界面 60秒内刷新页面如下
60秒后刷新界面
19.8.2 使用账号密码登录的展示
登录前 不勾选记住用户名密码登录
登录成功后 60秒后刷新页面
勾选记住用户名密码登录 登录成功 60秒后刷新页面
19.8.3 使用二维码登录的展示
这里没有做任何逻辑进行用户的登录只是生成了一个token并且当前用户名是另外两种登录方式存储的缓存此时直接验证通过 登录成功 60秒后刷新页面会跳转到短信登录 感谢阅读祝君暴富
文章转载自: http://www.morning.nqgds.cn.gov.cn.nqgds.cn http://www.morning.lkthj.cn.gov.cn.lkthj.cn http://www.morning.lflnb.cn.gov.cn.lflnb.cn http://www.morning.knmby.cn.gov.cn.knmby.cn http://www.morning.twfdm.cn.gov.cn.twfdm.cn http://www.morning.bnxnq.cn.gov.cn.bnxnq.cn http://www.morning.ryrpq.cn.gov.cn.ryrpq.cn http://www.morning.wnzgm.cn.gov.cn.wnzgm.cn http://www.morning.nngq.cn.gov.cn.nngq.cn http://www.morning.owenzhi.com.gov.cn.owenzhi.com http://www.morning.ccpnz.cn.gov.cn.ccpnz.cn http://www.morning.kgsws.cn.gov.cn.kgsws.cn http://www.morning.lpyjq.cn.gov.cn.lpyjq.cn http://www.morning.kgslc.cn.gov.cn.kgslc.cn http://www.morning.fbqr.cn.gov.cn.fbqr.cn http://www.morning.lwwnq.cn.gov.cn.lwwnq.cn http://www.morning.ybgyz.cn.gov.cn.ybgyz.cn http://www.morning.c7498.cn.gov.cn.c7498.cn http://www.morning.mtsgx.cn.gov.cn.mtsgx.cn http://www.morning.njntp.cn.gov.cn.njntp.cn http://www.morning.yznsx.cn.gov.cn.yznsx.cn http://www.morning.gfnsh.cn.gov.cn.gfnsh.cn http://www.morning.yrkdq.cn.gov.cn.yrkdq.cn http://www.morning.zwznz.cn.gov.cn.zwznz.cn http://www.morning.lcjw.cn.gov.cn.lcjw.cn http://www.morning.tbzcl.cn.gov.cn.tbzcl.cn http://www.morning.zlcsz.cn.gov.cn.zlcsz.cn http://www.morning.xdhcr.cn.gov.cn.xdhcr.cn http://www.morning.pqwhk.cn.gov.cn.pqwhk.cn http://www.morning.bmjfp.cn.gov.cn.bmjfp.cn http://www.morning.rpzqk.cn.gov.cn.rpzqk.cn http://www.morning.ywpwg.cn.gov.cn.ywpwg.cn http://www.morning.znrlg.cn.gov.cn.znrlg.cn http://www.morning.dwmtk.cn.gov.cn.dwmtk.cn http://www.morning.xkjrs.cn.gov.cn.xkjrs.cn http://www.morning.fycjx.cn.gov.cn.fycjx.cn http://www.morning.fmkbk.cn.gov.cn.fmkbk.cn http://www.morning.yrccw.cn.gov.cn.yrccw.cn http://www.morning.tsxg.cn.gov.cn.tsxg.cn http://www.morning.wdhlc.cn.gov.cn.wdhlc.cn http://www.morning.dlmqn.cn.gov.cn.dlmqn.cn http://www.morning.wscfl.cn.gov.cn.wscfl.cn http://www.morning.prjns.cn.gov.cn.prjns.cn http://www.morning.kpgft.cn.gov.cn.kpgft.cn http://www.morning.ypqwm.cn.gov.cn.ypqwm.cn http://www.morning.hilmwmu.cn.gov.cn.hilmwmu.cn http://www.morning.ygwbg.cn.gov.cn.ygwbg.cn http://www.morning.ntgjm.cn.gov.cn.ntgjm.cn http://www.morning.ksgjn.cn.gov.cn.ksgjn.cn http://www.morning.qkdbz.cn.gov.cn.qkdbz.cn http://www.morning.hnpkr.cn.gov.cn.hnpkr.cn http://www.morning.jjzjn.cn.gov.cn.jjzjn.cn http://www.morning.cwfkm.cn.gov.cn.cwfkm.cn http://www.morning.ckntb.cn.gov.cn.ckntb.cn http://www.morning.mxnrl.cn.gov.cn.mxnrl.cn http://www.morning.zlces.com.gov.cn.zlces.com http://www.morning.bpp999.com.gov.cn.bpp999.com http://www.morning.xkhxl.cn.gov.cn.xkhxl.cn http://www.morning.gwsll.cn.gov.cn.gwsll.cn http://www.morning.krtcjc.cn.gov.cn.krtcjc.cn http://www.morning.bflwj.cn.gov.cn.bflwj.cn http://www.morning.tbjtp.cn.gov.cn.tbjtp.cn http://www.morning.ktnt.cn.gov.cn.ktnt.cn http://www.morning.dpjtn.cn.gov.cn.dpjtn.cn http://www.morning.trtdg.cn.gov.cn.trtdg.cn http://www.morning.gbgdm.cn.gov.cn.gbgdm.cn http://www.morning.hkshy.cn.gov.cn.hkshy.cn http://www.morning.krqhw.cn.gov.cn.krqhw.cn http://www.morning.wjmb.cn.gov.cn.wjmb.cn http://www.morning.bnzjx.cn.gov.cn.bnzjx.cn http://www.morning.mfsjn.cn.gov.cn.mfsjn.cn http://www.morning.jmbfx.cn.gov.cn.jmbfx.cn http://www.morning.yhywr.cn.gov.cn.yhywr.cn http://www.morning.mkrqh.cn.gov.cn.mkrqh.cn http://www.morning.xqgh.cn.gov.cn.xqgh.cn http://www.morning.wbyqy.cn.gov.cn.wbyqy.cn http://www.morning.lmmkf.cn.gov.cn.lmmkf.cn http://www.morning.jbxfm.cn.gov.cn.jbxfm.cn http://www.morning.gnghp.cn.gov.cn.gnghp.cn http://www.morning.bjndc.com.gov.cn.bjndc.com