零基础快速开发Vue图书管理系统—登录注册篇

Posted 王同学要努力

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了零基础快速开发Vue图书管理系统—登录注册篇相关的知识,希望对你有一定的参考价值。

零基础快速开发Vue图书管理系统—登录注册篇(一)

一、图书管理系统项目功能

二、项目技术选型

  • 前端主要采用:Vue3.x (vuex/vue-router)、Ant Design Vue、Axios
  • 服务端主要采用:Node.js、Koa、Mongoose
  • 数据库主要采用:MongoDB

三、使用vue-cli3创建项目

如何搭建环境看我之前写的文章:五分钟教你使用vue-cli3创建项目(三种创建方式,小白入门必看)

四、搭建所需的文件

在view的目录下新建Auth文件夹,里面分别放以下三个文件

前端UI框架主要采用Ant Design Vue


😛index.vue内容如下

<template>
    <div class="auth">
        <div class="bg"></div>
        <div class="title-info">
            <img src="https://ncstatic.clewm.net/rsrc/2020/1016/02/4757e4910cb527fc040d019a93ded74f.png?x-oss-process=image/resize,w_750/format,gif/sharpen,100/quality,Q_80/interlace,1/auto-orient,1"
                alt="">
            <h2 class="title">图书后台管理系统</h2>
        </div>
        <div class="form">
            <a-tabs>
                <a-tab-pane key="1" tab="登录">
                    <div class="item">
                        <a-input size="large" placeholder="账户">
                            <template v-slot:prefix>
                                <UserOutlined />
                            </template>
                        </a-input>

                    </div>

                    <div class="item">
                        <a-input size="large" placeholder="密码">
                            <template v-slot:prefix>
                                <LockOutlined />
                            </template>
                        </a-input>
                    </div>
                    <div class="item">
                        <a href="">忘记密码</a>
                    </div>

                    <div class="item">
                        <a-button size="large" type="primary">
                            登录
                        </a-button>
                    </div>
                </a-tab-pane>
                <a-tab-pane key="2" tab="注册">
                    <div class="item">
                        <a-input size="large" placeholder="账户">
                            <template v-slot:prefix>
                                <UserOutlined />
                            </template>
                        </a-input>
                    </div>

                    <div class="item">
                        <a-input size="large" placeholder="密码">
                            <template v-slot:prefix>
                                <LockOutlined />
                            </template>

                        </a-input>
                    </div>
                    <div class="item">
                        <a-input size="large" placeholder="邀请码">
                            <template v-slot:prefix>
                                <MailOutlined />
                            </template>

                        </a-input>
                    </div>
                    <div class="item">
                        <a-button size="large" type="primary">
                            注册
                        </a-button>
                    </div>
                </a-tab-pane>
            </a-tabs>
        </div>
    </div>
</template>
<script src="./index.js">
</script>
<style lang="scss" scoped>
    @import './index.scss'
</style>

😅index.scss内容如下:

.bg 
    position: fixed;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    background-image: url("https://gw.alipayobjects.com/zos/rmsportal/TVYTbAXWheQpRcWDaDMu.svg");
    background-repeat: no-repeat;
    background-size: cover;
    background-position: center center;


.auth 
    .title-info 
        display: flex;
        margin-top: 100px;
        text-align: center;
        align-items: center;
        justify-content: center;
        margin-bottom: 32px;
        img 
            width: 60px;
            height: 60px;
        
        h2 
            margin: 0;
            margin-left: 18px;
        
    
    .form 
        width: 400px;
        margin: 0 auto;
        .item 
            margin-bottom: 16px;
            button 
                width: 100%;
            
        
    

🤣index.js内容如下:

 import  defineComponent  from 'vue';
 import  UserOutlined, LockOutlined, MailOutlined  from '@ant-design/icons-vue';

 export default defineComponent(
     components: 
         UserOutlined,
         LockOutlined,
         MailOutlined
     ,
     setup() 

     

 );

五、服务端开发

执行以下命令安装koa

npm i @koa/router

服务端文件结构如下:




六、nodemon使用

