登陆和注册界面开发

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函数职责就是告诉你,代码执行的流程

登陆和注册界面实现

登陆界面.png
注册界面.png
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容