diff --git a/src/field/README.md b/src/field/README.md
index 9b85daf92..3068c69b3 100644
--- a/src/field/README.md
+++ b/src/field/README.md
@@ -37,12 +37,10 @@ Use `type` prop to custom different type fields.
```html
-
-
-
-
-
+
+
+
```
```js
@@ -50,8 +48,9 @@ export default {
data() {
return {
tel: '',
+ text: '',
+ digit: '',
number: '',
- username: '',
password: ''
};
}
@@ -182,7 +181,7 @@ Textarea Field can be auto resize when has `autosize` prop
|------|------|------|------|------|
| value | Field value | *string \| number* | - | - |
| label | Field label | *string* | - | - |
-| type | Input type, can be set to `tel` `number`
`textarea` `password` | *string* | `text` | - |
+| type | Input type, can be set to `tel` `digit`
`number` `textarea` `password` | *string* | `text` | - |
| size | Size,can be set to `large` | *string* | - | - |
| maxlength | Max length of value | *string \| number* | - | - |
| placeholder | Placeholder | *string* | - | - |
diff --git a/src/field/README.zh-CN.md b/src/field/README.zh-CN.md
index 0858ee34e..d5d084ec5 100644
--- a/src/field/README.zh-CN.md
+++ b/src/field/README.zh-CN.md
@@ -41,17 +41,16 @@ export default {
根据`type`属性定义不同类型的输入框,默认值为`text`
```html
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
```
```js
@@ -60,6 +59,7 @@ export default {
return {
tel: '',
text: '',
+ digit: '',
number: '',
password: ''
};
@@ -67,6 +67,8 @@ export default {
}
```
+> Tips: digit 类型从 2.4.2 版本开始支持
+
### 禁用输入框
通过`readonly`将输入框设置为只读状态,通过`disabled`将输入框设置为禁用状态
@@ -197,7 +199,7 @@ export default {
|------|------|------|------|------|
| label | 输入框左侧文本 | *string* | - | - |
| value | 当前输入的值 | *string \| number* | - | - |
-| type | 输入框类型, 可选值为 `tel` `number`
`textarea` `password` 等 | *string* | `text` | - |
+| type | 输入框类型, 可选值为 `tel` `digit`
`number` `textarea` `password` 等 | *string* | `text` | - |
| size | 大小,可选值为 `large` | *string* | - | - |
| maxlength | 输入的最大字符数 | *string \| number* | - | - |
| placeholder | 占位提示文字 | *string* | - | - |
diff --git a/src/field/demo/index.vue b/src/field/demo/index.vue
index 8eae764ab..1993c18ac 100644
--- a/src/field/demo/index.vue
+++ b/src/field/demo/index.vue
@@ -15,10 +15,17 @@
/>
+
+
@@ -141,6 +148,7 @@ export default {
sms: '短信验证码',
tel: '手机号',
text: '文本',
+ digit: '整数',
phone: '手机号',
number: '数字',
message: '留言',
@@ -151,7 +159,8 @@ export default {
textareaAutosize: '高度自适应',
smsPlaceholder: '请输入短信验证码',
textPlaceholder: '请输入文本',
- numberPlaceholder: '请输入数字',
+ digitPlaceholder: '请输入整数',
+ numberPlaceholder: '请输入数字(支持小数)',
phonePlaceholder: '请输入手机号',
messagePlaceholder: '请输入留言',
inputReadonly: '输入框只读',
@@ -166,6 +175,7 @@ export default {
sms: 'SMS',
tel: 'Tel',
text: 'Text',
+ digit: 'Digit',
phone: 'Phone',
number: 'Number',
message: 'Message',
@@ -176,6 +186,7 @@ export default {
textareaAutosize: 'Auto Resize',
smsPlaceholder: 'SMS',
textPlaceholder: 'Text',
+ digitPlaceholder: 'Digit',
phonePlaceholder: 'Phone',
numberPlaceholder: 'Number',
messagePlaceholder: 'Message',
@@ -190,6 +201,7 @@ export default {
sms: '',
text: '',
value: '',
+ digit: '',
number: '',
icon1: '',
icon2: '123',
diff --git a/src/field/index.js b/src/field/index.js
index 92d2e264e..52eb8263a 100644
--- a/src/field/index.js
+++ b/src/field/index.js
@@ -3,20 +3,12 @@ import Cell from '../cell';
import { cellProps } from '../cell/shared';
import { preventDefault } from '../utils/dom/event';
import { resetScroll } from '../utils/dom/reset-scroll';
+import { isIOS } from '../utils/validate/system';
+import { formatNumber } from './utils';
import { createNamespace, isObj, isDef, addUnit } from '../utils';
const [createComponent, bem] = createNamespace('field');
-function formatNumber(value) {
- const dotIndex = value.indexOf('.');
-
- if (dotIndex > -1) {
- value = value.slice(0, dotIndex + 1) + value.slice(dotIndex).replace(/\./g, '');
- }
-
- return value.replace(/[^0-9.]/g, '');
-}
-
export default createComponent({
inheritAttrs: false,
@@ -121,10 +113,11 @@ export default createComponent({
target.value = value;
}
- if (this.type === 'number') {
+ if (this.type === 'number' || this.type === 'digit') {
const originValue = value;
+ const allowDot = this.type === 'number';
- value = formatNumber(value);
+ value = formatNumber(value, allowDot);
if (value !== originValue) {
target.value = value;
@@ -213,6 +206,7 @@ export default createComponent({
},
genInput() {
+ const { type } = this;
const inputSlot = this.slots('input');
if (inputSlot) {
@@ -239,18 +233,34 @@ export default createComponent({
]
};
- if (this.type === 'textarea') {
+ if (type === 'textarea') {
return ;
}
+ let inputType = type;
+
// type="number" is weired in iOS
- const inputType = this.type === 'number' ? 'text' : this.type;
+ if (type === 'number') {
+ inputType = 'text';
+ }
+
+ if (type === 'digit') {
+ // set pattern to show number keyboard in iOS
+ if (isIOS()) {
+ inputType = 'number';
+ inputProps.attrs.pattern = '\\d*';
+ // cannot prevent dot when type is number in Android, so use tel
+ } else {
+ inputType = 'tel';
+ }
+ }
return ;
},
genLeftIcon() {
const showLeftIcon = this.slots('left-icon') || this.leftIcon;
+
if (showLeftIcon) {
return (
@@ -263,6 +273,7 @@ export default createComponent({
genRightIcon() {
const { slots } = this;
const showRightIcon = slots('right-icon') || this.rightIcon;
+
if (showRightIcon) {
return (
@@ -289,6 +300,7 @@ export default createComponent({
const scopedSlots = {
icon: this.genLeftIcon
};
+
if (slots('label')) {
scopedSlots.title = () => slots('label');
}
diff --git a/src/field/test/__snapshots__/demo.spec.js.snap b/src/field/test/__snapshots__/demo.spec.js.snap
index 2dd8a775f..72fcb3367 100644
--- a/src/field/test/__snapshots__/demo.spec.js.snap
+++ b/src/field/test/__snapshots__/demo.spec.js.snap
@@ -20,21 +20,27 @@ exports[`renders demo correctly 1`] = `
+
diff --git a/src/field/test/index.spec.js b/src/field/test/index.spec.js
index 1ff62befc..acd91cb4c 100644
--- a/src/field/test/index.spec.js
+++ b/src/field/test/index.spec.js
@@ -56,6 +56,29 @@ test('number type', () => {
expect(wrapper.emitted('input')[2][0]).toEqual('123');
});
+test('digit type', () => {
+ const wrapper = mount(Field, {
+ propsData: {
+ value: '',
+ type: 'digit'
+ }
+ });
+
+ const input = wrapper.find('input');
+
+ input.element.value = '1';
+ input.trigger('input');
+ expect(wrapper.emitted('input')[0][0]).toEqual('1');
+
+ input.element.value = '1.';
+ input.trigger('input');
+ expect(wrapper.emitted('input')[1][0]).toEqual('1');
+
+ input.element.value = '123abc';
+ input.trigger('input');
+ expect(wrapper.emitted('input')[2][0]).toEqual('123');
+});
+
test('render textarea', async () => {
const wrapper = mount(Field, {
propsData: {
diff --git a/src/field/utils.ts b/src/field/utils.ts
new file mode 100644
index 000000000..d37981cd0
--- /dev/null
+++ b/src/field/utils.ts
@@ -0,0 +1,14 @@
+export function formatNumber(value: string, allowDot: boolean) {
+ if (allowDot) {
+ const dotIndex = value.indexOf('.');
+
+ if (dotIndex > -1) {
+ value =
+ value.slice(0, dotIndex + 1) + value.slice(dotIndex).replace(/\./g, '');
+ }
+ }
+
+ const regExp = allowDot ? /[^0-9.]/g : /\D/g;
+
+ return value.replace(regExp, '');
+}