登录页面
This commit is contained in:
parent
c0881225ea
commit
2bcd996d58
@ -72,6 +72,7 @@ export default {
|
|||||||
'/login',
|
'/login',
|
||||||
'/login/other',
|
'/login/other',
|
||||||
'/login/password',
|
'/login/password',
|
||||||
|
'/login/verification-code',
|
||||||
|
|
||||||
|
|
||||||
'/service-protocol',
|
'/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,
|
type: String,
|
||||||
default: 'gray',//white
|
default: 'gray',//white
|
||||||
},
|
},
|
||||||
|
isClose: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
direction: {
|
direction: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'left',
|
default: 'left',
|
||||||
},
|
},
|
||||||
scale: {
|
scale: {
|
||||||
type: [Number,String],
|
type: [Number, String],
|
||||||
default: 1,
|
default: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
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() {
|
mounted() {
|
||||||
this.$setCss(this.$refs.img, 'transform', `rotate(${this.direction === 'left' ? '0' : '180'}deg) scale(${this.scale})`)
|
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>
|
<template>
|
||||||
<div id='BaseHeader'>
|
<div id='BaseHeader' :class="mode">
|
||||||
<div class="header">
|
<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="center"><span></span></slot>
|
||||||
<slot name="right"><span></span></slot>
|
<slot name="right"><span></span></slot>
|
||||||
</div>
|
</div>
|
||||||
@ -12,7 +15,16 @@
|
|||||||
export default {
|
export default {
|
||||||
name: "BaseHeader",
|
name: "BaseHeader",
|
||||||
components: {},
|
components: {},
|
||||||
props: {},
|
props: {
|
||||||
|
mode: {
|
||||||
|
type: String,
|
||||||
|
default: 'dark',//light
|
||||||
|
},
|
||||||
|
isClose: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {}
|
return {}
|
||||||
},
|
},
|
||||||
@ -37,9 +49,18 @@ export default {
|
|||||||
#BaseHeader {
|
#BaseHeader {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
background: $main-bg;
|
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
|
|
||||||
|
&.light {
|
||||||
|
background: white;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.dark {
|
||||||
|
background: $main-bg;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@ -47,7 +68,6 @@ export default {
|
|||||||
height: 6rem;
|
height: 6rem;
|
||||||
border-bottom: 1px solid #cccccc11;
|
border-bottom: 1px solid #cccccc11;
|
||||||
position: relative;
|
position: relative;
|
||||||
color: white;
|
|
||||||
|
|
||||||
.left {
|
.left {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="ConfirmDialog " @click="$emit('dismiss')">
|
<div class="SimpleConfirmDialog " @click="$emit('dismiss')">
|
||||||
<div class="content" @click.stop="null">
|
<div class="content" @click.stop="null">
|
||||||
<div class="item">{{ title }}</div>
|
<div class="item">{{ title }}</div>
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
@ -11,7 +11,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: "ConfirmDialog",
|
name: "SimpleConfirmDialog",
|
||||||
props: {
|
props: {
|
||||||
visible: {
|
visible: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
@ -32,7 +32,7 @@ export default {
|
|||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|
||||||
.ConfirmDialog {
|
.SimpleConfirmDialog {
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
|||||||
@ -1,19 +1,21 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="login">
|
<div class="login">
|
||||||
<BaseHeader>
|
<BaseHeader mode="light" :isClose="true">
|
||||||
<template v-slot:right>
|
<template v-slot:right>
|
||||||
<span class="f16">帮助</span>
|
<span class="f16">帮助</span>
|
||||||
</template>
|
</template>
|
||||||
</BaseHeader>
|
</BaseHeader>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="notice">
|
<div class="desc">
|
||||||
<div class="title">登录看朋友内容</div>
|
<div class="title">登录看朋友内容</div>
|
||||||
<div class="phone-number">138****8000</div>
|
<div class="phone-number">138****8000</div>
|
||||||
<div class="sub-title">认证服务由中国移动提供</div>
|
<div class="sub-title">认证服务由中国移动提供</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="button primary no-active" @click="login">一键登录</div>
|
<b-button :loading="loading" :active="false" :loadingWithText="true" @click="login">
|
||||||
<div class="button white" @click="$nav('/login/other')">其他手机号码登录</div>
|
{{ loading ? '登录中' : '一键登录' }}
|
||||||
|
</b-button>
|
||||||
|
<b-button :active="false" type="white" @click="$nav('/login/other')">其他手机号码登录</b-button>
|
||||||
|
|
||||||
<div class="protocol" :class="showAnim?'anim-bounce':''">
|
<div class="protocol" :class="showAnim?'anim-bounce':''">
|
||||||
<Tooltip style="top: -100%;left: -1rem;" v-model="showTooltip"/>
|
<Tooltip style="top: -100%;left: -1rem;" v-model="showTooltip"/>
|
||||||
@ -65,6 +67,7 @@ export default {
|
|||||||
isOtherLogin: false,
|
isOtherLogin: false,
|
||||||
showAnim: false,
|
showAnim: false,
|
||||||
showTooltip: false,
|
showTooltip: false,
|
||||||
|
loading: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {},
|
computed: {},
|
||||||
@ -72,15 +75,19 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
login() {
|
login() {
|
||||||
if (!this.isAgree && !this.showAnim && !this.showTooltip) {
|
if (this.isAgree) {
|
||||||
this.showAnim = true
|
this.loading = true
|
||||||
setTimeout(() => {
|
} else {
|
||||||
this.showAnim = false
|
if (!this.showAnim && !this.showTooltip) {
|
||||||
this.showTooltip = true
|
this.showAnim = true
|
||||||
}, 500)
|
setTimeout(() => {
|
||||||
setTimeout(() => {
|
this.showAnim = false
|
||||||
this.showTooltip = false
|
this.showTooltip = true
|
||||||
}, 3000)
|
}, 500)
|
||||||
|
setTimeout(() => {
|
||||||
|
this.showTooltip = false
|
||||||
|
}, 3000)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -104,8 +111,8 @@ export default {
|
|||||||
.content {
|
.content {
|
||||||
padding: 6rem 3rem;
|
padding: 6rem 3rem;
|
||||||
|
|
||||||
.notice {
|
.desc {
|
||||||
margin-bottom: 8rem;
|
margin-bottom: 6rem;
|
||||||
margin-top: 12rem;
|
margin-top: 12rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
@ -1,22 +1,20 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="other-login">
|
<div class="other-login">
|
||||||
<BaseHeader>
|
<BaseHeader mode="light" :isClose="true">
|
||||||
<template v-slot:right>
|
<template v-slot:right>
|
||||||
<span class="f16">帮助</span>
|
<span class="f16">帮助</span>
|
||||||
</template>
|
</template>
|
||||||
</BaseHeader>
|
</BaseHeader>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="notice">
|
<div class="desc">
|
||||||
<div class="title">登录看朋友内容</div>
|
<div class="title">登录看朋友内容</div>
|
||||||
<div class="sub-title">未注册的手机号验证通过后将自动注册</div>
|
<div class="sub-title">未注册的手机号验证通过后将自动注册</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="input-number">
|
<LoginInput autofocus type="phone" v-model="phone" placeholder="请输入手机号"/>
|
||||||
<div class="left">
|
|
||||||
<span>+86</span>
|
<div class="notice">
|
||||||
<div class="arrow"></div>
|
{{ notice }}
|
||||||
</div>
|
|
||||||
<input v-model="phone" type="text" class="right" placeholder="请输入手机号">
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="protocol" :class="showAnim?'anim-bounce':''">
|
<div class="protocol" :class="showAnim?'anim-bounce':''">
|
||||||
@ -33,9 +31,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</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">
|
<div class="options">
|
||||||
<span class="link" @click="$nav('/login/password')">密码登录</span>
|
<span class="link" @click="$nav('/login/password')">密码登录</span>
|
||||||
@ -48,12 +46,14 @@
|
|||||||
<script>
|
<script>
|
||||||
import Check from "../../components/Check";
|
import Check from "../../components/Check";
|
||||||
import Tooltip from "./components/Tooltip";
|
import Tooltip from "./components/Tooltip";
|
||||||
|
import LoginInput from "./components/LoginInput";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "OtherLogin",
|
name: "OtherLogin",
|
||||||
components: {
|
components: {
|
||||||
Check,
|
Check,
|
||||||
Tooltip
|
Tooltip,
|
||||||
|
LoginInput
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -61,7 +61,9 @@ export default {
|
|||||||
phone: '',
|
phone: '',
|
||||||
isOtherLogin: false,
|
isOtherLogin: false,
|
||||||
showAnim: false,
|
showAnim: false,
|
||||||
showTooltip: false ,
|
showTooltip: false,
|
||||||
|
loading: false,
|
||||||
|
notice: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {},
|
computed: {},
|
||||||
@ -69,15 +71,22 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getCode() {
|
getCode() {
|
||||||
if (!this.isAgree && !this.showAnim && !this.showTooltip && this.phone.length > 10) {
|
if (this.isAgree) {
|
||||||
this.showAnim = true
|
this.loading = true
|
||||||
setTimeout(() => {
|
setTimeout(()=>{
|
||||||
this.showAnim = false
|
this.$nav('/login/verification-code')
|
||||||
this.showTooltip = true
|
},2000)
|
||||||
}, 500)
|
} else {
|
||||||
setTimeout(() => {
|
if (!this.showAnim && !this.showTooltip) {
|
||||||
this.showTooltip = false
|
this.showAnim = true
|
||||||
}, 3000)
|
setTimeout(() => {
|
||||||
|
this.showAnim = false
|
||||||
|
this.showTooltip = true
|
||||||
|
}, 500)
|
||||||
|
setTimeout(() => {
|
||||||
|
this.showTooltip = false
|
||||||
|
}, 3000)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -102,7 +111,7 @@ export default {
|
|||||||
padding: 6rem 3rem;
|
padding: 6rem 3rem;
|
||||||
//padding-top: 6rem;
|
//padding-top: 6rem;
|
||||||
|
|
||||||
.notice {
|
.desc {
|
||||||
margin-bottom: 2rem;
|
margin-bottom: 2rem;
|
||||||
margin-top: 4rem;
|
margin-top: 4rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -120,47 +129,10 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-number {
|
.notice {
|
||||||
display: flex;
|
margin-top: 1rem;
|
||||||
background: whitesmoke;
|
font-size: 1.3rem;
|
||||||
padding: 1.5rem 1rem;
|
color: $primary-btn-color;
|
||||||
|
|
||||||
.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 {
|
.button {
|
||||||
|
|||||||
@ -1,23 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="PasswordLogin">
|
<div class="PasswordLogin">
|
||||||
<BaseHeader>
|
<BaseHeader mode="light" :isClose="true">
|
||||||
<template v-slot:right>
|
<template v-slot:right>
|
||||||
<span class="f16">帮助</span>
|
<span class="f16">帮助</span>
|
||||||
</template>
|
</template>
|
||||||
</BaseHeader>
|
</BaseHeader>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="notice">
|
<div class="notice">
|
||||||
<div class="title">登录看朋友内容</div>
|
<div class="title">手机号密码登录</div>
|
||||||
<div class="sub-title">未注册的手机号验证通过后将自动注册</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="input-number">
|
<LoginInput autofocus type="phone" v-model="phone" placeholder="请输入手机号"/>
|
||||||
<div class="left">
|
<LoginInput autofocus class="mt1r" type="password" v-model="password" placeholder="请输入密码"/>
|
||||||
<span>+86</span>
|
|
||||||
<div class="arrow"></div>
|
|
||||||
</div>
|
|
||||||
<input type="text" class="right" placeholder="请输入手机号">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="protocol">
|
<div class="protocol">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
@ -32,11 +26,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</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">
|
<div class="options">
|
||||||
<span class="link">密码登录</span>
|
<span>
|
||||||
<span class="link">其他方式登录</span>
|
忘记了?<span class="link">找回密码</span>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -44,21 +41,50 @@
|
|||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import Check from "../../components/Check";
|
import Check from "../../components/Check";
|
||||||
|
import LoginInput from "./components/LoginInput";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "PasswordLogin",
|
name: "PasswordLogin",
|
||||||
components: {
|
components: {
|
||||||
Check
|
Check,
|
||||||
|
LoginInput
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isAgree:false
|
isAgree: false,
|
||||||
|
showAnim: false,
|
||||||
|
showTooltip: false,
|
||||||
|
loading: false,
|
||||||
|
phone: '',
|
||||||
|
password: '',
|
||||||
|
code: '',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
disabled() {
|
||||||
|
return !(this.phone && this.password);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {},
|
|
||||||
created() {
|
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>
|
</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 {
|
.button {
|
||||||
margin-bottom: .5rem;
|
margin-bottom: .5rem;
|
||||||
}
|
}
|
||||||
@ -157,7 +141,7 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.options{
|
.options {
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
margin-top: 2rem;
|
margin-top: 2rem;
|
||||||
display: flex;
|
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 Login from "../pages/login/Login";
|
||||||
import OtherLogin from "../pages/login/OtherLogin";
|
import OtherLogin from "../pages/login/OtherLogin";
|
||||||
import PasswordLogin from "../pages/login/PasswordLogin";
|
import PasswordLogin from "../pages/login/PasswordLogin";
|
||||||
|
import VerificationCode from "../pages/login/VerificationCode";
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
// {path: '', component: Music},
|
// {path: '', component: Music},
|
||||||
@ -82,6 +83,7 @@ const routes = [
|
|||||||
{path: '/login', component: Login},
|
{path: '/login', component: Login},
|
||||||
{path: '/login/other', component: OtherLogin},
|
{path: '/login/other', component: OtherLogin},
|
||||||
{path: '/login/password', component: PasswordLogin},
|
{path: '/login/password', component: PasswordLogin},
|
||||||
|
{path: '/login/verification-code', component: VerificationCode},
|
||||||
]
|
]
|
||||||
|
|
||||||
export default VueRouter.createRouter({
|
export default VueRouter.createRouter({
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import Mask from "../components/Mask";
|
|||||||
import NoMore from "../components/NoMore";
|
import NoMore from "../components/NoMore";
|
||||||
import Back from "../components/Back";
|
import Back from "../components/Back";
|
||||||
import Loading from "../components/Loading";
|
import Loading from "../components/Loading";
|
||||||
|
import BaseButton from "../components/BaseButton";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@ -25,7 +26,8 @@ export default {
|
|||||||
Mask,
|
Mask,
|
||||||
NoMore,
|
NoMore,
|
||||||
Back,
|
Back,
|
||||||
Loading
|
Loading,
|
||||||
|
'b-button':BaseButton
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user