登录页面
This commit is contained in:
parent
c0881225ea
commit
2bcd996d58
@ -72,6 +72,7 @@ export default {
|
||||
'/login',
|
||||
'/login/other',
|
||||
'/login/password',
|
||||
'/login/verification-code',
|
||||
|
||||
|
||||
'/service-protocol',
|
||||
|
||||
BIN
src/assets/img/icon/components/back-gray.png
Normal file
BIN
src/assets/img/icon/components/back-gray.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.8 KiB |
BIN
src/assets/img/icon/components/back-white.png
Normal file
BIN
src/assets/img/icon/components/back-white.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.6 KiB |
BIN
src/assets/img/icon/components/close-black.png
Normal file
BIN
src/assets/img/icon/components/close-black.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.4 KiB |
BIN
src/assets/img/icon/loading-white.png
Normal file
BIN
src/assets/img/icon/loading-white.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.7 KiB |
BIN
src/assets/img/icon/login/close-full-gray.png
Normal file
BIN
src/assets/img/icon/login/close-full-gray.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.3 KiB |
@ -9,21 +9,32 @@ export default {
|
||||
type: String,
|
||||
default: 'gray',//white
|
||||
},
|
||||
isClose: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
direction: {
|
||||
type: String,
|
||||
default: 'left',
|
||||
},
|
||||
scale: {
|
||||
type: [Number,String],
|
||||
type: [Number, String],
|
||||
default: 1,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
src: require(`../assets/img/icon/back-${this.mode}.png`)
|
||||
// src: require(`../assets/img/icon/components/back-${this.mode}.png`)
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
src() {
|
||||
if (this.isClose) {
|
||||
return require(`../assets/img/icon/components/close-${this.mode}.png`)
|
||||
}
|
||||
return require(`../assets/img/icon/components/back-${this.mode}.png`)
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
mounted() {
|
||||
this.$setCss(this.$refs.img, 'transform', `rotate(${this.direction === 'left' ? '0' : '180'}deg) scale(${this.scale})`)
|
||||
},
|
||||
|
||||
138
src/components/BaseButton.vue
Normal file
138
src/components/BaseButton.vue
Normal file
@ -0,0 +1,138 @@
|
||||
<template>
|
||||
<div class="button" :class="class1" @click.capture.stop="check">
|
||||
<img v-if="loading" src="../assets/img/icon/loading-white.png" alt="">
|
||||
<slot v-if="showText"></slot>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "BaseButton",
|
||||
props: {
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
loadingWithText: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'primary'
|
||||
},
|
||||
active: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
computed: {
|
||||
class1() {
|
||||
return [this.type, this.active ? '' : 'no-active', this.disabled && 'disabled']
|
||||
},
|
||||
showText() {
|
||||
if (this.loading) {
|
||||
return this.loadingWithText
|
||||
}
|
||||
return true
|
||||
}
|
||||
},
|
||||
created() {
|
||||
},
|
||||
methods: {
|
||||
check() {
|
||||
if (this.disabled) return
|
||||
if (this.loading) return
|
||||
return this.$emit('click')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "../assets/scss/index";
|
||||
|
||||
.button {
|
||||
color: white;
|
||||
height: 4rem;
|
||||
line-height: 4rem;
|
||||
border-radius: .3rem;
|
||||
//width: 100%;
|
||||
font-size: 1.4rem;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
height: 1.6rem;
|
||||
margin-right: .5rem;
|
||||
animation: animal .8s infinite linear;
|
||||
|
||||
@keyframes animal {
|
||||
0% {
|
||||
transform: rotate(-360deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.primary {
|
||||
background: $primary-btn-color;
|
||||
|
||||
&:active {
|
||||
background: $disable-primary-btn-color;
|
||||
}
|
||||
}
|
||||
|
||||
&.no-active {
|
||||
&:active {
|
||||
&.primary {
|
||||
background: $primary-btn-color;
|
||||
}
|
||||
|
||||
&.dark {
|
||||
background: $second-btn-color;
|
||||
}
|
||||
|
||||
&.white {
|
||||
background: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
&.primary {
|
||||
background: gainsboro;
|
||||
color: white;
|
||||
}
|
||||
|
||||
&:active {
|
||||
&.primary {
|
||||
background: gainsboro;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.dark {
|
||||
background: $second-btn-color;
|
||||
|
||||
&:active {
|
||||
background: $second-btn-color-tran;
|
||||
}
|
||||
}
|
||||
|
||||
&.white {
|
||||
background: white;
|
||||
color: black;
|
||||
border: 1px solid gainsboro;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -1,7 +1,10 @@
|
||||
<template>
|
||||
<div id='BaseHeader'>
|
||||
<div id='BaseHeader' :class="mode">
|
||||
<div class="header">
|
||||
<back @click="back()" mode="white" class="left" scale="1.8" direction="left"></back>
|
||||
<back :isClose="isClose" :mode="isClose?'black':'gray'"
|
||||
@click="back()"
|
||||
class="left"
|
||||
direction="left"/>
|
||||
<slot name="center"><span></span></slot>
|
||||
<slot name="right"><span></span></slot>
|
||||
</div>
|
||||
@ -12,7 +15,16 @@
|
||||
export default {
|
||||
name: "BaseHeader",
|
||||
components: {},
|
||||
props: {},
|
||||
props: {
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'dark',//light
|
||||
},
|
||||
isClose: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
@ -37,9 +49,18 @@ export default {
|
||||
#BaseHeader {
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
background: $main-bg;
|
||||
z-index: 2;
|
||||
|
||||
&.light {
|
||||
background: white;
|
||||
color: black;
|
||||
}
|
||||
|
||||
&.dark {
|
||||
background: $main-bg;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
@ -47,7 +68,6 @@ export default {
|
||||
height: 6rem;
|
||||
border-bottom: 1px solid #cccccc11;
|
||||
position: relative;
|
||||
color: white;
|
||||
|
||||
.left {
|
||||
position: absolute;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="ConfirmDialog " @click="$emit('dismiss')">
|
||||
<div class="SimpleConfirmDialog " @click="$emit('dismiss')">
|
||||
<div class="content" @click.stop="null">
|
||||
<div class="item">{{ title }}</div>
|
||||
<div class="footer">
|
||||
@ -11,7 +11,7 @@
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "ConfirmDialog",
|
||||
name: "SimpleConfirmDialog",
|
||||
props: {
|
||||
visible: {
|
||||
type: Boolean,
|
||||
@ -32,7 +32,7 @@ export default {
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
.ConfirmDialog {
|
||||
.SimpleConfirmDialog {
|
||||
z-index: 10;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
|
||||
@ -1,19 +1,21 @@
|
||||
<template>
|
||||
<div class="login">
|
||||
<BaseHeader>
|
||||
<BaseHeader mode="light" :isClose="true">
|
||||
<template v-slot:right>
|
||||
<span class="f16">帮助</span>
|
||||
</template>
|
||||
</BaseHeader>
|
||||
<div class="content">
|
||||
<div class="notice">
|
||||
<div class="desc">
|
||||
<div class="title">登录看朋友内容</div>
|
||||
<div class="phone-number">138****8000</div>
|
||||
<div class="sub-title">认证服务由中国移动提供</div>
|
||||
</div>
|
||||
|
||||
<div class="button primary no-active" @click="login">一键登录</div>
|
||||
<div class="button white" @click="$nav('/login/other')">其他手机号码登录</div>
|
||||
<b-button :loading="loading" :active="false" :loadingWithText="true" @click="login">
|
||||
{{ loading ? '登录中' : '一键登录' }}
|
||||
</b-button>
|
||||
<b-button :active="false" type="white" @click="$nav('/login/other')">其他手机号码登录</b-button>
|
||||
|
||||
<div class="protocol" :class="showAnim?'anim-bounce':''">
|
||||
<Tooltip style="top: -100%;left: -1rem;" v-model="showTooltip"/>
|
||||
@ -65,6 +67,7 @@ export default {
|
||||
isOtherLogin: false,
|
||||
showAnim: false,
|
||||
showTooltip: false,
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
@ -72,15 +75,19 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
login() {
|
||||
if (!this.isAgree && !this.showAnim && !this.showTooltip) {
|
||||
this.showAnim = true
|
||||
setTimeout(() => {
|
||||
this.showAnim = false
|
||||
this.showTooltip = true
|
||||
}, 500)
|
||||
setTimeout(() => {
|
||||
this.showTooltip = false
|
||||
}, 3000)
|
||||
if (this.isAgree) {
|
||||
this.loading = true
|
||||
} else {
|
||||
if (!this.showAnim && !this.showTooltip) {
|
||||
this.showAnim = true
|
||||
setTimeout(() => {
|
||||
this.showAnim = false
|
||||
this.showTooltip = true
|
||||
}, 500)
|
||||
setTimeout(() => {
|
||||
this.showTooltip = false
|
||||
}, 3000)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -104,8 +111,8 @@ export default {
|
||||
.content {
|
||||
padding: 6rem 3rem;
|
||||
|
||||
.notice {
|
||||
margin-bottom: 8rem;
|
||||
.desc {
|
||||
margin-bottom: 6rem;
|
||||
margin-top: 12rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@ -1,22 +1,20 @@
|
||||
<template>
|
||||
<div class="other-login">
|
||||
<BaseHeader>
|
||||
<BaseHeader mode="light" :isClose="true">
|
||||
<template v-slot:right>
|
||||
<span class="f16">帮助</span>
|
||||
</template>
|
||||
</BaseHeader>
|
||||
<div class="content">
|
||||
<div class="notice">
|
||||
<div class="desc">
|
||||
<div class="title">登录看朋友内容</div>
|
||||
<div class="sub-title">未注册的手机号验证通过后将自动注册</div>
|
||||
</div>
|
||||
|
||||
<div class="input-number">
|
||||
<div class="left">
|
||||
<span>+86</span>
|
||||
<div class="arrow"></div>
|
||||
</div>
|
||||
<input v-model="phone" type="text" class="right" placeholder="请输入手机号">
|
||||
<LoginInput autofocus type="phone" v-model="phone" placeholder="请输入手机号"/>
|
||||
|
||||
<div class="notice">
|
||||
{{ notice }}
|
||||
</div>
|
||||
|
||||
<div class="protocol" :class="showAnim?'anim-bounce':''">
|
||||
@ -33,9 +31,9 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="button primary no-active" :class="phone.length>10?'':'disabled'" @click="getCode">
|
||||
<b-button :loading="loading" :active="false" :disabled="phone.length < 10" @click="getCode">
|
||||
获取短信验证码
|
||||
</div>
|
||||
</b-button>
|
||||
|
||||
<div class="options">
|
||||
<span class="link" @click="$nav('/login/password')">密码登录</span>
|
||||
@ -48,12 +46,14 @@
|
||||
<script>
|
||||
import Check from "../../components/Check";
|
||||
import Tooltip from "./components/Tooltip";
|
||||
import LoginInput from "./components/LoginInput";
|
||||
|
||||
export default {
|
||||
name: "OtherLogin",
|
||||
components: {
|
||||
Check,
|
||||
Tooltip
|
||||
Tooltip,
|
||||
LoginInput
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@ -61,7 +61,9 @@ export default {
|
||||
phone: '',
|
||||
isOtherLogin: false,
|
||||
showAnim: false,
|
||||
showTooltip: false ,
|
||||
showTooltip: false,
|
||||
loading: false,
|
||||
notice: ''
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
@ -69,15 +71,22 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
getCode() {
|
||||
if (!this.isAgree && !this.showAnim && !this.showTooltip && this.phone.length > 10) {
|
||||
this.showAnim = true
|
||||
setTimeout(() => {
|
||||
this.showAnim = false
|
||||
this.showTooltip = true
|
||||
}, 500)
|
||||
setTimeout(() => {
|
||||
this.showTooltip = false
|
||||
}, 3000)
|
||||
if (this.isAgree) {
|
||||
this.loading = true
|
||||
setTimeout(()=>{
|
||||
this.$nav('/login/verification-code')
|
||||
},2000)
|
||||
} else {
|
||||
if (!this.showAnim && !this.showTooltip) {
|
||||
this.showAnim = true
|
||||
setTimeout(() => {
|
||||
this.showAnim = false
|
||||
this.showTooltip = true
|
||||
}, 500)
|
||||
setTimeout(() => {
|
||||
this.showTooltip = false
|
||||
}, 3000)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -102,7 +111,7 @@ export default {
|
||||
padding: 6rem 3rem;
|
||||
//padding-top: 6rem;
|
||||
|
||||
.notice {
|
||||
.desc {
|
||||
margin-bottom: 2rem;
|
||||
margin-top: 4rem;
|
||||
display: flex;
|
||||
@ -120,47 +129,10 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
.input-number {
|
||||
display: flex;
|
||||
background: whitesmoke;
|
||||
padding: 1.5rem 1rem;
|
||||
|
||||
.left {
|
||||
font-size: 1.2rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-right: 1rem;
|
||||
padding-right: 1rem;
|
||||
position: relative;
|
||||
|
||||
.arrow {
|
||||
margin-top: .4rem;
|
||||
margin-left: .5rem;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border: .3rem solid transparent;
|
||||
border-top: .5rem solid black;
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: ' ';
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: .8rem;
|
||||
top: 4px;
|
||||
right: 0;
|
||||
background: gainsboro;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
flex: 1;
|
||||
outline: none;
|
||||
border: none;
|
||||
background: whitesmoke;
|
||||
caret-color: red;
|
||||
//background: red;
|
||||
}
|
||||
.notice {
|
||||
margin-top: 1rem;
|
||||
font-size: 1.3rem;
|
||||
color: $primary-btn-color;
|
||||
}
|
||||
|
||||
.button {
|
||||
|
||||
@ -1,23 +1,17 @@
|
||||
<template>
|
||||
<div class="PasswordLogin">
|
||||
<BaseHeader>
|
||||
<BaseHeader mode="light" :isClose="true">
|
||||
<template v-slot:right>
|
||||
<span class="f16">帮助</span>
|
||||
</template>
|
||||
</BaseHeader>
|
||||
<div class="content">
|
||||
<div class="notice">
|
||||
<div class="title">登录看朋友内容</div>
|
||||
<div class="sub-title">未注册的手机号验证通过后将自动注册</div>
|
||||
<div class="title">手机号密码登录</div>
|
||||
</div>
|
||||
|
||||
<div class="input-number">
|
||||
<div class="left">
|
||||
<span>+86</span>
|
||||
<div class="arrow"></div>
|
||||
</div>
|
||||
<input type="text" class="right" placeholder="请输入手机号">
|
||||
</div>
|
||||
<LoginInput autofocus type="phone" v-model="phone" placeholder="请输入手机号"/>
|
||||
<LoginInput autofocus class="mt1r" type="password" v-model="password" placeholder="请输入密码"/>
|
||||
|
||||
<div class="protocol">
|
||||
<div class="left">
|
||||
@ -32,11 +26,14 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="button primary no-active disabled">获取短信验证码</div>
|
||||
<b-button :loading="loading" :active="false" :disabled="disabled" @click="login">
|
||||
{{ loading ? '登录中' : '登录' }}
|
||||
</b-button>
|
||||
|
||||
<div class="options">
|
||||
<span class="link">密码登录</span>
|
||||
<span class="link">其他方式登录</span>
|
||||
<span>
|
||||
忘记了?<span class="link">找回密码</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@ -44,21 +41,50 @@
|
||||
</template>
|
||||
<script>
|
||||
import Check from "../../components/Check";
|
||||
import LoginInput from "./components/LoginInput";
|
||||
|
||||
export default {
|
||||
name: "PasswordLogin",
|
||||
components: {
|
||||
Check
|
||||
Check,
|
||||
LoginInput
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isAgree:false
|
||||
isAgree: false,
|
||||
showAnim: false,
|
||||
showTooltip: false,
|
||||
loading: false,
|
||||
phone: '',
|
||||
password: '',
|
||||
code: '',
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
disabled() {
|
||||
return !(this.phone && this.password);
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
created() {
|
||||
},
|
||||
methods: {}
|
||||
methods: {
|
||||
login() {
|
||||
if (this.isAgree) {
|
||||
this.loading = true
|
||||
} else {
|
||||
if (!this.showAnim && !this.showTooltip) {
|
||||
this.showAnim = true
|
||||
setTimeout(() => {
|
||||
this.showAnim = false
|
||||
this.showTooltip = true
|
||||
}, 500)
|
||||
setTimeout(() => {
|
||||
this.showTooltip = false
|
||||
}, 3000)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -98,48 +124,6 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
.input-number {
|
||||
display: flex;
|
||||
background: whitesmoke;
|
||||
padding: 1.5rem 1rem;
|
||||
|
||||
.left {
|
||||
font-size: 1.2rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-right: 1rem;
|
||||
padding-right: 1rem;
|
||||
position: relative;
|
||||
.arrow {
|
||||
margin-top: .4rem;
|
||||
margin-left: .5rem;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border: .3rem solid transparent;
|
||||
border-top: .5rem solid black;
|
||||
}
|
||||
|
||||
&::before{
|
||||
content: ' ';
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: .8rem;
|
||||
top: 4px;
|
||||
right: 0;
|
||||
background: gainsboro;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
flex: 1;
|
||||
outline: none;
|
||||
border: none;
|
||||
background: whitesmoke;
|
||||
caret-color:red;
|
||||
//background: red;
|
||||
}
|
||||
}
|
||||
|
||||
.button {
|
||||
margin-bottom: .5rem;
|
||||
}
|
||||
@ -157,7 +141,7 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
.options{
|
||||
.options {
|
||||
font-size: 1.2rem;
|
||||
margin-top: 2rem;
|
||||
display: flex;
|
||||
|
||||
130
src/pages/login/VerificationCode.vue
Normal file
130
src/pages/login/VerificationCode.vue
Normal file
@ -0,0 +1,130 @@
|
||||
<template>
|
||||
<div class="VerificationCode">
|
||||
<BaseHeader mode="light" :isClose="true">
|
||||
<template v-slot:right>
|
||||
<span class="f16">帮助</span>
|
||||
</template>
|
||||
</BaseHeader>
|
||||
<div class="content">
|
||||
<div class="notice">
|
||||
<div class="title">请输入验证码</div>
|
||||
<div class="sub-title">验证码已通过短信发送到+86 13800138000</div>
|
||||
</div>
|
||||
|
||||
<LoginInput autofocus type="code"
|
||||
v-model="code"
|
||||
placeholder="请输入验证码"
|
||||
v-model:isSendVerificationCode="isSendVerificationCode"
|
||||
@send="sendCode"
|
||||
/>
|
||||
<div class="options">
|
||||
<span>
|
||||
收不到短信?<span class="link" @click="getVoiceCode">获取语音验证码</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<b-button :loading="loading" :active="false" :disabled="code.length < 4" @click="login">
|
||||
{{ loading ? '登录中' : '登录' }}
|
||||
</b-button>
|
||||
|
||||
<!-- <ConfirmDialog></ConfirmDialog>-->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import Check from "../../components/Check";
|
||||
import LoginInput from "./components/LoginInput";
|
||||
import ConfirmDialog from "../../components/dialog/ConfirmDialog";
|
||||
|
||||
export default {
|
||||
name: "VerificationCode",
|
||||
components: {
|
||||
Check,
|
||||
LoginInput,
|
||||
ConfirmDialog
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showAnim: false,
|
||||
showTooltip: false,
|
||||
loading: false,
|
||||
phone: '',
|
||||
password: '',
|
||||
code: '',
|
||||
isSendVerificationCode: true,
|
||||
}
|
||||
},
|
||||
created() {
|
||||
},
|
||||
methods: {
|
||||
getVoiceCode(){
|
||||
this.$showConfirmDialog('','语音验证码')
|
||||
},
|
||||
//TODO loading样式不对
|
||||
async sendCode() {
|
||||
this.$showLoading()
|
||||
await this.$sleep(500)
|
||||
this.$hideLoading()
|
||||
this.isSendVerificationCode = true
|
||||
},
|
||||
login() {
|
||||
this.loading = true
|
||||
setTimeout(() => {
|
||||
this.isSendVerificationCode = true
|
||||
this.loading = false
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "../../assets/scss/index";
|
||||
|
||||
.VerificationCode {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
top: 0;
|
||||
overflow: auto;
|
||||
color: black;
|
||||
font-size: 1.4rem;
|
||||
background: white;
|
||||
|
||||
.content {
|
||||
padding: 6rem 3rem;
|
||||
//padding-top: 6rem;
|
||||
|
||||
.notice {
|
||||
margin-bottom: 2rem;
|
||||
margin-top: 4rem;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
|
||||
.title {
|
||||
font-size: 2rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.sub-title {
|
||||
font-size: 1.2rem;
|
||||
color: $second-text-color;
|
||||
}
|
||||
}
|
||||
|
||||
.button {
|
||||
margin-bottom: .5rem;
|
||||
}
|
||||
|
||||
.options {
|
||||
font-size: 1.2rem;
|
||||
margin-top: 2rem;
|
||||
margin-bottom: 2rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
179
src/pages/login/components/LoginInput.vue
Normal file
179
src/pages/login/components/LoginInput.vue
Normal file
@ -0,0 +1,179 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="input-number" v-if="type === 'phone'">
|
||||
<div class="left">
|
||||
<span>+86</span>
|
||||
<div class="arrow"></div>
|
||||
</div>
|
||||
<div class="right flex1">
|
||||
<input :autofocus="autofocus" v-model="value" type="text" :placeholder="placeholder">
|
||||
<img v-if="value" src="../../../assets/img/icon/login/close-full-gray.png" alt="" @click="value=''">
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-number" v-if="type === 'password'">
|
||||
<div class="right flex1">
|
||||
<input :autofocus="autofocus" v-model="value" type="password" :placeholder="placeholder">
|
||||
<img v-if="value" src="../../../assets/img/icon/login/close-full-gray.png" alt="" @click="value=''">
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-number" v-if="type === 'code'">
|
||||
<div class="left no-border flex1">
|
||||
<input :autofocus="autofocus" v-model="value" type="text" :placeholder="placeholder">
|
||||
<img v-if="value" src="../../../assets/img/icon/login/close-full-gray.png" alt="" @click="value=''">
|
||||
</div>
|
||||
<div class="right" @click="send">
|
||||
<span :class="isSendVerificationCode && 'disabled'">{{ verificationCodeBtnText }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "LoginInput",
|
||||
props: {
|
||||
modelValue: '',
|
||||
placeholder: '',
|
||||
type: {
|
||||
type: String,
|
||||
default: 'phone'
|
||||
},
|
||||
autofocus: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
isSendVerificationCode: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
verificationCodeBtnText: 60
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
value: {
|
||||
get() {
|
||||
return this.modelValue
|
||||
},
|
||||
set(e) {
|
||||
this.$emit('update:modelValue', e)
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
isSendVerificationCode: {
|
||||
immediate: true,
|
||||
handler(newVal, oldVal) {
|
||||
if (newVal) {
|
||||
this.verificationCodeBtnText = 60
|
||||
let ticker = setInterval(() => {
|
||||
if (this.verificationCodeBtnText > 0) {
|
||||
this.verificationCodeBtnText--
|
||||
} else {
|
||||
this.verificationCodeBtnText = '重新发送'
|
||||
this.$emit('update:isSendVerificationCode', false)
|
||||
clearInterval(ticker)
|
||||
}
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
send(){
|
||||
if (!this.isSendVerificationCode){
|
||||
this.$emit('send')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "../../../assets/scss/index";
|
||||
|
||||
.input-number {
|
||||
display: flex;
|
||||
background: whitesmoke;
|
||||
padding: 1.5rem 1rem;
|
||||
font-size: 1.4rem;
|
||||
|
||||
.left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-right: 1rem;
|
||||
padding-right: 1rem;
|
||||
position: relative;
|
||||
|
||||
&.no-border {
|
||||
&::before {
|
||||
content: '';
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.flex1 {
|
||||
flex: 1;
|
||||
margin-right: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
img {
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
right: 1rem;
|
||||
position: absolute;
|
||||
height: 1.5rem;
|
||||
}
|
||||
|
||||
.arrow {
|
||||
margin-top: .4rem;
|
||||
margin-left: .5rem;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border: .3rem solid transparent;
|
||||
border-top: .5rem solid black;
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: ' ';
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: .8rem;
|
||||
top: 4px;
|
||||
right: 0;
|
||||
background: gainsboro;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
//background: red;
|
||||
position: relative;
|
||||
|
||||
&.flex1 {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
img {
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
right: 1rem;
|
||||
position: absolute;
|
||||
height: 1.5rem;
|
||||
}
|
||||
|
||||
.disabled {
|
||||
color: $second-text-color;
|
||||
}
|
||||
}
|
||||
|
||||
input {
|
||||
width: 90%;
|
||||
outline: none;
|
||||
border: none;
|
||||
background: whitesmoke;
|
||||
caret-color: red;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -39,6 +39,7 @@ import Me2 from "../pages/me/Me2";
|
||||
import Login from "../pages/login/Login";
|
||||
import OtherLogin from "../pages/login/OtherLogin";
|
||||
import PasswordLogin from "../pages/login/PasswordLogin";
|
||||
import VerificationCode from "../pages/login/VerificationCode";
|
||||
|
||||
const routes = [
|
||||
// {path: '', component: Music},
|
||||
@ -82,6 +83,7 @@ const routes = [
|
||||
{path: '/login', component: Login},
|
||||
{path: '/login/other', component: OtherLogin},
|
||||
{path: '/login/password', component: PasswordLogin},
|
||||
{path: '/login/verification-code', component: VerificationCode},
|
||||
]
|
||||
|
||||
export default VueRouter.createRouter({
|
||||
|
||||
@ -11,6 +11,7 @@ import Mask from "../components/Mask";
|
||||
import NoMore from "../components/NoMore";
|
||||
import Back from "../components/Back";
|
||||
import Loading from "../components/Loading";
|
||||
import BaseButton from "../components/BaseButton";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@ -25,7 +26,8 @@ export default {
|
||||
Mask,
|
||||
NoMore,
|
||||
Back,
|
||||
Loading
|
||||
Loading,
|
||||
'b-button':BaseButton
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user