编写调试Node的时候,项目代码做了修改,需要频繁手动停止,在重新启动,非常繁琐,使用nodemon能够监听项目文件的变动,当代码被修改后,nodemon会自动重启项目,极大方便了开发和调试

在终端中,运行如下命令,即可将nodemon安装为全局可用的工具:

npm install -g nodemon
  • 传统的方式是运行node app.js命令启动项目,需要手动重启
  • 现在将node命令替换为nodemon命令,使用nodemon app.js启动项目,会自动重启

七、使用JWT和Session实现登录注册


📢📢📢登录部分(服务端)



核心代码如下:

const Router = require('@koa/router');
const mongoose = require('mongoose');
const  getBody  = require('../../helpers/utils')
const jwt = require('jsonwebtoken');

const User = mongoose.model('User');

const router = new Router(
    prefix: '/auth',
);


router.post('/register', async(ctx) => 
    // console.log(ctx.request.body);
    const 
        account,
        password,
     = getBody(ctx);

    const one = await User.findOne(
        account,
    ).exec();

    if (one) 
        ctx.body = 
            code: 0,
            msg: '已存在该用户',
            data: null,
        
        return;

    
    const user = new User(
        account,
        password

    );
    const res = await user.save();
    ctx.body = 
        code: 1,
        msg: '注册成功',
        data: res,
    
);
router.post('/login', async(ctx) => 
    const 
        account,
        password,
     = getBody(ctx);

    const one = await User.findOne(
        account,
    ).exec();

    if (!one) 
        ctx.body = 
            code: 0,
            msg: '用户名或者密码错误',
            data: null,
        
        return;
    
    const user = 
        account: one.account,
        _id: one._id,
    
    if (one.password === password) 
        ctx.body = 
            code: 1,
            msg: '登录成功',
            data: 
                user,
                token: jwt.sign(user, 'manage')
            ,

        
        return;
    
    ctx.body = 
        code: 0,
        msg: '用户名或密码错误',
        data: null,
    
);

module.exports = router;

📢📢📢登录部分(前端)


核心代码:

 import  defineComponent, reactive  from 'vue';
 import  UserOutlined, LockOutlined, MailOutlined  from '@ant-design/icons-vue';
 import  auth  from '@/service';
 export default defineComponent(
     components: 
         UserOutlined,
         LockOutlined,
         MailOutlined,
     ,
     setup() 
         //注册相关的逻辑
         const regForm = reactive(
                 account: '',
                 password: '',
             )
             //注册逻辑
         const register = () => 
                 auth.register(regForm.account, regForm.password)
             
             //登录相关的逻辑
         const loginForm = reactive(
             account: '',
             password: '',
         );
         //登录逻辑
         const login = () => 
             auth.login(loginForm.account, loginForm.password)
         
         return 
             //注册相关的数据
             register,
             regForm,
             //登录相关的数据
             login,
             loginForm,
         
     

 );

index.vue

<template>
    <div class="auth">
        <div class="bg"></div>
        <div class="title-info">
            <img src="https://ncstatic.clewm.net/rsrc/2020/1016/02/4757e4910cb527fc040d019a93ded74f.png?x-oss-process=image/resize,w_750/format,gif/sharpen,100/quality,Q_80/interlace,1/auto-orient,1"
                alt="">
            <h2 class="title">图书后台管理系统</h2>
        </div>
        <div class="form">
            <a-tabs>
                <a-tab-pane key="1" tab="登录">
                    <div class="item">
                        <a-input 
                        v-model:value="loginForm.account"
                        size="large" 
                        placeholder="账户">
                            <template v-slot:prefix>
                                <UserOutlined />
                            </template>
                        </a-input>

                    </div>

                    <div class="item">
                        <a-input 
                        v-model:value="loginForm.password"
                        size="large" 
                        placeholder="密码">
                            <template v-slot:prefix>
                                <LockOutlined />
                            </template>
                        </a-input>
                    </div>
                    <div class="item">
                        <a href="">忘记密码</a>
                    </div>

                    <div class="item">
                        <a-button 
                        @click="login"
                        size="large" 
                        type="primary">
                            登录
                        </a-button>
                    </div>
                </a-tab-pane>
                <a-tab-pane key="2" tab="注册">
                    <div class="item">
                        <a-input 
                        size="large"
                        placeholder="账户"
                        v-model:value="regForm.account"
                        >
                            <template v-slot:prefix>
                                <UserOutlined />
                            </template>
                        </a-input>
                    </div>

                    <div class="item">
                        <a-input 
                        size="large" 
                        placeholder="密码"
                        v-model:value="regForm.password"
                        >
                            <template v-slot:prefix>
                                <LockOutlined />
                            </template>

                        </a-input>
                    </div>
                    <div class="item">
                        <a-input size="large" placeholder="邀请码">
                            <template v-slot:prefix>
                                <MailOutlined />
                            </template>

                        </a-input>
                    </div>
                    <div class="item">
                        <a-button 
                        size="large" 
                        type="primary"
                        @click="register">
                            注册
                        </a-button>
                    </div>
                </a-tab-pane>
            </a-tabs>
        </div>
    </div>
