1.路由守卫实现基础校验功能
(1)在router文件夹下面的index.js文件中,写入
beforeEnter(to,from,next){
const {isLogin} =localStorage;
isLogin ? next({name:"Home"}) : next();
},
(2)使用axios发送登陆mock请求
将请求函数进行封装,在src建立一个utils文件夹,在utils文件夹下创建一个request.js文件
request.js
import axios from 'axios';
const instance = axios.create({
baseURL:'https://www.fastmock.site/mock/ae8e9031947a302fed5f92425995aa19/jd',
timeout:10000
})
export const get = (url,params = {})=>{
return new Promise((resolve,reject) => {
instance.get(url,{params}).then((response)=>{
resolve(response.data)
},err=>{
reject(err)
})
})
}
export const post = (url,data = {})=>{
return new Promise((resolve,reject) => {
instance.post(url,data,{
headers:{
'Content-Type':'application/json'
}
}).then((response)=>{
resolve(response.data)
},err=>{
reject(err)
})
})
}
登陆请求跳转到首页的函数
const handleLogin= async ()=>{
try{
const result = await post('/api/user/login',{
username:data.username,
password:data.password
})
if(result?.errno === 0){
localStorage.isLogin=true;
router.push({name:'Home'});
}else{
showToast("登陆失败")
}
}catch(e){
showToast("请求失败")
}
}
弹窗组件的开发ToastV.vue
<template>
<div class="toast">{{message}}</div>
</template>
<script>
import { reactive,toRefs } from 'vue';
export default {
props:["message"],
setup() {
},
}
export const useToastEffect = ()=>{
const toastData = reactive({
show:false,
toastMessage:''
});
const showToast = (message)=>{
toastData.show=true;
toastData.toastMessage=message;
setTimeout(()=>{
toastData.show=false;
toastData.toastMessage='';
},3000)
}
const { show,toastMessage } = toRefs(toastData);
return {show,toastMessage,showToast}
}
</script>
<style lang="scss" scoped>
@import '../style/viriables.scss';
.toast{
position: fixed;
left: 50%;
top:50%;
transform: translate(-50%,-50%);
padding: .1rem;
background: rgba(0,0,0,.35);
border-radius: .05rem;
color: $bgColor;
}
</style>
2.整体代码如下
LoginV.vue
<template>
<div class="wrapper">
<img class="wrapper__img" src="http://www.dell-lee.com/imgs/vue3/user.png" />
<div class="wrapper__input">
<input
class="wrapper__input__content"
placeholder="请输入用户名"
v-model="username"
/>
</div>
<div class="wrapper__input">
<input
class="wrapper__input__content"
placeholder="请输入密码"
type="password"
v-model="password"
autocomplete="new-password"
/>
</div>
<div class="wrapper__login-button" @click="handleLogin">登陆</div>
<div class="wrapper__login-link" @click="handleRegisterClick">立即注册</div>
<ToastV v-if="show" :message="toastMessage" />
</div>
</template>
<script>
import {useRouter} from 'vue-router';
import {post} from '../../utils/request'
import { reactive,toRefs } from 'vue';
import ToastV,{useToastEffect} from '../../components/ToastV.vue'
const useLoginEffect = (showToast)=>{
const router = useRouter();
const data = reactive({ username:'', password:'', });
const handleLogin= async ()=>{
try{
const result = await post('/api/user/login',{
username:data.username,
password:data.password
})
if(result?.errno === 0){
localStorage.isLogin=true;
router.push({name:'Home'});
}else{
showToast("登陆失败")
}
}catch(e){
showToast("请求失败")
}
}
const { username,password } = toRefs(data);
return {username,password,handleLogin}
}
const useRegisterEffect = ()=>{
const router = useRouter();
const handleRegisterClick = ()=>{
router.push({name:"Register"});
}
return {handleRegisterClick}
}
export default {
name:'LoginV',
components:{ToastV},
//职责就是告诉你,代码执行的流程
setup() {
const {show,toastMessage,showToast} = useToastEffect();
const {username,password,handleLogin} = useLoginEffect(showToast);
const {handleRegisterClick} = useRegisterEffect();
return{
username,password,show,toastMessage,
handleLogin,handleRegisterClick,
}
},
}
</script>
<style lang="scss" scoped>
@import '../../style/viriables.scss';
.wrapper{
position:absolute;
top: 50%;
left: 0;
right: 0;
transform: translateY(-50%);
&__img{
display: block;
margin: 0 auto .4rem auto;
width: .66rem;
height: .66rem;
}
&__input{
box-sizing: border-box;
height: .48rem;
margin: 0 .4rem .16rem .4rem;
padding: 0 .16rem;
background: #F9F9F9;
border: .01rem solid rgba(0,0, 0 ,0.10);
border-radius: .06rem;
&__content{
margin-top: .12rem;
line-height: .22rem;
border: none;
outline: none;
width: 100%;
background: none;
font-size: .16rem;
color:$content-notice-fontcolor;
&::placeholder{
color:$content-notice-fontcolor;
}
}
}
&__login-button{
margin: .32rem .4rem .16rem .4rem;
line-height: .48rem;
font-size: .16rem;
background: $btn-bgColor;
box-shadow: 0 .04rem .08rem 0 rgba( 0, 145,255,0.32);
border-radius: .04rem;
color: $bgColor;
text-align: center;
}
&__login-link{
text-align: center;
font-size: .14rem;
color: $content-notice-fontcolor ;
}
}
</style>
注册界面RegisterV.Vue
<template>
<div class="wrapper">
<img class="wrapper__img" src="http://www.dell-lee.com/imgs/vue3/user.png" />
<div class="wrapper__input">
<input
class="wrapper__input__content"
placeholder="请输入用户名"
v-model="username"
/>
</div>
<div class="wrapper__input">
<input
class="wrapper__input__content"
placeholder="请输入密码"
type="password"
autocomplete="new-password"
v-model="password"
/>
</div>
<div class="wrapper__input">
<input
class="wrapper__input__content"
placeholder="确认密码"
type="password"
v-model="ensurement"
/>
</div>
<div class="wrapper__register-button" @click="handleRegister">注册</div>
<div class="wrapper__register-link" @click="handleLoginClick">已有账号去登陆</div>
<ToastV v-if="show" :message="toastMessage" />
</div>
</template>
<script>
import {useRouter} from "vue-router";
import { reactive,toRefs } from 'vue';
import {post} from '../../utils/request';
import ToastV,{useToastEffect} from '../../components/ToastV.vue'
//注册相关逻辑
const useRegisterEffect = (showToast)=>{
const router = useRouter();
const data = reactive({ username:'', password:'',ensurement:'' });
const handleRegister= async ()=>{
try{
const result = await post('/api/user/register',{
username:data.username,
password:data.password
})
if(result?.errno === 0){
router.push({name:'Login'});
}else{
showToast("注册失败")
}
}catch(e){
showToast("请求失败")
}
}
const { username,password,ensurement } = toRefs(data);
return {username,password,ensurement,handleRegister}
}
export default {
name:'RegisterV',
components:{ToastV},
setup() {
const router = useRouter();
const {show,toastMessage,showToast} = useToastEffect();
const { username,password,ensurement,handleRegister} = useRegisterEffect(showToast);
const handleLoginClick = ()=>{
router.push({name:"Login"});
}
return {
username,password,ensurement,show,toastMessage,
handleRegister,handleLoginClick
}
},
}
</script>
<style lang="scss" scoped>
@import '../../style/viriables.scss';
.wrapper{
position: absolute;
top: 50%;
left: 0;
right: 0;
transform: translateY(-50%);
&__img{
display: block;
margin: 0 auto .4rem auto;
width: .66rem;
height: .66rem;
}
&__input{
box-sizing: border-box;
height: .48rem;
margin: 0 .4rem .16rem .4rem;
padding: 0 .16rem;
background: #F9F9F9;
border: .01rem solid rgba(0,0, 0 ,0.10);
border-radius: .06rem;
&__content{
line-height: .48rem;
border: none;
outline: none;
width: 100%;
background: none;
font-size: .16rem;
color:$content-notice-fontcolor;
&::placeholder{
color:$content-notice-fontcolor;
}
}
}
&__register-button{
margin: .32rem .4rem .16rem .4rem;
line-height: .48rem;
font-size: .16rem;
background: $btn-bgColor;
box-shadow: 0 .04rem .08rem 0 rgba( 0, 145,255,0.32);
border-radius: .04rem;
color: $bgColor;
text-align: center;
}
&__register-link{
text-align: center;
font-size: .14rem;
color: $content-notice-fontcolor ;
}
}
</style>
通过代码拆分可提高代码的维护性,将代码封装好放入script内,在setup中引用
setup函数职责就是告诉你,代码执行的流程