mand-mobile/components/captcha/index.vue

238 lines
5.0 KiB
Vue
Raw Normal View History

2018-03-26 16:04:04 +08:00
<template>
<div class="md-captcha" v-show="isView || value || visible">
<template v-if="isView">
<div class="md-captcha-content">
<h2 class="md-captcha-title" v-if="title" v-text="title"></h2>
2018-04-11 15:22:40 +08:00
<div class="md-captcha-error" v-text="errorMsg"></div>
<div class="md-captcha-message">
2018-03-26 16:04:04 +08:00
<slot></slot>
</div>
<md-button
v-if="count"
type="ghost"
size="small"
v-text="counterText"
:disabled="this.isCounting"
2018-04-24 22:49:00 +08:00
@click="$_onClickResend"
2018-03-26 16:04:04 +08:00
></md-button>
</div>
<md-codebox
ref="codebox"
v-model="code"
:maxlength="maxlength"
:system="system"
:closable="false"
:isView="isView"
:mask="mask"
:autofocus="false"
@submit="$_onSubmit"
/>
</template>
<template v-else>
<md-dialog
:value="value"
:closable="true"
:appendTo="false"
position="center"
@input="$_onInput"
@show="$_onShow"
@hide="$_onHide"
>
<div class="md-captcha-content">
<h2 class="md-captcha-title" v-if="title" v-text="title"></h2>
2018-04-11 15:22:40 +08:00
<div class="md-captcha-error" v-text="errorMsg"></div>
<div class="md-captcha-message">
2018-03-26 16:04:04 +08:00
<slot></slot>
</div>
<md-button
v-if="count"
type="ghost"
size="small"
v-text="counterText"
:disabled="this.isCounting"
2018-04-24 22:49:00 +08:00
@click="$_onClickResend"
2018-03-26 16:04:04 +08:00
></md-button>
</div>
<md-codebox
ref="codebox"
v-model="code"
:maxlength="maxlength"
:system="system"
:closable="false"
:mask="mask"
:autofocus="false"
@submit="$_onSubmit"
/>
</md-dialog>
</template>
</div>
</template>
<script> import Dialog from '../dialog'
import Codebox from '../codebox'
import Button from '../button'
export default {
name: 'md-captcha',
components: {
[Dialog.name]: Dialog,
[Codebox.name]: Codebox,
[Button.name]: Button,
},
props: {
title: {
type: String,
},
value: {
type: Boolean,
default: false,
},
maxlength: {
type: [Number, String],
default: 4,
},
mask: {
type: Boolean,
default: false,
},
system: {
type: Boolean,
default: false,
},
appendTo: {
default: () => document.body,
},
count: {
type: Number,
default: 60,
},
isView: {
type: Boolean,
default: false,
},
},
data() {
return {
code: '',
visible: false,
counterText: '发送验证码',
2018-04-11 15:22:40 +08:00
errorMsg: '',
2018-03-26 16:04:04 +08:00
isCounting: false,
firstShown: false,
}
},
watch: {
value(val) {
if (val) {
this.code = ''
if (!this.firstShown) {
this.firstShown = true
2018-04-24 22:49:00 +08:00
this.countdown()
2018-03-26 16:04:04 +08:00
}
}
},
2018-04-11 15:22:40 +08:00
code(val) {
if (val && this.errorMsg) {
this.errorMsg = ''
}
},
2018-03-26 16:04:04 +08:00
},
mounted() {
if (this.appendTo && !this.isView) {
this.appendTo.appendChild(this.$el)
}
if (this.value) {
this.firstShown = true
2018-04-24 22:49:00 +08:00
this.countdown()
2018-03-26 16:04:04 +08:00
}
},
2018-04-18 15:05:47 +08:00
beforeDestroy() {
if (this.appendTo && !this.isView) {
this.appendTo.removeChild(this.$el)
}
},
2018-03-26 16:04:04 +08:00
methods: {
// MARK: events handler, 如 $_onButtonClick
$_onInput(val) {
this.$emit('input', val)
},
$_onShow() {
this.visible = true
this.$refs.codebox.focus()
this.$emit('show')
},
$_onHide() {
this.visible = false
this.$refs.codebox.blur()
this.$emit('hide')
},
$_onSubmit(code) {
this.$emit('submit', code)
},
$_onClickResend() {
2018-04-24 22:49:00 +08:00
this.countdown()
this.$emit('send')
2018-03-26 16:04:04 +08:00
},
// MARK: public methods
countdown() {
2018-04-24 22:49:00 +08:00
if (!this.count) {
return
}
2018-03-26 16:04:04 +08:00
clearInterval(this.__counter__)
let i = this.count - 1
this.isCounting = true
this.counterText = `${i}s后重发`
2018-04-23 17:33:32 +08:00
/* istanbul ignore next */
2018-03-26 16:04:04 +08:00
this.__counter__ = setInterval(() => {
if (i === 0) {
this.resetcount()
} else {
i--
this.counterText = `${i}s后重发`
}
}, 1000)
},
resetcount() {
this.isCounting = false
this.counterText = '发送验证码'
clearInterval(this.__counter__)
},
2018-04-11 15:22:40 +08:00
setError(msg) {
this.$nextTick(() => {
this.errorMsg = msg
this.code = ''
})
},
2018-03-26 16:04:04 +08:00
},
}
</script>
<style lang="stylus">
.md-captcha
.md-dialog .md-dialog-content
margin-bottom number-keyboard-height
.md-captcha-content
text-align center
margin-bottom 20px
font-size 24px
.md-captcha-title
color color-text-base
font-size 32px
2018-04-11 15:22:40 +08:00
margin 0
.md-captcha-error
color #FF525D
font-size 24px
line-height 32px
height 32px
margin-bottom 12px
2018-03-26 16:04:04 +08:00
.md-button
2018-04-11 15:22:40 +08:00
margin 0.32rem auto
2018-03-26 16:04:04 +08:00
</style>