手把手教你使用Vue搭建注册登录界面及前端源码
2021/7/20 12:06:43
本文主要是介绍手把手教你使用Vue搭建注册登录界面及前端源码,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
文章目录
- 一、前言
- 二、概况
- 三、搭建注册页面
- 四、改造登录页面
- 四、整体效果动画演示
- 五、前端源码下载
- 六、后续
一、前言
-
本文将在vue-admin-template模板基础上完成搭建注册与登录页面。文末处有完整的前端源码下载。
-
环境准备
- 浏览器:Chrome
- IDE: VS Code
- Node.js 10+,npm
二、概况
- 我们先了解一下整个项目的目录结构
├── build # 构建相关 ├── mock # 项目mock 模拟数据 ├── plop-templates # 基本模板 ├── public # 静态资源 │ │── favicon.ico # favicon图标 │ └── index.html # html模板 ├── src # 源代码 │ ├── api # 所有请求 │ ├── assets # 主题 字体等静态资源 │ ├── components # 全局公用组件 │ ├── directive # 全局指令 │ ├── filters # 全局 filter │ ├── icons # 项目所有 svg icons │ ├── lang # 国际化 language │ ├── layout # 全局 layout │ ├── router # 路由 │ ├── store # 全局 store管理 │ ├── styles # 全局样式 │ ├── utils # 全局公用方法 │ ├── vendor # 公用vendor │ ├── views # views 所有页面 │ ├── App.vue # 入口页面 │ ├── main.js # 入口文件 加载组件 初始化等 │ └── permission.js # 权限管理 ├── tests # 测试 ├── .env.xxx # 环境变量配置 ├── .eslintrc.js # eslint 配置项 ├── .babelrc # babel-loader 配置 ├── .travis.yml # 自动化CI配置 ├── vue.config.js # vue-cli 配置 ├── postcss.config.js # postcss 配置 └── package.json # package.json
- 项目的运行方法
# 安装依赖 npm install # 本地开发 启动项目 npm run dev
三、搭建注册页面
- 下载vue-admin-template模板后,我们在src/views目录下新建一个register目录,并添加index.vue,源代码如下:
<template> <div class="register-container"> <article class="header"> <header> <el-avatar icon="el-icon-user-solid" shape="circle" /> <span class="login"> <em class="bold">已有账号?</em> <a href="/login"> <el-button type="primary" size="mini">登录</el-button> </a> </span> </header> </article> <section> <el-form ref="ruleForm" :model="ruleForm" :rules="rules" label-width="100px" autocomplete="off" hide-required-asterisk="true" size="medium" > <div style="padding-top: 10px"> <el-form-item label="邮箱" prop="email"> <el-col :span="10"> <el-input v-model="ruleForm.email" placeholder="输入邮箱并点击发送验证码" /> </el-col> <el-button :loading="codeLoading" :disabled="isDisable" size="small" round @click="sendMsg" >发送验证码</el-button> <span class="status">{{ statusMsg }}</span> </el-form-item> <el-form-item label="验证码" prop="code"> <el-col :span="10"> <el-input v-model="ruleForm.code" maxlength="6" placeholder="请登录邮箱接收验证码" /> </el-col> </el-form-item> <el-form-item label="密码" prop="pwd"> <el-col :span="10"> <el-input v-model="ruleForm.pwd" type="password" /> </el-col> </el-form-item> <el-form-item label="确认密码" prop="cpwd"> <el-col :span="10"> <el-input v-model="ruleForm.cpwd" type="password" /> </el-col> </el-form-item> <el-form-item> <el-button type="primary" style="width: 40%" @click="register" >注册</el-button> </el-form-item> </div> </el-form> </section> <div class="error">{{ error }}</div> </div> </template> <script> import { getEmailCode, register } from '@/api/register' import { encrypt } from '@/utils/rsaEncrypt' export default { name: 'Register', data() { return { statusMsg: '', error: '', isDisable: false, codeLoading: false, ruleForm: { email: '', code: '', pwd: '', cpwd: '' }, rules: { email: [{ required: true, type: 'email', message: '请输入邮箱', trigger: 'blur' }], code: [{ required: true, type: 'string', message: '请输入验证码', trigger: 'blur' }], pwd: [{ required: true, message: '创建密码', trigger: 'blur' }, { pattern: /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,20}$/, message: '密码必须同时包含数字与字母,且长度为 8-20位' }], cpwd: [{ required: true, message: '确认密码', trigger: 'blur' }, { validator: (rule, value, callback) => { if (value === '') { callback(new Error('请再次输入密码')) } else if (value !== this.ruleForm.pwd) { callback(new Error('两次输入密码不一致')) } else { callback() } }, trigger: 'blur' }] } } }, methods: { sendMsg: function() { const self = this let emailPass let timerid if (timerid) { return false } self.statusMsg = '' this.$refs['ruleForm'].validateField('email', (valid) => { emailPass = valid }) // 向后台API验证码发送 if (!emailPass) { self.codeLoading = true self.statusMsg = '验证码发送中...' getEmailCode(self.ruleForm.email).then(res => { this.$message({ showClose: true, message: '发送成功,验证码有效期5分钟', type: 'success' }) let count = 60 self.ruleForm.code = '' self.codeLoading = false self.isDisable = true self.statusMsg = `验证码已发送,${count--}秒后重新发送` timerid = window.setInterval(function() { self.statusMsg = `验证码已发送,${count--}秒后重新发送` if (count <= 0) { window.clearInterval(timerid) self.isDisable = false self.statusMsg = '' } }, 1000) }).catch(err => { this.isDisable = false this.statusMsg = '' this.codeLoading = false console.log(err.response.data.message) }) } }, // 用户注册 register: function() { this.$refs['ruleForm'].validate((valid) => { if (valid) { const user = { email: this.ruleForm.email, code: this.ruleForm.code, password: encrypt(this.ruleForm.pwd) } register(this.ruleForm.code, user).then(res => { this.$message({ showClose: true, message: '注册成功,正在跳转到登录界面...', type: 'success' }) setTimeout(() => { this.$router.push('/') }, 2000) }).catch(err => { console.log(err.response.data.message) }) } }) } } } </script> <style lang="scss"> /* 修复input 背景不协调 和光标变色 */ /* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */ $bg: #283443; $light_gray: #fff; $cursor: #fff; @supports (-webkit-mask: none) and (not (cater-color: $cursor)) { .register-container .el-input input { color: $cursor; } } /* reset element-ui css */ .register-container { .el-input { display: inline-block; height: 47px; width: 95%; input { background: rgba(0, 0, 0, 0.1); border-radius: 5px; border: 1px solid rgba(255, 255, 255, 0.1); -webkit-appearance: none; padding: 12px 5px 12px 15px; color: $light_gray; height: 47px; caret-color: $cursor; &:-webkit-autofill { box-shadow: 0 0 0px 1000px $bg inset !important; -webkit-text-fill-color: $cursor !important; } } } .el-form-item { label { font-style: normal; font-size: 12px; color: $light_gray; } } } </style> <style lang="scss" scoped> $bg: #2d3a4b; $dark_gray: #889aa4; $light_gray: #eee; .register-container { min-height: 100%; width: 100%; background-color: $bg; overflow: hidden; .header { border-bottom: 2px solid rgb(235, 232, 232); min-width: 980px; color: #666; header { margin: 0 auto; padding: 10px 0; width: 980px; .login { float: right; } .bold { font-style: normal; color: $light_gray; } } } > section { margin: 0 auto 30px; padding-top: 30px; width: 980px; min-height: 300px; padding-right: 100px; box-sizing: border-box; .status { font-size: 12px; margin-left: 20px; color: #e6a23c; } .error { color: red; } } .tips { float: right; font-size: 14px; color: #fff; margin-bottom: 10px; span { &:first-of-type { margin-right: 16px; } } } } </style> <style scoped> /* 修改验证器样式 */ /deep/ .el-form-item.is-error .el-input__inner { border-color: #889aa4; } /deep/ .el-form-item.is-error .el-input__validateIcon { color: #889aa4; } /deep/ .el-form-item__error { color: #e6a23c; } </style>
- 页面呈现效果如下:
- 为了让注册页面可以访问api,我们在src/api目录下添加register.js,源代码如下:
import request from '@/utils/request' //在注册时根据邮箱名获取验证码 export function getEmailCode(email) { return request({ url: '/vue-admin-template/register/getEmailCode', method: 'post', email }) } //提交注册 export function register(code, data) { return request({ url: '/vue-admin-template/register?code=' + code, method: 'post', data }) }
- 同时,我们通过能过mockserver来模拟后台api的数据返回:在mock目录下添加register.js,源代码如下:
// mock api接口数据 module.exports = [ { url: '/vue-admin-template/register/getEmailCode', type: 'post', response: _ => { return { code: 20000, data: { message: 'success' } } } }, { url: '/vue-admin-template/register\.*', type: 'post', response: _ => { return { code: 20000, data: { message: 'success' } } } } ]
四、改造登录页面
- 接下来我们稍微对原来的登录页面做下调整:
- 增加新注册的链接
- 修正验证规则:以邮箱做为用户名登录,登录密码必须为8位,且为数字与字母混合,源代码如下:
<template> <div class="login-container"> <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" auto-complete="on" label-position="left"> <div class="title-container"> <h3 class="title">欢迎使用</h3> </div> <el-form-item prop="username"> <span class="svg-container"> <svg-icon icon-class="user" /> </span> <el-input ref="username" v-model="loginForm.username" placeholder="邮箱" name="username" type="text" tabindex="1" auto-complete="on" /> </el-form-item> <el-form-item prop="password"> <span class="svg-container"> <svg-icon icon-class="password" /> </span> <el-input :key="passwordType" ref="password" v-model="loginForm.password" :type="passwordType" placeholder="密码" name="password" tabindex="2" auto-complete="on" @keyup.enter.native="handleLogin" /> <span class="show-pwd" @click="showPwd"> <svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" /> </span> </el-form-item> <el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;" @click.native.prevent="handleLogin">登录</el-button> <p class="tips"> <a href="/register" type="primary">还没有帐号?立即注册</a> </p> </el-form> </div> </template> <script> export default { name: 'Login', data() { return { loginForm: { username: '', password: '' }, loginRules: { username: [{ type: 'email', required: true, trigger: 'blur', message: '请输入邮箱' }], password: [{ required: true, message: '创建密码', trigger: 'blur' }, { pattern: /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,20}$/, message: '密码必须同时包含数字与字母,且长度为 8-20位' }] }, loading: false, passwordType: 'password', redirect: undefined } }, watch: { $route: { handler: function(route) { this.redirect = route.query && route.query.redirect }, immediate: true } }, methods: { showPwd() { if (this.passwordType === 'password') { this.passwordType = '' } else { this.passwordType = 'password' } this.$nextTick(() => { this.$refs.password.focus() }) }, handleLogin() { this.$refs.loginForm.validate(valid => { if (valid) { this.loading = true this.$store.dispatch('user/login', this.loginForm).then(() => { this.$router.push({ path: this.redirect || '/' }) this.loading = false }).catch(() => { this.loading = false }) } else { console.log('error submit!!') return false } }) } } } </script> <style lang="scss"> /* 修复input 背景不协调 和光标变色 */ /* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */ $bg:#283443; $light_gray:#fff; $cursor: #fff; @supports (-webkit-mask: none) and (not (cater-color: $cursor)) { .login-container .el-input input { color: $cursor; } } /* reset element-ui css */ .login-container { .el-input { display: inline-block; height: 47px; width: 85%; input { background: transparent; border: 0px; -webkit-appearance: none; border-radius: 0px; padding: 12px 5px 12px 15px; color: $light_gray; height: 47px; caret-color: $cursor; &:-webkit-autofill { box-shadow: 0 0 0px 1000px $bg inset !important; -webkit-text-fill-color: $cursor !important; } } } .el-form-item { border: 1px solid rgba(255, 255, 255, 0.1); background: rgba(0, 0, 0, 0.1); border-radius: 5px; color: #454545; } } </style> <style lang="scss" scoped> $bg:#2d3a4b; $dark_gray:#889aa4; $light_gray:#eee; .login-container { min-height: 100%; width: 100%; background-color: $bg; overflow: hidden; .login-form { position: relative; width: 520px; max-width: 100%; padding: 160px 35px 0; margin: 0 auto; overflow: hidden; } .tips { float: right; font-size: 14px; color: #fff; margin-bottom: 10px; span { &:first-of-type { margin-right: 16px; } } } .svg-container { padding: 6px 5px 6px 15px; color: $dark_gray; vertical-align: middle; width: 30px; display: inline-block; } .title-container { position: relative; .title { font-size: 26px; color: $light_gray; margin: 0px auto 40px auto; text-align: center; font-weight: bold; } } .show-pwd { position: absolute; right: 10px; top: 7px; font-size: 16px; color: $dark_gray; cursor: pointer; user-select: none; } } </style> <style scoped> /* 修改验证器样式 */ /deep/ .el-form-item.is-error .el-input__inner { border-color: #889aa4; } /deep/ .el-form-item.is-error .el-input__validateIcon { color: #889aa4; } /deep/ .el-form-item__error { color: #e6a23c; } </style>
- 页面呈现效果如下:
四、整体效果动画演示
五、前端源码下载
- github
- gitee
六、后续
- 将会增加后台源码(JAVA),实现邮箱发送验证码,注册等功能,敬请期待。
这篇关于手把手教你使用Vue搭建注册登录界面及前端源码的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-09vue3开发前端表单缓存自定义指令,移动端h5必备插件
- 2024-05-09React Hooks在class组件中的使用方式
- 2024-03-30[OIDC in Action] 2. 基于OIDC(OpenID Connect)的SSO(纯JS客户端)
- 2024-03-29terraform jsonencode
- 2024-03-13vuex-persist
- 2024-03-11icons for vue
- 2024-03-07breadcrumbs react js
- 2024-03-06react login page example
- 2024-03-06react router uselocation
- 2024-03-04postgres jsonb_set