mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-05-24 15:39:15 +08:00
feat(Field): add formatter prop (#5534)
This commit is contained in:
parent
47c24e192c
commit
9452444a7d
@ -126,17 +126,43 @@ Use `error` or `error-message` to show error info
|
|||||||
Use button slot to insert button
|
Use button slot to insert button
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<van-cell-group>
|
<van-field
|
||||||
<van-field
|
|
||||||
v-model="sms"
|
v-model="sms"
|
||||||
center
|
center
|
||||||
clearable
|
clearable
|
||||||
label="SMS"
|
label="SMS"
|
||||||
placeholder="SMS"
|
placeholder="SMS"
|
||||||
>
|
>
|
||||||
<van-button slot="button" size="small" type="primary">Send SMS</van-button>
|
<van-button slot="button" size="small" type="primary">Send SMS</van-button>
|
||||||
</van-field>
|
</van-field>
|
||||||
</van-cell-group>
|
```
|
||||||
|
|
||||||
|
### Format Value
|
||||||
|
|
||||||
|
Use `formatter` prop to format the input value
|
||||||
|
|
||||||
|
```html
|
||||||
|
<van-field
|
||||||
|
v-model="value"
|
||||||
|
label="Text"
|
||||||
|
:formatter="formatter"
|
||||||
|
placeholder="Format Value"
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
value: ''
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
formatter(value) {
|
||||||
|
return value.replace(/\d/g, '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Auto Resize
|
### Auto Resize
|
||||||
@ -144,33 +170,29 @@ Use button slot to insert button
|
|||||||
Textarea Field can be auto resize when has `autosize` prop
|
Textarea Field can be auto resize when has `autosize` prop
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<van-cell-group>
|
<van-field
|
||||||
<van-field
|
|
||||||
v-model="message"
|
v-model="message"
|
||||||
label="Message"
|
label="Message"
|
||||||
type="textarea"
|
type="textarea"
|
||||||
placeholder="Message"
|
placeholder="Message"
|
||||||
rows="1"
|
rows="1"
|
||||||
autosize
|
autosize
|
||||||
/>
|
/>
|
||||||
</van-cell-group>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Show Word Limit
|
### Show Word Limit
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<van-cell-group>
|
<van-field
|
||||||
<van-field
|
|
||||||
v-model="message"
|
v-model="message"
|
||||||
rows="2"
|
rows="2"
|
||||||
autosize
|
autosize
|
||||||
label="留言"
|
label="Message"
|
||||||
type="textarea"
|
type="textarea"
|
||||||
maxlength="50"
|
maxlength="50"
|
||||||
placeholder="请输入留言"
|
placeholder="Message"
|
||||||
show-word-limit
|
show-word-limit
|
||||||
/>
|
/>
|
||||||
</van-cell-group>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## API
|
## API
|
||||||
@ -195,6 +217,7 @@ Textarea Field can be auto resize when has `autosize` prop
|
|||||||
| autofocus | Whether to auto focus, unsupported in iOS | *boolean* | `false` | - |
|
| autofocus | Whether to auto focus, unsupported in iOS | *boolean* | `false` | - |
|
||||||
| show-word-limit | Whether to show word limit, need to set the `maxlength` prop | *boolean* | `false` | 2.2.8 |
|
| show-word-limit | Whether to show word limit, need to set the `maxlength` prop | *boolean* | `false` | 2.2.8 |
|
||||||
| error | Whether to show error info | *boolean* | `false` | - |
|
| error | Whether to show error info | *boolean* | `false` | - |
|
||||||
|
| formatter | Input value formatter | *Function* | - | 2.4.2 |
|
||||||
| arrow-direction | Can be set to `left` `up` `down` | *string* | - | 2.0.4 |
|
| arrow-direction | Can be set to `left` `up` `down` | *string* | - | 2.0.4 |
|
||||||
| error-message | Error message | *string* | `''` | - |
|
| error-message | Error message | *string* | `''` | - |
|
||||||
| label-class | Label className | *any* | - | - |
|
| label-class | Label className | *any* | - | - |
|
||||||
|
@ -142,17 +142,44 @@ export default {
|
|||||||
通过 button 插槽可以在输入框尾部插入按钮
|
通过 button 插槽可以在输入框尾部插入按钮
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<van-cell-group>
|
<van-field
|
||||||
<van-field
|
|
||||||
v-model="sms"
|
v-model="sms"
|
||||||
center
|
center
|
||||||
clearable
|
clearable
|
||||||
label="短信验证码"
|
label="短信验证码"
|
||||||
placeholder="请输入短信验证码"
|
placeholder="请输入短信验证码"
|
||||||
>
|
>
|
||||||
<van-button slot="button" size="small" type="primary">发送验证码</van-button>
|
<van-button slot="button" size="small" type="primary">发送验证码</van-button>
|
||||||
</van-field>
|
</van-field>
|
||||||
</van-cell-group>
|
```
|
||||||
|
|
||||||
|
### 格式化输入内容
|
||||||
|
|
||||||
|
通过`formatter`属性可以对输入的内容进行格式化
|
||||||
|
|
||||||
|
```html
|
||||||
|
<van-field
|
||||||
|
v-model="value"
|
||||||
|
label="文本"
|
||||||
|
:formatter="formatter"
|
||||||
|
placeholder="格式化输入内容"
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
value: ''
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
formatter(value) {
|
||||||
|
// 过滤输入的数字
|
||||||
|
return value.replace(/\d/g, '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 高度自适应
|
### 高度自适应
|
||||||
@ -160,16 +187,14 @@ export default {
|
|||||||
对于 textarea,可以通过`autosize`属性设置高度自适应
|
对于 textarea,可以通过`autosize`属性设置高度自适应
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<van-cell-group>
|
<van-field
|
||||||
<van-field
|
|
||||||
v-model="message"
|
v-model="message"
|
||||||
rows="1"
|
rows="1"
|
||||||
autosize
|
autosize
|
||||||
label="留言"
|
label="留言"
|
||||||
type="textarea"
|
type="textarea"
|
||||||
placeholder="请输入留言"
|
placeholder="请输入留言"
|
||||||
/>
|
/>
|
||||||
</van-cell-group>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 显示字数统计
|
### 显示字数统计
|
||||||
@ -177,8 +202,7 @@ export default {
|
|||||||
设置`maxlength`和`show-word-limit`属性后会在底部显示字数统计
|
设置`maxlength`和`show-word-limit`属性后会在底部显示字数统计
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<van-cell-group>
|
<van-field
|
||||||
<van-field
|
|
||||||
v-model="message"
|
v-model="message"
|
||||||
rows="2"
|
rows="2"
|
||||||
autosize
|
autosize
|
||||||
@ -187,8 +211,7 @@ export default {
|
|||||||
maxlength="50"
|
maxlength="50"
|
||||||
placeholder="请输入留言"
|
placeholder="请输入留言"
|
||||||
show-word-limit
|
show-word-limit
|
||||||
/>
|
/>
|
||||||
</van-cell-group>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## API
|
## API
|
||||||
@ -213,6 +236,7 @@ export default {
|
|||||||
| autofocus | 是否自动聚焦,iOS 系统不支持该属性 | *boolean* | `false` | - |
|
| autofocus | 是否自动聚焦,iOS 系统不支持该属性 | *boolean* | `false` | - |
|
||||||
| show-word-limit | 是否显示字数统计,需要设置`maxlength`属性 | *boolean* | `false` | 2.2.8 |
|
| show-word-limit | 是否显示字数统计,需要设置`maxlength`属性 | *boolean* | `false` | 2.2.8 |
|
||||||
| error | 是否将输入内容标红 | *boolean* | `false` | - |
|
| error | 是否将输入内容标红 | *boolean* | `false` | - |
|
||||||
|
| formatter | 输入内容格式化函数 | *Function* | - | 2.4.2 |
|
||||||
| arrow-direction | 箭头方向,可选值为 `left` `up` `down` | *string* | - | 2.0.4 |
|
| arrow-direction | 箭头方向,可选值为 `left` `up` `down` | *string* | - | 2.0.4 |
|
||||||
| error-message | 底部错误提示文案,为空时不展示 | *string* | `''` | -
|
| error-message | 底部错误提示文案,为空时不展示 | *string* | `''` | -
|
||||||
| label-class | 左侧文本额外类名 | *any* | - | - |
|
| label-class | 左侧文本额外类名 | *any* | - | - |
|
||||||
@ -220,7 +244,7 @@ export default {
|
|||||||
| label-align | 左侧文本对齐方式,可选值为 `center` `right` | *string* | `left` | - |
|
| label-align | 左侧文本对齐方式,可选值为 `center` `right` | *string* | `left` | - |
|
||||||
| input-align | 输入框内容对齐方式,可选值为 `center` `right` | *string* | `left` | - |
|
| input-align | 输入框内容对齐方式,可选值为 `center` `right` | *string* | `left` | - |
|
||||||
| error-message-align | 错误提示文案对齐方式,可选值为 `center` `right` | *string* | `left` | - |
|
| error-message-align | 错误提示文案对齐方式,可选值为 `center` `right` | *string* | `left` | - |
|
||||||
| autosize | 自适应内容高度,只对 textarea 有效,可传入对象,<br>如 { maxHeight: 100, minHeight: 50 },单位为`px` | *boolean \| object* | `false` | - |
|
| autosize | 是否自适应内容高度,只对 textarea 有效,<br>可传入对象,如 { maxHeight: 100, minHeight: 50 },<br>单位为`px` | *boolean \| object* | `false` | - |
|
||||||
| left-icon | 左侧图标名称或图片链接,可选值见 [Icon 组件](#/zh-CN/icon) | *string* | - | - |
|
| left-icon | 左侧图标名称或图片链接,可选值见 [Icon 组件](#/zh-CN/icon) | *string* | - | - |
|
||||||
| right-icon | 右侧图标名称或图片链接,可选值见 [Icon 组件](#/zh-CN/icon) | *string* | - | - |
|
| right-icon | 右侧图标名称或图片链接,可选值见 [Icon 组件](#/zh-CN/icon) | *string* | - | - |
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
</van-cell-group>
|
</van-cell-group>
|
||||||
</demo-block>
|
</demo-block>
|
||||||
|
|
||||||
<demo-block :title="$t('title2')">
|
<demo-block :title="$t('customType')">
|
||||||
<van-cell-group>
|
<van-cell-group>
|
||||||
<van-field
|
<van-field
|
||||||
v-model="text"
|
v-model="text"
|
||||||
@ -44,7 +44,7 @@
|
|||||||
</van-cell-group>
|
</van-cell-group>
|
||||||
</demo-block>
|
</demo-block>
|
||||||
|
|
||||||
<demo-block :title="$t('title3')">
|
<demo-block :title="$t('disabled')">
|
||||||
<van-cell-group>
|
<van-cell-group>
|
||||||
<van-field :value="$t('inputReadonly')" :label="$t('text')" readonly />
|
<van-field :value="$t('inputReadonly')" :label="$t('text')" readonly />
|
||||||
<van-field :value="$t('inputDisabled')" :label="$t('text')" disabled />
|
<van-field :value="$t('inputDisabled')" :label="$t('text')" disabled />
|
||||||
@ -70,7 +70,7 @@
|
|||||||
</van-cell-group>
|
</van-cell-group>
|
||||||
</demo-block>
|
</demo-block>
|
||||||
|
|
||||||
<demo-block :title="$t('title4')">
|
<demo-block :title="$t('errorInfo')">
|
||||||
<van-cell-group>
|
<van-cell-group>
|
||||||
<van-field
|
<van-field
|
||||||
v-model="username"
|
v-model="username"
|
||||||
@ -89,7 +89,7 @@
|
|||||||
</van-cell-group>
|
</van-cell-group>
|
||||||
</demo-block>
|
</demo-block>
|
||||||
|
|
||||||
<demo-block :title="$t('title6')">
|
<demo-block :title="$t('insertButton')">
|
||||||
<van-cell-group>
|
<van-cell-group>
|
||||||
<van-field
|
<van-field
|
||||||
center
|
center
|
||||||
@ -107,6 +107,17 @@
|
|||||||
</van-cell-group>
|
</van-cell-group>
|
||||||
</demo-block>
|
</demo-block>
|
||||||
|
|
||||||
|
<demo-block v-if="!isWeapp" :title="$t('formatValue')">
|
||||||
|
<van-cell-group>
|
||||||
|
<van-field
|
||||||
|
v-model="formatValue"
|
||||||
|
:label="$t('text')"
|
||||||
|
:formatter="formatter"
|
||||||
|
:placeholder="$t('formatValue')"
|
||||||
|
/>
|
||||||
|
</van-cell-group>
|
||||||
|
</demo-block>
|
||||||
|
|
||||||
<demo-block :title="$t('textareaAutosize')">
|
<demo-block :title="$t('textareaAutosize')">
|
||||||
<van-cell-group>
|
<van-cell-group>
|
||||||
<van-field
|
<van-field
|
||||||
@ -141,58 +152,60 @@
|
|||||||
export default {
|
export default {
|
||||||
i18n: {
|
i18n: {
|
||||||
'zh-CN': {
|
'zh-CN': {
|
||||||
title2: '自定义类型',
|
|
||||||
title3: '禁用输入框',
|
|
||||||
title4: '错误提示',
|
|
||||||
title6: '插入按钮',
|
|
||||||
sms: '短信验证码',
|
|
||||||
tel: '手机号',
|
tel: '手机号',
|
||||||
|
sms: '短信验证码',
|
||||||
text: '文本',
|
text: '文本',
|
||||||
digit: '整数',
|
digit: '整数',
|
||||||
phone: '手机号',
|
phone: '手机号',
|
||||||
number: '数字',
|
number: '数字',
|
||||||
message: '留言',
|
message: '留言',
|
||||||
sendSMS: '发送验证码',
|
sendSMS: '发送验证码',
|
||||||
|
disabled: '禁用输入框',
|
||||||
showIcon: '显示图标',
|
showIcon: '显示图标',
|
||||||
|
errorInfo: '错误提示',
|
||||||
|
customType: '自定义类型',
|
||||||
|
phoneError: '手机号格式错误',
|
||||||
|
formatValue: '格式化输入内容',
|
||||||
|
insertButton: '插入按钮',
|
||||||
showClearIcon: '显示清除图标',
|
showClearIcon: '显示清除图标',
|
||||||
showWordLimit: '显示字数统计',
|
showWordLimit: '显示字数统计',
|
||||||
textareaAutosize: '高度自适应',
|
inputReadonly: '输入框只读',
|
||||||
|
inputDisabled: '输入框已禁用',
|
||||||
smsPlaceholder: '请输入短信验证码',
|
smsPlaceholder: '请输入短信验证码',
|
||||||
textPlaceholder: '请输入文本',
|
textPlaceholder: '请输入文本',
|
||||||
digitPlaceholder: '请输入整数',
|
digitPlaceholder: '请输入整数',
|
||||||
numberPlaceholder: '请输入数字(支持小数)',
|
|
||||||
phonePlaceholder: '请输入手机号',
|
phonePlaceholder: '请输入手机号',
|
||||||
messagePlaceholder: '请输入留言',
|
textareaAutosize: '高度自适应',
|
||||||
inputReadonly: '输入框只读',
|
numberPlaceholder: '请输入数字(支持小数)',
|
||||||
inputDisabled: '输入框已禁用',
|
messagePlaceholder: '请输入留言'
|
||||||
phoneError: '手机号格式错误'
|
|
||||||
},
|
},
|
||||||
'en-US': {
|
'en-US': {
|
||||||
title2: 'Custom Type',
|
|
||||||
title3: 'Disabled',
|
|
||||||
title4: 'Error Info',
|
|
||||||
title6: 'Insert Button',
|
|
||||||
sms: 'SMS',
|
|
||||||
tel: 'Tel',
|
tel: 'Tel',
|
||||||
|
sms: 'SMS',
|
||||||
text: 'Text',
|
text: 'Text',
|
||||||
digit: 'Digit',
|
digit: 'Digit',
|
||||||
phone: 'Phone',
|
phone: 'Phone',
|
||||||
number: 'Number',
|
number: 'Number',
|
||||||
message: 'Message',
|
message: 'Message',
|
||||||
sendSMS: 'Send SMS',
|
sendSMS: 'Send SMS',
|
||||||
|
disabled: 'Disabled',
|
||||||
showIcon: 'Show Icon',
|
showIcon: 'Show Icon',
|
||||||
|
errorInfo: 'Error Info',
|
||||||
|
customType: 'Custom Type',
|
||||||
|
phoneError: 'Invalid phone',
|
||||||
|
formatValue: 'Format Value',
|
||||||
|
insertButton: 'Insert Button',
|
||||||
showClearIcon: 'Show Clear Icon',
|
showClearIcon: 'Show Clear Icon',
|
||||||
showWordLimit: 'Show Word Limit',
|
showWordLimit: 'Show Word Limit',
|
||||||
textareaAutosize: 'Auto Resize',
|
inputReadonly: 'Input Readonly',
|
||||||
|
inputDisabled: 'Input Disabled',
|
||||||
smsPlaceholder: 'SMS',
|
smsPlaceholder: 'SMS',
|
||||||
textPlaceholder: 'Text',
|
textPlaceholder: 'Text',
|
||||||
digitPlaceholder: 'Digit',
|
digitPlaceholder: 'Digit',
|
||||||
phonePlaceholder: 'Phone',
|
phonePlaceholder: 'Phone',
|
||||||
|
textareaAutosize: 'Auto Resize',
|
||||||
numberPlaceholder: 'Number',
|
numberPlaceholder: 'Number',
|
||||||
messagePlaceholder: 'Message',
|
messagePlaceholder: 'Message'
|
||||||
inputReadonly: 'Input Readonly',
|
|
||||||
inputDisabled: 'Input Disabled',
|
|
||||||
phoneError: 'Invalid phone'
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -211,8 +224,15 @@ export default {
|
|||||||
message: '',
|
message: '',
|
||||||
message2: '',
|
message2: '',
|
||||||
phone: '',
|
phone: '',
|
||||||
phone2: '12345'
|
phone2: '12345',
|
||||||
|
formatValue: ''
|
||||||
};
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
formatter(value) {
|
||||||
|
return value.replace(/\d/g, '');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -20,6 +20,7 @@ export default createComponent({
|
|||||||
leftIcon: String,
|
leftIcon: String,
|
||||||
rightIcon: String,
|
rightIcon: String,
|
||||||
clearable: Boolean,
|
clearable: Boolean,
|
||||||
|
formatter: Function,
|
||||||
maxlength: [Number, String],
|
maxlength: [Number, String],
|
||||||
labelWidth: [Number, String],
|
labelWidth: [Number, String],
|
||||||
labelClass: null,
|
labelClass: null,
|
||||||
@ -99,7 +100,6 @@ export default createComponent({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// native maxlength not work when type = number
|
|
||||||
format(target = this.$refs.input) {
|
format(target = this.$refs.input) {
|
||||||
if (!target) {
|
if (!target) {
|
||||||
return;
|
return;
|
||||||
@ -108,6 +108,7 @@ export default createComponent({
|
|||||||
let { value } = target;
|
let { value } = target;
|
||||||
const { maxlength } = this;
|
const { maxlength } = this;
|
||||||
|
|
||||||
|
// native maxlength not work when type is number
|
||||||
if (isDef(maxlength) && value.length > maxlength) {
|
if (isDef(maxlength) && value.length > maxlength) {
|
||||||
value = value.slice(0, maxlength);
|
value = value.slice(0, maxlength);
|
||||||
target.value = value;
|
target.value = value;
|
||||||
@ -124,6 +125,16 @@ export default createComponent({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.formatter) {
|
||||||
|
const originValue = value;
|
||||||
|
|
||||||
|
value = this.formatter(value);
|
||||||
|
|
||||||
|
if (value !== originValue) {
|
||||||
|
target.value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -115,6 +115,16 @@ exports[`renders demo correctly 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="van-cell-group van-hairline--top-bottom">
|
||||||
|
<div class="van-cell van-field">
|
||||||
|
<div class="van-cell__title van-field__label"><span>文本</span></div>
|
||||||
|
<div class="van-cell__value">
|
||||||
|
<div class="van-field__body"><input type="text" placeholder="格式化输入内容" class="van-field__control"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="van-cell-group van-hairline--top-bottom">
|
<div class="van-cell-group van-hairline--top-bottom">
|
||||||
<div class="van-cell van-field">
|
<div class="van-cell van-field">
|
||||||
|
@ -262,3 +262,21 @@ test('arrow-direction prop', () => {
|
|||||||
});
|
});
|
||||||
expect(wrapper).toMatchSnapshot();
|
expect(wrapper).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('formatter prop', () => {
|
||||||
|
const wrapper = mount(Field, {
|
||||||
|
propsData: {
|
||||||
|
value: 'abc123',
|
||||||
|
formatter: (value) => value.replace(/\d/g, '')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const input = wrapper.find('input');
|
||||||
|
|
||||||
|
input.trigger('input');
|
||||||
|
expect(wrapper.emitted('input')[0][0]).toEqual('abc');
|
||||||
|
|
||||||
|
input.element.value = '123efg';
|
||||||
|
input.trigger('input');
|
||||||
|
expect(wrapper.emitted('input')[1][0]).toEqual('efg');
|
||||||
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user