add NumberKeyboard component

This commit is contained in:
陈嘉涵
2017-09-08 21:06:16 +08:00
parent c221922e04
commit f0cbcc99dc
9 changed files with 466 additions and 0 deletions
+3
View File
@@ -24,6 +24,7 @@ import Lazyload from './lazyload';
import Loading from './loading';
import NavBar from './nav-bar';
import NoticeBar from './notice-bar';
import NumberKeyboard from './number-keyboard';
import Panel from './panel';
import Picker from './picker';
import Popup from './popup';
@@ -74,6 +75,7 @@ const components = [
Loading,
NavBar,
NoticeBar,
NumberKeyboard,
Panel,
Picker,
Popup,
@@ -140,6 +142,7 @@ export {
Loading,
NavBar,
NoticeBar,
NumberKeyboard,
Panel,
Picker,
Popup,
+137
View File
@@ -0,0 +1,137 @@
<template>
<transition :name="transition ? 'van-slide-bottom' : ''">
<div
v-show="show"
:style="style"
class="van-number-keyboard"
@touchstart.stop.prevent="focus"
@touchmove="blurKey"
@touchend="blurKey"
@touchcancel="blurKey"
@animationend="onAnimationEnd"
>
<h3 class="van-number-keyboard__title van-hairline--top">
<span>{{ title }}</span>
</h3>
<i
v-for="(key, index) in keys"
v-text="key"
:data-key="index"
:class="['van-hairline', {
'van-number-keyboard--active': index === active,
'van-number-keyboard__delete': index === 11 && showDeleteKey
}]"
/>
</div>
</transition>
</template>
<script>
export default {
name: 'van-number-keyboard',
props: {
show: Boolean,
extraKey: {
type: String,
default: ''
},
title: {
type: String,
default: '安全输入键盘'
},
zIndex: {
type: Number,
default: 100
},
transition: {
type: Boolean,
default: true
},
showDeleteKey: {
type: Boolean,
default: true
}
},
mounted() {
this.handler(true);
},
destroyed() {
this.handler(false);
},
activated() {
this.handler(true);
},
deactivated() {
this.handler(false);
},
data() {
return {
active: -1
};
},
watch: {
show() {
if (!this.transition) {
this.$emit(this.show ? 'show' : 'hide');
}
}
},
computed: {
keys() {
const keys = [];
for (let i = 0; i < 12; i++) {
const key = i === 10 ? 0 : i < 9 ? i + 1 : i === 9 ? this.extraKey : '';
keys.push(key);
}
return keys;
},
style() {
return {
zIndex: this.zIndex
};
}
},
methods: {
handler(action) {
if (action !== this.handlerStatus) {
this.handlerStatus = action;
document.body[(action ? 'add' : 'remove') + 'EventListener']('touchstart', this.blurKeyboard);
}
},
focus(event) {
this.active = parseInt(event.target.dataset.key);
if (this.active === 11) {
this.$emit('delete');
} else if (!isNaN(this.active)) {
const key = this.keys[this.active];
if (key !== '') {
this.$emit('input', key);
}
}
},
blurKey() {
this.active = -1;
},
blurKeyboard() {
this.$emit('blur');
},
onAnimationEnd() {
this.$emit(this.show ? 'show' : 'hide');
}
}
};
</script>
+1
View File
@@ -5,4 +5,5 @@
@import "./common/var.css";
@import "./common/normalize.css";
@import "./common/hairline.css";
@import "./common/animation.css";
@@ -0,0 +1,21 @@
@keyframes van-slide-bottom-enter {
from {
transform: translate3d(0, 100%, 0);
}
}
@keyframes van-slide-bottom-leave {
to {
transform: translate3d(0, 100%, 0);
}
}
.van-slide-bottom {
&-enter-active {
animation: van-slide-bottom-enter .3s both ease;
}
&-leave-active {
animation: van-slide-bottom-leave .3s both ease;
}
}
+1
View File
@@ -34,6 +34,7 @@
@import './radio.css';
@import './switch.css';
@import './uploader.css';
@import './number-keyboard.css';
/* action components */
@import './actionsheet.css';
+52
View File
@@ -0,0 +1,52 @@
@import "./common/var.css";
.van-number-keyboard {
left: 0;
bottom: 0;
width: 100%;
position: fixed;
user-select: none;
background-color: $white;
animation-timing-function: ease-out;
&__title {
font-weight: 400;
text-align: center;
color: $gray-dark;
font-size: 12px;
line-height: 25px;
}
i {
width: calc(100%/3);
height: 54px;
font-size: 24px;
line-height: 54px;
font-style: normal;
text-align: center;
display: inline-block;
vertical-align: middle;
&::after {
border-top-width: 1px;
}
&:not(:nth-of-type(3n))::after {
border-right-width: 1px;
}
&:nth-of-type(10),
&:nth-of-type(12) {
background-color: #F3F3F6;
}
}
&__delete {
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAeCAMAAABg6AyVAAAAbFBMVEUAAAAfHiIdHB4eHR8dHR4eHB4dHB4dHR8gICIdHB4dHB4dHB4dHB8eHh8hISEeHR8fHB8fHR8fHR8fHx8eHiArKyszMzMeHB8eHB8fHR8eHiAeHh4dHB4vLjDY2Nn////b29zKysq9vb28vLzkfBRpAAAAHHRSTlMAK/PW+I/llBv77N1kSCPwWlFAOTMGBb28hHlu08g5sgAAAMlJREFUOMuV1MsWgiAQgGHQyOx+s+sgYO//jnnMGIdDDfwbN99CYEDQFiVEKkolPUG7gl9VTWC31NKuDbVz+Fc1tRJtPDmxS2BS3p5ZC+XXnnbAVoz2WEBCH7uZAalzGoa06whGiznT6sG2xgX4QO2Aej1+KN7XBKL2FvGaMtTWBhbQhtoaYzVQrHKwuGf8hhAPSF5g3xPSt45sCHcouNWx436FGA+RHyQcD35EcUj54U8ff4WYvVi1zLjelUh/OG6XjOeLWv5hfAOI+HLwwOAqhAAAAABJRU5ErkJggg==") no-repeat center center;
background-size: auto 15px;
}
i&--active {
background-color: $active-color!important;
}
}