Keyboard
17:06Description
A custom keyboard that slides up from the bottom with three built-in layouts: number, ID card (card) and license plate (car). The top toolbar provides cancel and confirm; both collapse the keyboard before emitting confirm / cancel. Supports closing by tapping the mask, bottom safe-area adaptation, shuffled keys and custom toolbar text.
Compatibility
| Platform | Support |
|---|---|
| App | ✅ Supported |
| H5 | ✅ Supported |
| WeChat Mini Program | ✅ Supported |
Examples
Number Keyboard (mode="number")
The default number keyboard; dot-enabled controls the decimal point; tapping a key emits change and backspace fires on deletion.
View source
<template>
<view class="keyboard-display">
<text>{{ inputValue.length > 0 ? inputValue : '请点击按钮唤起键盘' }}</text>
</view>
<ux-button type="primary" shape="round" text="打开数字键盘" @click="open" />
<ux-keyboard v-model="show" mode="number" @change="onChange" @backspace="onBackspace" @confirm="onConfirm" @cancel="onCancel" />
<ux-toast ref="toastRef" />
</template>
<script setup lang="uts">
const toastRef = ref<any>();
const show = ref(false);
const inputValue = ref('');
const open = () => {
show.value = true;
};
const keyToString = (key: string | number): string => {
return typeof key == 'number' ? (key as number).toString() : key as string;
};
const onChange = (key: string | number) => {
inputValue.value = inputValue.value + keyToString(key);
};
const onBackspace = () => {
inputValue.value = inputValue.length > 0 ? inputValue.substring(0, inputValue.length - 1) : '';
};
const onConfirm = () => {
toastRef.value?.show?.({ title: '输入完成:' + inputValue.value, type: 'success', duration: 2000 });
};
const onCancel = () => {
toastRef.value?.show?.({ title: '已取消输入', type: 'info', duration: 2000 });
};
</script>
<style scoped>
.keyboard-display {
display: flex;
flex-direction: row;
align-items: center;
padding: 12px 15px;
border-radius: 6px;
background-color: #f8f8f8;
margin-bottom: 12px;
}
</style>ID Card Keyboard (mode="card")
Adds an X key on top of the number layout, suitable for ID card input.
View source
<template>
<ux-button type="primary" shape="round" text="打开身份证键盘" @click="open" />
<ux-keyboard v-model="show" mode="card" @change="onChange" @confirm="onConfirm" />
<ux-toast ref="toastRef" />
</template>
<script setup lang="uts">
const toastRef = ref<any>();
const show = ref(false);
const inputValue = ref('');
const open = () => {
show.value = true;
};
const onChange = (key: string | number) => {
inputValue.value = inputValue.value + (typeof key == 'number' ? (key as number).toString() : key as string);
};
const onConfirm = () => {
toastRef.value?.show?.({ title: '输入完成:' + inputValue.value, type: 'success', duration: 2000 });
};
</script>Plate Keyboard (mode="car")
A mixed layout of province abbreviations, letters and digits, suitable for license plates.
View source
<template>
<ux-button type="primary" shape="round" text="打开车牌号键盘" @click="open" />
<ux-keyboard v-model="show" mode="car" @change="onChange" @confirm="onConfirm" />
<ux-toast ref="toastRef" />
</template>
<script setup lang="uts">
const toastRef = ref<any>();
const show = ref(false);
const inputValue = ref('');
const open = () => {
show.value = true;
};
const onChange = (key: string | number) => {
inputValue.value = inputValue.value + (typeof key == 'number' ? (key as number).toString() : key as string);
};
const onConfirm = () => {
toastRef.value?.show?.({ title: '输入完成:' + inputValue.value, type: 'success', duration: 2000 });
};
</script>Custom Labels & Keys
tips / cancel-text / confirm-text customize the toolbar labels; random shuffles the keys.
View source
<template>
<ux-button type="warning" shape="round" text="打乱按键并定制文案" @click="open" />
<ux-keyboard
v-model="show"
mode="number"
:random="true"
tips="安全输入"
cancel-text="重输"
confirm-text="确定"
@change="onChange"
@backspace="onBackspace"
@confirm="onConfirm"
@cancel="onCancel"
/>
<ux-toast ref="toastRef" />
</template>
<script setup lang="uts">
const toastRef = ref<any>();
const show = ref(false);
const inputValue = ref('');
const open = () => {
show.value = true;
};
const onChange = (key: string | number) => {
inputValue.value = inputValue.value + (typeof key == 'number' ? (key as number).toString() : key as string);
};
const onBackspace = () => {
inputValue.value = inputValue.length > 0 ? inputValue.substring(0, inputValue.length - 1) : '';
};
const onConfirm = () => {
toastRef.value?.show?.({ title: '输入完成:' + inputValue.value, type: 'success', duration: 2000 });
};
const onCancel = () => {
toastRef.value?.show?.({ title: '已取消输入', type: 'info', duration: 2000 });
};
</script>Toolbar & Mask Switches
tooltip hides the whole toolbar; show-tips / cancel-btn / confirm-btn control each element; mask / mask-close-able / dot-enabled control the mask and keys.
View source
<template>
<view class="keyboard-row">
<ux-button custom-class="keyboard-item" type="success" size="small" shape="round" text="无工具条" @click="openBoard('noTooltip')" />
<ux-button custom-class="keyboard-item" type="success" size="small" shape="round" text="隐藏提示与按钮" @click="openBoard('noTips')" />
<ux-button custom-class="keyboard-item" type="success" size="small" shape="round" text="无遮罩无小数点" @click="openBoard('noMask')" />
</view>
<ux-keyboard
v-model="show"
mode="number"
:tooltip="tooltip"
:show-tips="showTips"
:cancel-btn="cancelBtn"
:confirm-btn="confirmBtn"
:dot-enabled="dotEnabled"
:mask="mask"
/>
</template>
<script setup lang="uts">
const show = ref(false);
const tooltip = ref(true);
const showTips = ref(true);
const cancelBtn = ref(true);
const confirmBtn = ref(true);
const dotEnabled = ref(true);
const mask = ref(true);
const openBoard = (kind: string) => {
if (kind == 'noTooltip') {
tooltip.value = false;
} else if (kind == 'noTips') {
showTips.value = false;
cancelBtn.value = false;
confirmBtn.value = false;
} else {
dotEnabled.value = false;
mask.value = false;
}
show.value = true;
};
</script>
<style scoped>
.keyboard-row {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.keyboard-item {
margin-right: 8px;
margin-bottom: 8px;
}
</style>Safe Area & z-index
safe-area-inset-bottom adapts to the bottom safe area; z-index customizes the popup level.
View source
<template>
<ux-button type="info" shape="round" text="遮罩不可关 + 自定义层级" @click="open" />
<ux-keyboard
v-model="show"
mode="number"
:mask-close-able="false"
:safe-area-inset-bottom="true"
:z-index="9999"
/>
</template>
<script setup lang="uts">
const show = ref(false);
const open = () => {
show.value = true;
};
</script>API
Props
| Property | Description | Type | Default | Version |
|---|---|---|---|---|
mode | Keyboard type: number / card / car | String | 'number' | - |
dotEnabled | Whether to show the "." key; applies to number and card modes | Boolean | true | - |
tooltip | Whether to show the top toolbar | Boolean | true | - |
showTips | Whether to show the hint in the middle of the toolbar | Boolean | true | - |
tips | Hint text; falls back to the localized default for the current mode | String | '' | - |
cancelBtn | Whether to show the cancel button on the left of the toolbar | Boolean | true | - |
confirmBtn | Whether to show the confirm button on the right of the toolbar | Boolean | true | - |
random | Whether to shuffle key order | Boolean | false | - |
safeAreaInsetBottom | Whether to enable bottom safe-area adaptation | Boolean | true | - |
maskCloseAble | Whether tapping the mask closes the keyboard | Boolean | true | - |
modelValue | Controls keyboard visibility via v-model | Boolean | false | - |
mask | Whether to show the mask | Boolean | true | - |
zIndex | Popup z-index; falls back to the global popup layer | String|Number | - | - |
cancelText | Cancel button text; falls back to the localized default | String | '' | - |
confirmText | Confirm button text; falls back to the localized default | String | '' | - |
customClass | Custom class for the root node | String | '' | - |
customStyle | Custom style for the root node | Object|String | - | - |
Events
| Event | Description | Params | Version |
|---|---|---|---|
change | Emitted when a key is tapped, carrying the key value | value: string | number | - |
confirm | Emitted when the toolbar confirm button is tapped | - | - |
cancel | Emitted when the toolbar cancel button is tapped | - | - |
backspace | Emitted when backspace is tapped; long-pressing fires it repeatedly | - | - |
Slots
| Slot | Description | Version |
|---|---|---|
default | Custom content above the toolbar at the top of the popup | - |
Notes
- Tapping confirm or cancel first writes
modelValue=falseto collapse the keyboard, then emits the matching event. Closing via the mask only emitsupdate:modelValueand never firescancel, so track the close source yourself if the difference matters. dotEnabledonly affectsnumber/card; thecarlayout is defined by the plate keyboard and ignores it.- When
tips/cancelText/confirmTextare omitted, localized text is resolved frommodeand the current locale and follows language changes; explicit values stay fixed. - The default slot renders before the toolbar, so visually it sits above it — a good place for a title or extra hint.
- An empty
zIndexfalls back to the global popup layer. Mask closing is controlled bymaskCloseAble; withmask=falsethere is neither a mask nor tap-to-close. - Continuous backspace on long press is implemented by the inner number/plate keyboard; this component only forwards
backspace.