登陆注册页合并

master
toesbieya 6 years ago
parent 8fce04ae1b
commit 57419623c2
  1. 18
      vue/src/assets/styles/login.scss
  2. 5
      vue/src/router/constant/modules/app.js
  3. 4
      vue/src/store/modules/app.js
  4. 175
      vue/src/views/app/login.vue
  5. 123
      vue/src/views/app/login/LoginForm.vue
  6. 113
      vue/src/views/app/login/RegisterForm.vue
  7. 0
      vue/src/views/app/login/SetAnimation.vue
  8. 69
      vue/src/views/app/login/index.vue
  9. 154
      vue/src/views/app/register.vue

@ -95,5 +95,23 @@ $cursor: #fff;
background: rgba(0, 0, 0, 0.1);
margin-bottom: 22px;
}
.submit-btn {
width: 100%;
}
.other-ways {
color: #fff;
font-size: 14px;
svg {
cursor: pointer;
margin-left: 10px;
&:hover {
color: $--color-primary;
}
}
}
}
}

@ -14,12 +14,9 @@ const router = [
},
{
path: '/login',
alias: '/register',
component: () => import('@/views/app/login')
},
{
path: '/register',
component: () => import('@/views/app/register')
},
{
path: '/404',
component: () => import('@/views/app/404')

@ -8,9 +8,7 @@ const state = {
//区分pc和移动端(mobile)
device: isMobile() ? 'mobile' : 'pc',
//登陆页背景动画
loginPageBackgroundAnimation: 'firework',
//注册页背景动画
registerPageBackgroundAnimation: 'firework',
loginBackgroundAnimation: 'firework',
//路由页面滚动高度
scrollTop: 0,
//右侧块是否含有头部

@ -1,175 +0,0 @@
<template>
<div class="login-page">
<canvas id="login-background"/>
<div class="login-container" @click.stop>
<div class="title">
进销存管理系统
<set-animation
:value="loginPageBackgroundAnimation"
custom-class="set-animation"
@select="setAnimation"
/>
</div>
<el-form ref="form" :model="form" :rules="rules" autocomplete="on" label-position="left">
<el-form-item prop="username">
<span class="svg-container">
<svg-icon icon="user"/>
</span>
<el-input
ref="username"
v-model="form.username"
:maxlength="20"
name="username"
placeholder="请输入用户名"
type="text"
/>
</el-form-item>
<el-form-item prop="password">
<el-tooltip v-model="capsTooltip" :tabindex="-1" content="大写锁定已打开" manual placement="left">
<span class="svg-container">
<svg-icon icon="password"/>
</span>
</el-tooltip>
<el-input
ref="password"
v-model="form.password"
:key="passwordType"
:type="passwordType"
:maxlength="20"
name="password"
placeholder="请输入密码"
@keyup.enter.native="login"
/>
<span @click="showPwd" class="show-pwd">
<svg-icon :icon="passwordType === 'password' ? 'eye' : 'eye-open'"/>
</span>
</el-form-item>
<el-button :loading="loading" style="width: 100%" type="primary" @click="login"> </el-button>
<div class="flex" style="margin-top: 20px">
<p class="other-ways">
其他方式登录
<span v-for="i in otherWays" :key="i" @click="$message.info('假装可以第三方登录')">
<svg-icon :icon="i"/>
</span>
</p>
<el-button type="text" @click="!loading&&$router.push('/register')">注册账户</el-button>
</div>
</el-form>
</div>
</div>
</template>
<script>
import {mapState} from 'vuex'
import md5 from "js-md5"
import {isEmpty} from "@/utils"
import {elSuccess} from "@/utils/message"
import SetAnimation from "./components/SetAnimation"
export default {
name: 'login',
components: {SetAnimation},
data() {
return {
form: {
username: '',
password: ''
},
rules: {
username: [{required: true, message: '请输入用户名', trigger: 'change'}],
password: [
{required: true, message: '请输入密码', trigger: 'change'},
{min: 6, max: 32, message: '请输入6-32位的密码', trigger: 'change'}
]
},
passwordType: 'password',
capsTooltip: false,
otherWays: ['qq'],
loading: false,
animation: null
}
},
computed: mapState('app', {
device: state => state.device,
loginPageBackgroundAnimation: state => state.loginPageBackgroundAnimation
}),
methods: {
showPwd() {
this.passwordType = this.passwordType === 'password' ? '' : 'password'
this.$nextTick(() => this.$refs.password.focus())
},
login() {
if (this.loading) return
this.$refs.form.validate(valid => {
if (!valid) return
this.loading = true
this.$puzzleVerify()
.then(() => this.$store.dispatch('user/login', {
...this.form,
password: md5(this.form.password)
}))
.then(() => this.success())
.catch(() => this.loading = false)
})
},
success() {
elSuccess('登陆成功')
const redirect = this.$route.query.redirect || '/'
//0.2s
setTimeout(() => this.$router.push(redirect), 200)
},
capsLockTip({keyCode}) {
if (keyCode === 20) this.capsTooltip = !this.capsTooltip
},
addCapsLockEvent() {
document.addEventListener('keyup', this.capsLockTip)
},
removeEvent() {
document.removeEventListener('keyup', this.addCapsLockEvent)
},
clearAnimation() {
if (this.animation) {
this.animation.stop()
this.animation = null
}
},
setAnimation(value) {
this.clearAnimation()
this.$store.commit('app/loginPageBackgroundAnimation', value)
if (isEmpty(value)) return
import(`@/plugin/canvasAnimation/${value}`)
.then(_ => this.animation = new _.default(document.getElementById('login-background')))
}
},
mounted() {
//
this.device !== 'mobile' && this.setAnimation(this.loginPageBackgroundAnimation)
this.addCapsLockEvent()
if (isEmpty(this.form.username)) this.$refs.username.focus()
else this.$refs.password.focus()
},
beforeDestroy() {
this.$message.closeAll()
this.removeEvent()
this.clearAnimation()
}
}
</script>
<style lang="scss">
@import "src/assets/styles/login";
.other-ways {
color: #fff;
font-size: 14px;
span {
cursor: pointer;
margin-left: 10px;
&:hover {
color: $--color-primary;
}
}
}
</style>

@ -0,0 +1,123 @@
<template>
<el-form ref="form" :model="form" :rules="rules" label-position="left">
<el-form-item prop="username">
<span class="svg-container">
<svg-icon icon="user"/>
</span>
<el-input
ref="username"
v-model="form.username"
:maxlength="20"
name="username"
placeholder="请输入用户名"
type="text"
/>
</el-form-item>
<el-form-item prop="password">
<el-tooltip v-model="capsTooltip" :tabindex="-1" content="大写锁定已打开" manual placement="left">
<span class="svg-container">
<svg-icon icon="password"/>
</span>
</el-tooltip>
<el-input
ref="password"
v-model="form.password"
:key="passwordType"
:type="passwordType"
:maxlength="20"
name="password"
placeholder="请输入密码"
@keyup.enter.native="login"
/>
<span @click="showPwd" class="show-pwd">
<svg-icon :icon="passwordType === 'password' ? 'eye' : 'eye-open'"/>
</span>
</el-form-item>
<el-button :loading="loading" class="submit-btn" type="primary" @click="login"> </el-button>
<div class="flex" style="margin-top: 20px">
<p class="other-ways">
其他方式登录
<svg-icon v-for="i in otherWays" :key="i" :icon="i" @click="thirdPartyLogin(i)"/>
</p>
<el-button type="text" @click="register">注册账户</el-button>
</div>
</el-form>
</template>
<script>
import md5 from "js-md5"
import {elSuccess} from "@/utils/message"
import {isEmpty} from "@/utils"
export default {
name: "LoginForm",
data() {
return {
loading: false,
form: {
username: '',
password: ''
},
rules: {
username: [{required: true, message: '请输入用户名', trigger: 'change'}],
password: [
{required: true, message: '请输入密码', trigger: 'change'},
{min: 6, max: 32, message: '请输入6-32位的密码', trigger: 'change'}
]
},
passwordType: 'password',
capsTooltip: false,
otherWays: ['qq']
}
},
methods: {
showPwd() {
this.passwordType = this.passwordType === 'password' ? '' : 'password'
this.$nextTick(() => this.$refs.password.focus())
},
login() {
if (this.loading) return
this.$refs.form.validate(valid => {
if (!valid) return
this.loading = true
this.$puzzleVerify()
.then(() => this.$store.dispatch('user/login', {
...this.form,
password: md5(this.form.password)
}))
.then(() => this.success())
.catch(() => this.loading = false)
})
},
register() {
!this.loading && this.$router.push('/register')
},
success() {
elSuccess('登陆成功')
const redirect = this.$route.query.redirect || '/'
//0.2s
setTimeout(() => this.$router.push(redirect), 200)
},
thirdPartyLogin(channel) {
this.$message.info('假装可以第三方登录')
},
capsLockTip({keyCode}) {
if (keyCode === 20) this.capsTooltip = !this.capsTooltip
},
addCapsLockEvent() {
document.addEventListener('keyup', this.capsLockTip)
},
removeEvent() {
document.removeEventListener('keyup', this.addCapsLockEvent)
}
},
mounted() {
this.addCapsLockEvent()
if (isEmpty(this.form.username)) this.$refs.username.focus()
else this.$refs.password.focus()
},
beforeDestroy() {
this.removeEvent()
}
}
</script>

@ -0,0 +1,113 @@
<template>
<el-form ref="form" :model="form" :rules="rules" label-position="left">
<el-form-item prop="username">
<span class="svg-container">
<svg-icon icon="user"/>
</span>
<el-input ref="username" v-model="form.username" :maxlength="20" placeholder="请输入用户名"/>
</el-form-item>
<el-form-item prop="pwd">
<el-tooltip v-model="capsTooltip" :tabindex="-1" content="大写锁定已打开" manual placement="left">
<span class="svg-container">
<svg-icon icon="password"/>
</span>
</el-tooltip>
<el-input v-model="form.pwd" placeholder="请输入密码" type="password" :maxlength="20"/>
</el-form-item>
<el-form-item prop="repwd">
<span class="svg-container">
<svg-icon icon="password"/>
</span>
<el-input
v-model="form.repwd"
placeholder="请确认密码"
type="password"
:maxlength="20"
@keyup.enter.native="register"
/>
</el-form-item>
<el-button :loading="loading" class="submit-btn" type="primary" @click="register"> </el-button>
<div class="flex" style="margin-top: 20px">
<p/>
<el-button type="text" @click="login">已有账户登陆</el-button>
</div>
</el-form>
</template>
<script>
import md5 from "js-md5"
import {checkName} from "@/api/system/user"
import {register} from "@/api/account"
import {elSuccess} from "@/utils/message"
export default {
name: "RegisterForm",
data() {
const validateName = (r, v, c) => {
checkName(this.form.username)
.then(({msg}) => msg ? c(msg) : c())
.catch(e => c(e))
}
const validateRepwd = (r, v, c) => {
return v !== this.form.pwd ? c('两次密码输入不一致') : c()
}
return {
form: {
username: '',
pwd: '',
repwd: ''
},
rules: {
username: [
{required: true, message: '请输入用户名', trigger: 'change'},
{validator: validateName, trigger: 'change'}
],
pwd: [
{required: true, message: '请输入密码', trigger: 'change'},
{min: 6, max: 32, message: '请输入6-32位的密码', trigger: 'change'}
],
repwd: [
{required: true, message: '请确认密码', trigger: 'change'},
{validator: validateRepwd, trigger: 'change'}
],
},
capsTooltip: false,
loading: false
}
},
methods: {
register() {
if (this.loading) return
this.$refs.form.validate(valid => {
if (!valid) return
this.loading = true
register({username: this.form.username, password: md5(this.form.pwd)})
.then(() => {
elSuccess('注册成功')
this.$router.push('/login')
})
.catch(() => this.loading = false)
})
},
login() {
!this.loading && this.$router.push('/login')
},
capsLockTip({keyCode}) {
if (keyCode === 20) this.capsTooltip = !this.capsTooltip
},
addEvent() {
document.addEventListener('keyup', this.capsLockTip)
},
removeEvent() {
document.removeEventListener('keyup', this.addCapsLockEvent)
}
},
mounted() {
this.addEvent()
this.$nextTick(() => this.$refs.username.focus())
},
beforeDestroy() {
this.removeEvent()
}
}
</script>

@ -0,0 +1,69 @@
<template>
<div class="login-page">
<canvas id="login-background"/>
<div class="login-container" @click.stop>
<div class="title">
{{title}}
<set-animation :value="animation" custom-class="set-animation" @select="setAnimation"/>
</div>
<component :is="component"/>
</div>
</div>
</template>
<script>
import {mapState} from 'vuex'
import {title} from '@/config'
import SetAnimation from "./SetAnimation"
import LoginForm from "./LoginForm"
import RegisterForm from "./RegisterForm"
import {isEmpty} from "@/utils"
export default {
name: 'login',
components: {LoginForm, RegisterForm, SetAnimation},
data() {
return {
title,
animationInstance: null
}
},
computed: {
...mapState('app', {
device: state => state.device,
animation: state => state.loginBackgroundAnimation
}),
component() {
const {path} = this.$route
return `${path.substring(1)}-form`
}
},
methods: {
clearAnimation() {
if (this.animationInstance) {
this.animationInstance.stop()
this.animationInstance = null
}
},
setAnimation(value) {
this.clearAnimation()
this.$store.commit('app/loginBackgroundAnimation', value)
if (isEmpty(value)) return
import(`@/plugin/canvasAnimation/${value}`)
.then(_ => this.animationInstance = new _.default(document.getElementById('login-background')))
}
},
mounted() {
//
this.device !== 'mobile' && this.setAnimation(this.loginBackgroundAnimation)
},
beforeDestroy() {
this.clearAnimation()
this.$message.closeAll()
}
}
</script>
<style lang="scss">
@import "src/assets/styles/login";
</style>

@ -1,154 +0,0 @@
<template>
<div class="login-page">
<canvas id="login-background"/>
<div class="login-container" @click.stop>
<div class="title">
用户注册
<set-animation
:value="registerPageBackgroundAnimation"
custom-class="set-animation"
@select="setAnimation"
/>
</div>
<el-form ref="form" :model="form" :rules="rules" label-position="left">
<el-form-item prop="username">
<span class="svg-container">
<svg-icon icon="user"/>
</span>
<el-input ref="username" v-model="form.username" :maxlength="20" placeholder="请输入用户名"/>
</el-form-item>
<el-form-item prop="pwd">
<el-tooltip v-model="capsTooltip" :tabindex="-1" content="大写锁定已打开" manual placement="left">
<span class="svg-container">
<svg-icon icon="password"/>
</span>
</el-tooltip>
<el-input v-model="form.pwd" placeholder="请输入密码" type="password" :maxlength="20"/>
</el-form-item>
<el-form-item prop="repwd">
<span class="svg-container">
<svg-icon icon="password"/>
</span>
<el-input
v-model="form.repwd"
placeholder="请确认密码"
type="password"
:maxlength="20"
@keyup.enter.native="register"
/>
</el-form-item>
<el-button :loading="loading" style="width: 100%" type="primary" @click="register"> </el-button>
<div class="flex" style="margin-top: 20px">
<p/>
<el-button type="text" @click="!loading&&$router.push('/login')">已有账户登陆</el-button>
</div>
</el-form>
</div>
</div>
</template>
<script>
import {mapState} from 'vuex'
import md5 from "js-md5"
import {register} from "@/api/account"
import {checkName} from "@/api/system/user"
import {elSuccess} from "@/utils/message"
import {isEmpty} from "@/utils"
import SetAnimation from "./components/SetAnimation"
export default {
name: "register",
components: {SetAnimation},
data() {
const validateName = (r, v, c) => {
checkName(this.form.username)
.then(({msg}) => msg ? c(msg) : c())
.catch(e => c(e))
}
const validateRepwd = (r, v, c) => {
return v !== this.form.pwd ? c('两次密码输入不一致') : c()
}
return {
form: {
username: '',
pwd: '',
repwd: ''
},
rules: {
username: [
{required: true, message: '请输入用户名', trigger: 'change'},
{validator: validateName, trigger: 'change'}
],
pwd: [
{required: true, message: '请输入密码', trigger: 'change'},
{min: 6, max: 32, message: '请输入6-32位的密码', trigger: 'change'}
],
repwd: [
{required: true, message: '请确认密码', trigger: 'change'},
{validator: validateRepwd, trigger: 'change'}
],
},
capsTooltip: false,
loading: false,
animation: null
}
},
computed: mapState('app', {
device: state => state.device,
registerPageBackgroundAnimation: state => state.registerPageBackgroundAnimation
}),
methods: {
register() {
if (this.loading) return
this.$refs.form.validate(valid => {
if (!valid) return
this.loading = true
register({username: this.form.username, password: md5(this.form.pwd)})
.then(() => {
elSuccess('注册成功')
this.$router.push('/login')
})
.catch(() => this.loading = false)
})
},
capsLockTip({keyCode}) {
if (keyCode === 20) this.capsTooltip = !this.capsTooltip
},
addEvent() {
document.addEventListener('keyup', this.capsLockTip)
},
removeEvent() {
document.removeEventListener('keyup', this.addCapsLockEvent)
},
clearAnimation() {
if (this.animation) {
this.animation.stop()
this.animation = null
}
},
setAnimation(value) {
this.clearAnimation()
this.$store.commit('app/registerPageBackgroundAnimation', value)
if (isEmpty(value)) return
import(`@/plugin/canvasAnimation/${value}`)
.then(_ => this.animation = new _.default(document.getElementById('login-background')))
}
},
mounted() {
//
this.device !== 'mobile' && this.setAnimation(this.registerPageBackgroundAnimation)
this.addEvent()
this.$nextTick(() => this.$refs.username.focus())
},
beforeDestroy() {
this.$message.closeAll()
this.removeEvent()
this.clearAnimation()
}
}
</script>
<style lang="scss">
@import "~@/assets/styles/login";
</style>
Loading…
Cancel
Save