《VUE+Django:手把手教你打造自己的电商独立站》2.7.2 VUE实现用户注册/登录页面

228 阅读1分钟

专栏大纲《VUE+Django:手把手教你打造自己的电商独立站》专栏写作大纲

上一篇《VUE+Django:手把手教你打造自己的电商独立站》VUE项目结构和页面框架实现

用户注册和登录页面是电商网站的重要部分,便于获取用户的关键信息,为后续的用户管理打好基础。

在src/page目录下创建RegisPage.vue文件,在其中加入以下代码。使用了el-tabs控件展示不同注册方式的页签,每个页签内部使用el-form供用户输入注册信息。使用了v-show显示一些错误提示,这里的regisCode来自于服务端的响应数据

<template> <div class="register-container"> <div v-if="regisFlagByEmailTmp || regisFlagByPhoneTmp" class="register-box"> <el-button type="success" icon="el-icon-check" circle></el-button> 注册成功,请点击<router-link :to="LoginPage">这里</router-link>登录 </div> <div v-else class="register-box"> <el-form :inline="true" ref="registerForm" :model="registerForm" :rules="registerRules" class="register-form" size="small" label-position="left" label-width="100px"> <el-tabs v-model="activeTab" class="register-tabs"> <el-tab-pane label="邮箱注册" name="email"> <el-form-item label="邮箱" prop="email"> <el-input v-model="registerForm.email" placeholder="请输入邮箱"></el-input> <span v-show="regisCode===9997" style="color: red">邮箱已注册</span> </el-form-item> <el-form-item label=" "> <el-button type="primary" size="mini" style=" margin: 0 auto; display: block;" @click="getCode(activeTab)" :disabled="countdown > 0"> {{ countdown > 0 ? countdown + '秒后重试' : '获取验证码' }} </el-button> </el-form-item> <el-form-item label="验证码" prop="emailCode"> <el-input v-model="registerForm.emailCode"></el-input> <span v-show="regisCode===9999" style="color: red">验证码不正确</span> <span v-show="regisCode===9995" style="color: red">未获取验证码</span> </el-form-item> <el-form-item label="密码" prop="passwordEmail"> <el-input type="password" v-model="registerForm.passwordEmail"></el-input> </el-form-item> <el-form-item label="确认密码" prop="checkPasswordEmail"> <el-input type="password" v-model="registerForm.checkPasswordEmail"></el-input> </el-form-item> </el-tab-pane> <el-tab-pane label="手机号注册" name="phone"> <el-form-item label="手机号" prop="phone"> <el-input v-model="registerForm.phone" placeholder="请输入手机号"></el-input> <span v-show="regisCode===9997" style="color: red">手机号已注册</span> </el-form-item> <el-form-item label=" "> <el-button type="primary" size="mini" style=" margin: 0 auto; display: block;" @click="getCode(activeTab)" :disabled="countdown > 0"> {{ countdown > 0 ? countdown + '秒后重试' : '获取验证码' }} </el-button> </el-form-item> <el-form-item label="验证码" prop="phoneCode"> <el-input v-model="registerForm.phoneCode"></el-input> <span v-show="regisCode===9999" style="color: red">验证码不正确</span> <span v-show="regisCode===9995" style="color: red">未获取验证码</span> </el-form-item> <el-form-item label="密码" prop="passwordPhone"> <el-input type="password" v-model="registerForm.passwordPhone"></el-input> </el-form-item> <el-form-item label="确认密码" prop="checkPasswordPhone"> <el-input type="password" v-model="registerForm.checkPasswordPhone"></el-input> </el-form-item> </el-tab-pane> </el-tabs> <el-form-item label=" " size="medium" style="margin-top: 5px"> <el-button type="primary" style="width: 290%" @click="submitForm(activeTab)">注册</el-button> </el-form-item> <div class="login-link"> <router-link :to="LoginPage">已有账号?去登录</router-link> </div> </el-form> </div> </div> </template> <script> import LoginPage from "@/page/LoginPage.vue"; export default { name: 'RegisPage', computed: { LoginPage() { return LoginPage }, regisFlagByEmailTmp:{ get(){ if(this.$route.query.regisFlagByEmail){ return this.$route.query.regisFlagByEmail } return this.regisFlagByEmail }, set(v){ this.regisFlagByEmail=v } }, regisFlagByPhoneTmp:{ get(){ if(this.$route.query.regisFlagByPhone){ return this.$route.query.regisFlagByPhone }else { return this.regisFlagByPhone } }, set(v){ this.regisFlagByPhone= v } }, }, data() { return { activeTab: 'email', // 添加activeTab属性并赋值为'email' countdown:0, regisCode:'', regisFlagByEmail:false, regisFlagByPhone:false, registerForm: { email: '', emailCode: '', passwordEmail: '', checkPasswordEmail: '', phone: '', phoneCode: '', passwordPhone: '', checkPasswordPhone: '' }, registerRules: { email: [ {required: true, message: '请输入邮箱', trigger: 'blur'}, {type: 'email', message: '请输入正确的邮箱地址', trigger: ['blur', 'change']} ], emailCode: [ {required: true, message: '请输入验证码', trigger: 'blur'} ], phone: [ {required: true, message: '请输入手机号', trigger: 'blur'}, {pattern: /^1\d{10}$/, message: '请输入正确的手机号', trigger: ['blur', 'change']} ], phoneCode: [ {required: true, message: '请输入验证码', trigger: 'blur'} ], passwordEmail: [ {required: true, message: '请输入密码', trigger: 'blur'}, {min: 6, message: '密码长度不能少于6位', trigger: 'blur'} ], checkPasswordEmail: [ {required: true, message: '请再次输入密码', trigger: 'blur'}, {validator: this.checkPassword, trigger: 'blur'} ], passwordPhone: [ {required: true, message: '请输入密码', trigger: 'blur'}, {min: 6, message: '密码长度不能少于6位', trigger: 'blur'} ], checkPasswordPhone: [ {required: true, message: '请再次输入密码', trigger: 'blur'}, {validator: this.checkPassword, trigger: 'blur'} ], } } }, methods: { checkPassword(rule, value, regisMode,callback) { let secondPassword=null if(regisMode==='email'){ secondPassword=this.registerForm.checkPasswordEmail }else if(regisMode==='phone'){ secondPassword=this.registerForm.checkPasswordPhone } if (value !== secondPassword) { callback(new Error('两次输入密码不一致')) } else { callback() } }, async submitForm(regisMode) { const pubKey = await getPubKey() if (regisMode === 'email') { //ToDo } else if (regisMode === 'phone') { //ToDo } }, } } </script> <style scoped> .register-container { display: flex; justify-content: right; align-items: center; height: 60vh; background-color: #f5f5f5; background-image: url(@/assets/background.jpg); } .register-box { width: 400px; height: 80%; padding: 20px; background-color: #fff; border-radius: 5px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); margin-right: 20%; } .login-link { margin-top: 10px; text-align: right; } </style>​

在src/page目录下创建LoginPage.vue文件,在其中加入以下代码。使用了el-tabs控件展示不同登录方式的页签,每个页签内部使用el-form供用户输入登录信息。​

<template> <div class="login-container"> <div class="login-box"> <el-tabs v-model="activeTab"> <el-tab-pane label="账号登录" name="username"> <el-form ref="form" :model="loginForm" label-width="80px" label-position="left" :rules="loginRules"> <el-form-item label="用户名" > <el-input v-model="loginForm.account" placeholder="用户名或邮箱"></el-input> <span v-show="loginCode===9999" style="color: red">用户名或邮箱未注册</span> </el-form-item> <el-form-item label="密码"> <el-input type="password" v-model="loginForm.password" placeholder="密码"></el-input> <span v-show="loginCode===9996" style="color: red">密码不正确</span> </el-form-item> <el-form-item label="" > <router-link :to="ResetPassword">忘记密码</router-link> </el-form-item> <el-form-item> <el-button type="primary" style="width: 100%" @click="submitForm('username')" >登录</el-button> </el-form-item> </el-form> </el-tab-pane> <el-tab-pane label="手机登录" name="phone"> <el-form ref="form" :model="loginForm" label-width="80px" label-position="left"> <el-form-item label="手机号"> <el-input v-model="loginForm.phone" placeholder="手机号"></el-input> </el-form-item> <el-form-item label="验证码"> <el-input v-model="loginForm.phoneCode" placeholder="验证码"></el-input> <el-button type="primary" @click="getCode" :disabled="countdown > 0" size="mini"> {{ countdown > 0 ? countdown + '秒后重试' : '获取验证码' }} </el-button> </el-form-item> <el-form-item > <el-button type="primary" style="width: 100%" @click="submitForm('phone')">登录</el-button> </el-form-item> </el-form> </el-tab-pane> <el-tab-pane label="扫码登录" name="qrcode"> <div class="qrcode-container"> <img :src="qrcode" alt="二维码"> <p>请使用微信扫描二维码登录</p> </div> </el-tab-pane> </el-tabs> <div class="register-link"> <router-link :to="RegisPage">没有账号?去注册</router-link> </div> </div> </div> </template> <script> import RegisPage from "@/page/RegisPage.vue"; import ResetPassword from "@/page/ResetPassword.vue"; import {getPubKey} from "@/plugins/axiosPlugin/interface"; import {encryptRSA} from "@/utils/rsa"; export default { name:'LoginPage', computed: { RegisPage() { return RegisPage }, ResetPassword() { return ResetPassword }, loading(){ return this.$store.getters.loading } }, data() { return { activeTab:'username', qrcode:require('../assets/qrcode.png'), countdown:0, loginCode:'', loginForm:{ account:'', password:'', phone:'', phoneCode:'', }, loginRules: { account: [ {required: true, message: '请输入邮箱', trigger: 'blur'}, ], phone: [ {required: true, message: '请输入手机号', trigger: 'blur'}, {pattern: /^1\d{10}$/, message: '请输入正确的手机号', trigger: ['blur', 'change']} ], phoneCode: [ {required: true, message: '请输入验证码', trigger: 'blur'} ], password: [ {required: true, message: '请输入密码', trigger: 'blur'}, {min: 6, message: '密码长度不能少于6位', trigger: 'blur'} ], } }; }, methods: { async submitForm(loginMode) { this.loginCode='' const pubKey=await getPubKey() if(loginMode==='username'){ if(pubKey){ //ToDo } }else if(loginMode==='phone'){ if(pubKey) { //ToDo } } }, async getCode() { const pubKey=await getPubKey() if(pubKey) { const phone = encryptRSA(this.loginForm.phone, JSON.parse(pubKey).pubkey) const codeResp = await this.$store.dispatch('getCode', {'phone': phone}) this.countdown = 60; const timer = setInterval(() => { if (this.countdown > 0) { this.countdown--; } else { clearInterval(timer); } }, 1000); } }, }, created() { console.log('登录页面加载完成'); }, mounted() { console.log('登录页面挂载完成'); }, updated() { console.log('登录页面更新完成'); }, deactivated() { console.log('登录页面停用'); }, activated() { console.log('登录页面激活'); }, beforeDestroy() { console.log('登录页面销毁前'); }, destroyed() { console.log('登录页面已销毁'); } } </script> <style scoped> .login-container { display: flex; justify-content: right; align-items: center; height: 50vh; background-color: #f5f5f5; background-image: url(@/assets/background.jpg); } .login-box { width: 400px; padding: 20px; background-color: #fff; border-radius: 5px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); margin-right: 20%; } .register-link { margin-top: 20px; text-align: right; } .qrcode-container { display: flex; flex-direction: column; justify-content: center; align-items: center; height: 200px; } .qrcode-container img { width: 100px; height: 100px; margin-bottom: 10px; } </style>

展示效果如下

image.png

image.png