</template>
<script src="./index.js">
</script>
<style lang="scss" scoped>
    @import './index.scss'
</style>

八、交互优化、表单校验、处理请求结果优化

登录注册逻辑校验






九、邀请码实现,完善注册流程


const Router = require('@koa/router');
const mongoose = require('mongoose');
const  getBody  = require('../../helpers/utils')
const jwt = require('jsonwebtoken');

const User = mongoose.model('User');
const InviteCode = mongoose.model('InviteCode');
const router = new Router(
    prefix: '/auth',
);


router.post('/register', async(ctx) => 

    const 
        account,
        password,
        inviteCode,
     = getBody(ctx);
    //表单校验
    if (account === '' || password === '' || inviteCode === '') 
        ctx.body = 
            code: 0,
            msg: '字段不能为空',
            data: null,
        
        return;
    
    //找是否有邀请码
    const findCode = await InviteCode.findOne(
        code: inviteCode,
    ).exec();
    //如果没有找到邀请码
    if ((!findCode) || findCode.user) 
        ctx.body = 
            code: 0,
            msg: '邀请码不正确',
            data: null,
        
        return;
    

    //去找account为传递上来的account的用户
    const findUser = await User.findOne(
        account,
    ).exec();
    //判断是否有用户
    if (findUser) 
        //如果有表示已经存在
        ctx.body = 
            code: 0,
            msg: '已存在该用户',
            data: null,
        
        return;

    
    //创建用户
    const user = new User(
        account,
        password

    );
    //把创建的用户同步到mongdb
    const res = await user.save();

    findCode.user = res._id;
    findCode.meta.updatedAt = new Date().getTime();
    await findCode.save();
    //响应成功
    ctx.body = 
        code: 1,
        msg: '注册成功',
        data: res,
    
);
router.post('/login', async(ctx) => 
    const 
        account,
        password,
     = getBody(ctx);

    if (account === '' || password === '') 
        ctx.body = 
            code: 0,
            msg: '字段不能为空',
            data: null,
        
        return;
    

    const one = await User.findOne(
        account,
    ).exec();

    if (!one) 
        ctx.body = 
            code: 0,
            msg: '用户名或者密码错误',
            data: null,
        
        return;
    
    const user = 
        account: one.account,
        _id: one._id,
    
    if (one.password === password) 
        ctx.body = 
            code: 1,
            msg: '登录成功',
            data: 
                user,
                token: jwt.sign(user, 'manage')
            ,

        
        return;
    
    ctx.body = 
        code: 0,
        msg: '用户名或密码错误',
        data: null,
    
);

module.exports = router;

以上是关于零基础快速开发Vue图书管理系统—登录注册篇的主要内容,如果未能解决你的问题,请参考以下文章

零基础快速开发Vue图书管理系统—主体列表实现篇

零基础快速开发Vue图书管理系统—主体列表实现篇

零基础快速开发Vue图书管理系统—主体列表实现篇

零基础快速开发Vue图书管理系统—主体列表实现篇

零基础快速开发Vue图书管理系统—主体列表实现篇

零基础快速开发Vue图书管理系统—主体列表实现篇