[improvement] rename packages dir to src (#3659)

This commit is contained in:
neverland
2019-06-27 11:25:57 +08:00
committed by GitHub
parent 8489918dca
commit 75c79b7044
619 changed files with 21 additions and 21 deletions
+65
View File
@@ -0,0 +1,65 @@
import { createNamespace } from '../utils';
const [createComponent, bem] = createNamespace('key');
export default createComponent({
props: {
type: String,
theme: Array,
text: [String, Number]
},
data() {
return {
active: false
};
},
computed: {
className() {
const classNames = this.theme.slice(0);
if (this.active) {
classNames.push('active');
}
if (this.type) {
classNames.push(this.type);
}
return bem(classNames);
}
},
methods: {
onFocus() {
this.active = true;
},
onBlur(event) {
this.active = false;
},
onClick() {
this.$emit('press', this.text, this.type);
}
},
render(h) {
const { onBlur } = this;
return (
<i
role="button"
tabindex="0"
class={['van-hairline', this.className]}
onClick={this.onClick}
onTouchstart={this.onFocus}
onTouchmove={onBlur}
onTouchend={onBlur}
onTouchcancel={onBlur}
>
{this.slots('default') || this.text}
</i>
);
}
});
+112
View File
@@ -0,0 +1,112 @@
<template>
<demo-section>
<demo-block :title="$t('default')">
<van-button
type="primary"
@touchstart.stop="keyboard = 'default'"
>
{{ $t('button1') }}
</van-button>
<van-number-keyboard
:show="keyboard === 'default'"
:close-button-text="$t('close')"
extra-key="."
safe-area-inset-bottom
@blur="keyboard = ''"
@input="onInput"
@delete="onDelete"
/>
</demo-block>
<demo-block :title="$t('custom')">
<van-button
type="primary"
@touchstart.stop="keyboard = 'custom'"
>
{{ $t('button2') }}
</van-button>
<van-number-keyboard
:show="keyboard === 'custom'"
:close-button-text="$t('close')"
theme="custom"
extra-key="."
safe-area-inset-bottom
@blur="keyboard = ''"
@input="onInput"
@delete="onDelete"
/>
</demo-block>
<demo-block :title="$t('bindValue')">
<van-field
readonly
clickable
:value="value"
:placeholder="$t('clickToInput')"
@touchstart.native.stop="keyboard = 'bindValue'"
/>
<van-number-keyboard
v-model="value"
:show="keyboard === 'bindValue'"
maxlength="6"
safe-area-inset-bottom
@blur="keyboard = ''"
/>
</demo-block>
</demo-section>
</template>
<script>
export default {
i18n: {
'zh-CN': {
default: '默认样式',
custom: '自定义样式',
button1: '弹出默认键盘',
button2: '弹出自定义键盘',
close: '完成',
input: '输入',
bindValue: '双向绑定',
clickToInput: '点此输入'
},
'en-US': {
default: 'Default style',
custom: 'Custom style',
button1: 'Show Default Keyboard',
button2: 'Show Custom Keyboard',
close: 'Close',
input: 'Input',
bindValue: 'Bind Value',
clickToInput: 'Click To Input'
}
},
data() {
return {
value: '',
keyboard: 'default'
};
},
methods: {
onInput(value) {
this.$toast(`${this.$t('input')}: ${value}`);
},
onDelete() {
this.$toast(this.$t('delete'));
}
}
};
</script>
<style lang="less">
.demo-number-keyboard {
.van-button {
margin-left: 15px;
}
}
</style>
+127
View File
@@ -0,0 +1,127 @@
# NumberKeyboard
### Install
``` javascript
import { NumberKeyboard } from 'vant';
Vue.use(NumberKeyboard);
```
## Usage
### Default Style
```html
<van-button @touchstart.stop="show = true">
Show Keyboard
</van-button>
<van-number-keyboard
:show="show"
extra-key="."
close-button-text="Close"
@blur="show = false"
@input="onInput"
@delete="onDelete"
/>
```
```javascript
export default {
data() {
return {
show: true
}
},
methods: {
onInput(value) {
Toast(value);
},
onDelete() {
Toast('delete');
}
}
}
```
### Custom Style
```html
<van-number-keyboard
:show="show"
theme="custom"
extra-key="."
close-button-text="Close"
@blur="show = false"
@input="onInput"
@delete="onDelete"
/>
```
### Bind Value
```html
<van-field
readonly
clickable
:value="value"
@touchstart.native.stop="show = true"
/>
<van-number-keyboard
v-model="value"
:show="show"
:maxlength="6"
@blur="show = false"
/>
```
```javascript
export default {
data() {
return {
show: false,
value: ''
}
}
}
```
## API
### Props
| Attribute | Description | Type | Default |
|------|------|------|------|
| v-model | Current value | `String` | - |
| show | Whether to show keyboard | `Boolean` | - |
| theme | Keyboard themecan be set to `default` `custom` | `String` | `default` |
| title | Keyboard title | `String` | - |
| maxlength | Value maxlength | `Number | String` | - |
| transition | Whether to show transition animation | `Boolean` | `true` |
| z-index | Keyboard z-index | `Number` | `100` |
| extra-key | Content of bottom left key | `String` | `''` |
| close-button-text | Close button text | `String` | `-` |
| delete-button-text | Delete button text | `String` | `delete` |
| show-delete-key | Whether to show delete button | `Boolean` | `true` |
| hide-on-click-outside | Whether to hide keyboard when click outside | `Boolean` | `true` |
| safe-area-inset-bottom | Whether to enable bottom safe area adaptation, to enable those features use `viewport-fit=cover` in the `viewport` meta tag | `Boolean` | `false` |
### Events
| Event | Description | Arguments |
|------|------|------|
| input | Triggered when keydown | key: Content of the key |
| delete | Triggered when press delete key | - |
| blur | Triggered when click close button | - |
| blur | Triggered when click close button or blur keyboard | - |
| show | Triggered when keyboard is fully displayed. | - |
| hide | Triggered when keyboard is fully hidden. | - |
### Slots
| Name | Description |
|------|------|
| delete | Custom delete button content |
| title-left | Custom title left content |
+199
View File
@@ -0,0 +1,199 @@
import { createNamespace } from '../utils';
import { stopPropagation } from '../utils/dom/event';
import { BindEventMixin } from '../mixins/bind-event';
import Key from './Key';
const [createComponent, bem, t] = createNamespace('number-keyboard');
const CLOSE_KEY_THEME = ['blue', 'big'];
const DELETE_KEY_THEME = ['delete', 'big', 'gray'];
export default createComponent({
mixins: [
BindEventMixin(function (bind) {
if (this.hideOnClickOutside) {
bind(document.body, 'touchstart', this.onBlur);
}
})
],
model: {
event: 'update:value'
},
props: {
show: Boolean,
title: String,
closeButtonText: String,
deleteButtonText: String,
safeAreaInsetBottom: Boolean,
theme: {
type: String,
default: 'default'
},
value: {
type: String,
default: ''
},
extraKey: {
type: String,
default: ''
},
maxlength: {
type: [Number, String],
default: Number.MAX_VALUE
},
zIndex: {
type: Number,
default: 100
},
transition: {
type: Boolean,
default: true
},
showDeleteKey: {
type: Boolean,
default: true
},
hideOnClickOutside: {
type: Boolean,
default: true
}
},
watch: {
show() {
if (!this.transition) {
this.$emit(this.show ? 'show' : 'hide');
}
}
},
computed: {
keys() {
const keys = [];
for (let i = 1; i <= 9; i++) {
keys.push({ text: i });
}
switch (this.theme) {
case 'default':
keys.push(
{ text: this.extraKey, theme: ['gray'] },
{ text: 0 },
{ text: this.deleteText, theme: ['gray'], type: 'delete' }
);
break;
case 'custom':
keys.push({ text: 0, theme: ['middle'] }, { text: this.extraKey });
break;
}
return keys;
},
deleteText() {
return this.deleteButtonText || t('delete');
}
},
methods: {
onBlur() {
this.$emit('blur');
},
onClose() {
this.$emit('close');
this.onBlur();
},
onAnimationEnd() {
this.$emit(this.show ? 'show' : 'hide');
},
onPress(text, type) {
if (text === '') {
return;
}
const { value } = this;
if (type === 'delete') {
this.$emit('delete');
this.$emit('update:value', value.slice(0, value.length - 1));
} else if (type === 'close') {
this.onClose();
} else if (value.length < this.maxlength) {
this.$emit('input', text);
this.$emit('update:value', value + text);
}
}
},
render(h) {
const { title, theme, onPress, closeButtonText } = this;
const titleLeftSlot = this.slots('title-left');
const showTitleClose = closeButtonText && theme === 'default';
const showTitle = title || showTitleClose || titleLeftSlot;
const Title = showTitle && (
<div class={[bem('title'), 'van-hairline--top']}>
{titleLeftSlot && <span class={bem('title-left')}>{titleLeftSlot}</span>}
{title && <span>{title}</span>}
{showTitleClose && (
<span role="button" tabindex="0" class={bem('close')} onClick={this.onClose}>
{closeButtonText}
</span>
)}
</div>
);
const Keys = this.keys.map(key => (
<Key
key={key.text}
text={key.text}
type={key.type}
theme={key.theme}
onPress={onPress}
>
{key.type === 'delete' && this.slots('delete')}
</Key>
));
const Sidebar = theme === 'custom' && (
<div class={bem('sidebar')}>
<Key
text={this.deleteText}
type="delete"
theme={DELETE_KEY_THEME}
onPress={onPress}
>
{this.slots('delete')}
</Key>
<Key
text={closeButtonText}
type="close"
theme={CLOSE_KEY_THEME}
onPress={onPress}
/>
</div>
);
return (
<transition name={this.transition ? 'van-slide-up' : ''}>
<div
vShow={this.show}
style={{ zIndex: this.zIndex }}
class={bem([theme, { 'safe-area-inset-bottom': this.safeAreaInsetBottom }])}
onTouchstart={stopPropagation}
onAnimationend={this.onAnimationEnd}
onWebkitAnimationEnd={this.onAnimationEnd}
>
{Title}
<div class={bem('body')}>{Keys}</div>
{Sidebar}
</div>
</transition>
);
}
});
+115
View File
@@ -0,0 +1,115 @@
@import '../style/var';
.van-number-keyboard {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
background-color: @number-keyboard-background-color;
animation-timing-function: ease-out;
user-select: none;
&__title {
position: relative;
height: @number-keyboard-title-height;
color: @number-keyboard-title-color;
font-size: @number-keyboard-title-font-size;
line-height: @number-keyboard-title-height;
text-align: center;
&-left {
position: absolute;
left: 0;
}
}
&__body {
box-sizing: border-box;
}
&__close {
position: absolute;
right: 0;
padding: @number-keyboard-close-padding;
color: @number-keyboard-close-color;
font-size: @number-keyboard-close-font-size;
&:active {
background-color: @number-keyboard-key-active-color;
}
}
&__sidebar {
position: absolute;
top: 0;
right: 0;
width: 25%;
height: @number-keyboard-key-height * 4;
}
&--custom {
.van-number-keyboard__body {
padding-right: 25%;
}
}
&--safe-area-inset-bottom {
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}
}
.van-key {
display: inline-block;
width: 100% / 3;
height: @number-keyboard-key-height;
font-size: @number-keyboard-key-font-size;
font-style: normal;
line-height: @number-keyboard-key-height;
text-align: center;
vertical-align: middle;
&::after {
border-width: 1px 1px 0 0;
}
&--middle {
width: 200% / 3;
}
&--big {
width: 100%;
height: @number-keyboard-key-height * 2;
line-height: @number-keyboard-key-height * 2;
}
&--blue,
&--delete {
font-size: @number-keyboard-delete-font-size;
}
&--blue {
color: @number-keyboard-button-text-color;
background-color: @number-keyboard-button-background-color;
&.van-key--active {
background-color: @number-keyboard-button-background-color;
}
&::after {
border-color: @number-keyboard-button-background-color;
}
&:active {
background-color: darken(@number-keyboard-button-background-color, 10%);
}
}
&--gray {
background-color: @number-keyboard-key-background;
}
&--active {
background-color: @number-keyboard-key-active-color;
}
}
@@ -0,0 +1,32 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`renders demo correctly 1`] = `
<div>
<div><button class="van-button van-button--primary van-button--normal"><span class="van-button__text">
弹出默认键盘
</span></button>
<div class="van-number-keyboard van-number-keyboard--default van-number-keyboard--safe-area-inset-bottom" style="z-index: 100;" name="van-slide-up">
<div class="van-number-keyboard__title van-hairline--top"><span role="button" tabindex="0" class="van-number-keyboard__close">完成</span></div>
<div class="van-number-keyboard__body"><i role="button" tabindex="0" class="van-hairline van-key">1</i><i role="button" tabindex="0" class="van-hairline van-key">2</i><i role="button" tabindex="0" class="van-hairline van-key">3</i><i role="button" tabindex="0" class="van-hairline van-key">4</i><i role="button" tabindex="0" class="van-hairline van-key">5</i><i role="button" tabindex="0" class="van-hairline van-key">6</i><i role="button" tabindex="0" class="van-hairline van-key">7</i><i role="button" tabindex="0" class="van-hairline van-key">8</i><i role="button" tabindex="0" class="van-hairline van-key">9</i><i role="button" tabindex="0" class="van-hairline van-key van-key--gray">.</i><i role="button" tabindex="0" class="van-hairline van-key">0</i><i role="button" tabindex="0" class="van-hairline van-key van-key--gray van-key--delete">删除</i></div>
</div>
</div>
<div><button class="van-button van-button--primary van-button--normal"><span class="van-button__text">
弹出自定义键盘
</span></button>
<div class="van-number-keyboard van-number-keyboard--custom van-number-keyboard--safe-area-inset-bottom" style="z-index: 100; display: none;" name="van-slide-up">
<div class="van-number-keyboard__body"><i role="button" tabindex="0" class="van-hairline van-key">1</i><i role="button" tabindex="0" class="van-hairline van-key">2</i><i role="button" tabindex="0" class="van-hairline van-key">3</i><i role="button" tabindex="0" class="van-hairline van-key">4</i><i role="button" tabindex="0" class="van-hairline van-key">5</i><i role="button" tabindex="0" class="van-hairline van-key">6</i><i role="button" tabindex="0" class="van-hairline van-key">7</i><i role="button" tabindex="0" class="van-hairline van-key">8</i><i role="button" tabindex="0" class="van-hairline van-key">9</i><i role="button" tabindex="0" class="van-hairline van-key van-key--middle">0</i><i role="button" tabindex="0" class="van-hairline van-key">.</i></div>
<div class="van-number-keyboard__sidebar"><i role="button" tabindex="0" class="van-hairline van-key van-key--delete van-key--big van-key--gray van-key--delete">删除</i><i role="button" tabindex="0" class="van-hairline van-key van-key--blue van-key--big van-key--close">完成</i></div>
</div>
</div>
<div>
<div class="van-cell van-cell--clickable van-field">
<div class="van-cell__value van-cell__value--alone">
<div class="van-field__body"><input type="text" placeholder="点此输入" readonly="readonly" class="van-field__control"></div>
</div>
</div>
<div class="van-number-keyboard van-number-keyboard--default van-number-keyboard--safe-area-inset-bottom" style="z-index: 100; display: none;" name="van-slide-up">
<div class="van-number-keyboard__body"><i role="button" tabindex="0" class="van-hairline van-key">1</i><i role="button" tabindex="0" class="van-hairline van-key">2</i><i role="button" tabindex="0" class="van-hairline van-key">3</i><i role="button" tabindex="0" class="van-hairline van-key">4</i><i role="button" tabindex="0" class="van-hairline van-key">5</i><i role="button" tabindex="0" class="van-hairline van-key">6</i><i role="button" tabindex="0" class="van-hairline van-key">7</i><i role="button" tabindex="0" class="van-hairline van-key">8</i><i role="button" tabindex="0" class="van-hairline van-key">9</i><i role="button" tabindex="0" class="van-hairline van-key van-key--gray"></i><i role="button" tabindex="0" class="van-hairline van-key">0</i><i role="button" tabindex="0" class="van-hairline van-key van-key--gray van-key--delete">删除</i></div>
</div>
</div>
</div>
`;
@@ -0,0 +1,27 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`focus on key 1`] = `
<div class="van-number-keyboard van-number-keyboard--default" style="z-index: 100; display: none;" name="van-slide-up">
<div class="van-number-keyboard__body"><i role="button" tabindex="0" class="van-hairline van-key van-key--active">1</i><i role="button" tabindex="0" class="van-hairline van-key">2</i><i role="button" tabindex="0" class="van-hairline van-key">3</i><i role="button" tabindex="0" class="van-hairline van-key">4</i><i role="button" tabindex="0" class="van-hairline van-key">5</i><i role="button" tabindex="0" class="van-hairline van-key">6</i><i role="button" tabindex="0" class="van-hairline van-key">7</i><i role="button" tabindex="0" class="van-hairline van-key">8</i><i role="button" tabindex="0" class="van-hairline van-key">9</i><i role="button" tabindex="0" class="van-hairline van-key van-key--gray"></i><i role="button" tabindex="0" class="van-hairline van-key">0</i><i role="button" tabindex="0" class="van-hairline van-key van-key--gray van-key--delete">删除</i></div>
</div>
`;
exports[`focus on key 2`] = `
<div class="van-number-keyboard van-number-keyboard--default" style="z-index: 100; display: none;" name="van-slide-up">
<div class="van-number-keyboard__body"><i role="button" tabindex="0" class="van-hairline van-key">1</i><i role="button" tabindex="0" class="van-hairline van-key">2</i><i role="button" tabindex="0" class="van-hairline van-key">3</i><i role="button" tabindex="0" class="van-hairline van-key">4</i><i role="button" tabindex="0" class="van-hairline van-key">5</i><i role="button" tabindex="0" class="van-hairline van-key">6</i><i role="button" tabindex="0" class="van-hairline van-key">7</i><i role="button" tabindex="0" class="van-hairline van-key">8</i><i role="button" tabindex="0" class="van-hairline van-key">9</i><i role="button" tabindex="0" class="van-hairline van-key van-key--gray"></i><i role="button" tabindex="0" class="van-hairline van-key">0</i><i role="button" tabindex="0" class="van-hairline van-key van-key--gray van-key--delete">删除</i></div>
</div>
`;
exports[`render title 1`] = `
<div class="van-number-keyboard van-number-keyboard--default" style="z-index: 100; display: none;" name="van-slide-up">
<div class="van-number-keyboard__title van-hairline--top"><span>Title</span><span role="button" tabindex="0" class="van-number-keyboard__close">Close</span></div>
<div class="van-number-keyboard__body"><i role="button" tabindex="0" class="van-hairline van-key">1</i><i role="button" tabindex="0" class="van-hairline van-key">2</i><i role="button" tabindex="0" class="van-hairline van-key">3</i><i role="button" tabindex="0" class="van-hairline van-key">4</i><i role="button" tabindex="0" class="van-hairline van-key">5</i><i role="button" tabindex="0" class="van-hairline van-key">6</i><i role="button" tabindex="0" class="van-hairline van-key">7</i><i role="button" tabindex="0" class="van-hairline van-key">8</i><i role="button" tabindex="0" class="van-hairline van-key">9</i><i role="button" tabindex="0" class="van-hairline van-key van-key--gray"></i><i role="button" tabindex="0" class="van-hairline van-key">0</i><i role="button" tabindex="0" class="van-hairline van-key van-key--gray van-key--delete">删除</i></div>
</div>
`;
exports[`title-left slot 1`] = `
<div class="van-number-keyboard van-number-keyboard--default" style="z-index: 100; display: none;" name="van-slide-up">
<div class="van-number-keyboard__title van-hairline--top"><span class="van-number-keyboard__title-left">Custom Title Left</span></div>
<div class="van-number-keyboard__body"><i role="button" tabindex="0" class="van-hairline van-key">1</i><i role="button" tabindex="0" class="van-hairline van-key">2</i><i role="button" tabindex="0" class="van-hairline van-key">3</i><i role="button" tabindex="0" class="van-hairline van-key">4</i><i role="button" tabindex="0" class="van-hairline van-key">5</i><i role="button" tabindex="0" class="van-hairline van-key">6</i><i role="button" tabindex="0" class="van-hairline van-key">7</i><i role="button" tabindex="0" class="van-hairline van-key">8</i><i role="button" tabindex="0" class="van-hairline van-key">9</i><i role="button" tabindex="0" class="van-hairline van-key van-key--gray"></i><i role="button" tabindex="0" class="van-hairline van-key">0</i><i role="button" tabindex="0" class="van-hairline van-key van-key--gray van-key--delete">删除</i></div>
</div>
`;
+4
View File
@@ -0,0 +1,4 @@
import Demo from '../demo';
import demoTest from '../../../test/demo-test';
demoTest(Demo);
+173
View File
@@ -0,0 +1,173 @@
import NumberKeyboard from '..';
import { mount, trigger } from '../../../test/utils';
test('click number key', () => {
const wrapper = mount(NumberKeyboard, {
propsData: {
theme: 'custom',
closeButtonText: 'close'
}
});
wrapper
.findAll('.van-key')
.at(0)
.trigger('click');
expect(wrapper.emitted('input')[0][0]).toEqual(1);
wrapper.destroy();
});
it('click delete key', () => {
const wrapper = mount(NumberKeyboard);
wrapper
.findAll('.van-key')
.at(11)
.trigger('click');
expect(wrapper.emitted('delete')).toBeTruthy();
});
it('click empty key', () => {
const wrapper = mount(NumberKeyboard);
wrapper
.findAll('.van-key')
.at(9)
.trigger('click');
expect(wrapper.emitted('input')).toBeFalsy();
});
test('click close button', () => {
const wrapper = mount(NumberKeyboard, {
propsData: {
theme: 'custom',
closeButtonText: 'close'
}
});
wrapper
.findAll('.van-key')
.at(12)
.trigger('click');
expect(wrapper.emitted('close')).toBeTruthy();
});
test('listen to show/hide event when has transtion', () => {
const wrapper = mount(NumberKeyboard);
wrapper.vm.show = true;
wrapper.trigger('animationend');
wrapper.vm.show = false;
wrapper.trigger('animationend');
expect(wrapper.emitted('show')).toBeTruthy();
expect(wrapper.emitted('hide')).toBeTruthy();
});
test('listen to show event when no transtion', () => {
const wrapper = mount(NumberKeyboard, {
propsData: {
transition: false
}
});
wrapper.vm.show = true;
wrapper.vm.show = false;
expect(wrapper.emitted('show')).toBeTruthy();
expect(wrapper.emitted('hide')).toBeTruthy();
});
test('render title', () => {
const wrapper = mount(NumberKeyboard, {
propsData: {
title: 'Title',
closeButtonText: 'Close'
}
});
expect(wrapper).toMatchSnapshot();
});
test('title-left slot', () => {
const wrapper = mount(NumberKeyboard, {
scopedSlots: {
'title-left': () => 'Custom Title Left'
}
});
expect(wrapper).toMatchSnapshot();
});
test('hideOnClickOutside', () => {
const wrapper = mount(NumberKeyboard, {
propsData: {
show: true
}
});
trigger(document.body, 'touchstart');
expect(wrapper.emitted('blur')).toBeTruthy();
});
test('disable hideOnClickOutside', () => {
const wrapper = mount(NumberKeyboard, {
propsData: {
show: true,
hideOnClickOutside: false
}
});
trigger(document.body, 'touchstart');
expect(wrapper.emitted('blur')).toBeFalsy();
});
test('focus on key', () => {
const wrapper = mount(NumberKeyboard);
const key = wrapper.find('.van-key');
trigger(key, 'touchstart');
expect(wrapper).toMatchSnapshot();
trigger(key, 'touchend');
expect(wrapper).toMatchSnapshot();
});
test('bind value', () => {
const wrapper = mount(NumberKeyboard, {
propsData: {
value: ''
},
listeners: {
'update:value': value => {
wrapper.setProps({ value });
}
}
});
const keys = wrapper.findAll('.van-key');
keys.at(0).trigger('click');
keys.at(1).trigger('click');
expect(wrapper.vm.value).toEqual('12');
keys.at(11).trigger('click');
expect(wrapper.vm.value).toEqual('1');
});
test('maxlength', () => {
const onInput = jest.fn();
const wrapper = mount(NumberKeyboard, {
propsData: {
value: '',
maxlength: 1
},
listeners: {
input: onInput,
'update:value': value => {
wrapper.setProps({ value });
}
}
});
const keys = wrapper.findAll('.van-key');
keys.at(0).trigger('click');
keys.at(1).trigger('click');
expect(wrapper.vm.value).toEqual('1');
expect(onInput).toHaveBeenCalledTimes(1);
});
+130
View File
@@ -0,0 +1,130 @@
# NumberKeyboard 数字键盘
### 引入
``` javascript
import { NumberKeyboard } from 'vant';
Vue.use(NumberKeyboard);
```
## 代码演示
### 默认样式
```html
<van-button @touchstart.stop="show = true">
弹出默认键盘
</van-button>
<van-number-keyboard
:show="show"
extra-key="."
close-button-text="完成"
@blur="show = false"
@input="onInput"
@delete="onDelete"
/>
```
```javascript
export default {
data() {
return {
show: true
}
},
methods: {
onInput(value) {
Toast(value);
},
onDelete() {
Toast('删除');
}
}
}
```
### 自定义样式
```html
<van-number-keyboard
:show="show"
theme="custom"
extra-key="."
close-button-text="完成"
@blur="show = false"
@input="onInput"
@delete="onDelete"
/>
```
### 双向绑定
可以通过`v-model`绑定键盘当前输入值
```html
<van-field
readonly
clickable
:value="value"
@touchstart.native.stop="show = true"
/>
<van-number-keyboard
v-model="value"
:show="show"
:maxlength="6"
@blur="show = false"
/>
```
```javascript
export default {
data() {
return {
show: false,
value: ''
}
}
}
```
## API
### Props
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|------|------|------|------|------|
| v-model | 当前输入值 | `String` | - | 2.0.2 |
| show | 是否显示键盘 | `Boolean` | - | - |
| theme | 样式风格,可选值为 `default` `custom` | `String` | `default` | - |
| title | 键盘标题 | `String` | - | - |
| maxlength | 输入值最大长度 | `Number | String` | - | 2.0.2 |
| transition | 是否开启过场动画 | `Boolean` | `true` | - |
| z-index | 键盘 z-index | `Number` | `100` | - |
| extra-key | 左下角按键内容 | `String` | `''` | - |
| close-button-text | 关闭按钮文字,空则不展示 | `String` | `-` | - |
| delete-button-text | 删除按钮文字 | `String` | `删除` | - |
| show-delete-key | 是否展示删除按钮 | `Boolean` | `true` | - |
| hide-on-click-outside | 点击外部时是否收起键盘 | `Boolean` | `true` | - |
| safe-area-inset-bottom | 是否开启 iPhone X 底部安全区适配,需要在 `viewport` meta 标签中设置 `viewport-fit=cover` | `Boolean` | `false` | 1.6.15 |
### Events
| 事件名 | 说明 | 回调参数 |
|------|------|------|
| input | 点击按键时触发 | key: 按键内容 |
| delete | 点击删除键时触发 | - |
| close | 点击关闭按钮时触发 | - |
| blur | 点击关闭按钮或非键盘区域时触发 | - |
| show | 键盘完全弹出时触发 | - |
| hide | 键盘完全收起时触发 | - |
### Slots
| 名称 | 说明 |
|------|------|
| delete | 自定义删除按钮内容 |
| title-left | 自定义标题栏左侧内容 |