feat(Field): add format-trigger prop (#6566)

This commit is contained in:
neverland 2020-06-18 20:57:42 +08:00 committed by GitHub
parent f2543b5dfa
commit 95313ef459
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 87 additions and 27 deletions

View File

@ -139,10 +139,17 @@ Use `formatter` prop to format the input value
```html ```html
<van-field <van-field
v-model="value" v-model="value1"
label="Text" label="Text"
:formatter="formatter" :formatter="formatter"
placeholder="Format Value" placeholder="Format On Change"
/>
<van-field
v-model="value2"
label="Text"
:formatter="formatter"
format-trigger="onBlur"
placeholder="Format On Blur"
/> />
``` ```
@ -150,7 +157,8 @@ Use `formatter` prop to format the input value
export default { export default {
data() { data() {
return { return {
value: '', value1: '',
value2: '',
}; };
}, },
methods: { methods: {
@ -230,6 +238,7 @@ Use `input-align` prop to align the input value
| error | Whether to show error info | _boolean_ | `false` | | error | Whether to show error info | _boolean_ | `false` |
| error-message | Error message | _string_ | - | | error-message | Error message | _string_ | - |
| formatter `v2.4.2` | Input value formatter | _Function_ | - | | formatter `v2.4.2` | Input value formatter | _Function_ | - |
| format-trigger `v2.8.7` | When to format valuecan be set to `onBlur` | _string_ | `onChange` |
| arrow-direction `v2.0.4` | Can be set to `left` `up` `down` | _string_ | `right` | | arrow-direction `v2.0.4` | Can be set to `left` `up` `down` | _string_ | `right` |
| label-class | Label className | _any_ | - | | label-class | Label className | _any_ | - |
| label-width | Label width | _number \| string_ | `90px` | | label-width | Label width | _number \| string_ | `90px` |

View File

@ -17,7 +17,7 @@ Vue.use(Field);
### 基础用法 ### 基础用法
可以通过`v-model`双向绑定输入框的值,通过`placeholder`设置占位提示文字 可以通过 `v-model` 双向绑定输入框的值,通过 `placeholder` 设置占位提示文字
```html ```html
<!-- Field 是基于 Cell 实现的,可以使用 CellGroup 作为容器来提供外边框。 --> <!-- Field 是基于 Cell 实现的,可以使用 CellGroup 作为容器来提供外边框。 -->
@ -38,7 +38,7 @@ export default {
### 自定义类型 ### 自定义类型
根据`type`属性定义不同类型的输入框,默认值为`text` 根据 `type` 属性定义不同类型的输入框,默认值为 `text`
```html ```html
<!-- 输入任意文本 --> <!-- 输入任意文本 -->
@ -71,7 +71,7 @@ export default {
### 禁用输入框 ### 禁用输入框
通过`readonly`将输入框设置为只读状态,通过`disabled`将输入框设置为禁用状态 通过 `readonly` 将输入框设置为只读状态,通过 `disabled` 将输入框设置为禁用状态
```html ```html
<van-cell-group> <van-cell-group>
@ -82,7 +82,7 @@ export default {
### 显示图标 ### 显示图标
通过`left-icon``right-icon`配置输入框两侧的图标,通过设置`clearable`在输入过程中展示清除图标 通过 `left-icon` `right-icon` 配置输入框两侧的图标,通过设置 `clearable` 在输入过程中展示清除图标
```html ```html
<van-cell-group> <van-cell-group>
@ -116,7 +116,7 @@ export default {
### 错误提示 ### 错误提示
设置`required`属性表示这是一个必填项,可以配合`error``error-message`属性显示对应的错误提示 设置 `required` 属性表示这是一个必填项,可以配合 `error` `error-message` 属性显示对应的错误提示
```html ```html
<van-cell-group> <van-cell-group>
@ -139,7 +139,7 @@ export default {
### 插入按钮 ### 插入按钮
通过 button 插槽可以在输入框尾部插入按钮 通过 button 插槽可以在输入框尾部插入按钮
```html ```html
<van-field <van-field
@ -157,14 +157,21 @@ export default {
### 格式化输入内容 ### 格式化输入内容
通过`formatter`属性可以对输入的内容进行格式化 通过 `formatter` 属性可以对输入的内容进行格式化,通过 `format-trigger` 属性可以指定执行格式化的时机,默认在输入时进行格式化。
```html ```html
<van-field <van-field
v-model="value" v-model="value1"
label="文本" label="文本"
:formatter="formatter" :formatter="formatter"
placeholder="格式化输入内容" placeholder="在输入时执行格式化"
/>
<van-field
v-model="value2"
label="文本"
:formatter="formatter"
format-trigger="onBlur"
placeholder="在失焦时执行格式化"
/> />
``` ```
@ -172,7 +179,8 @@ export default {
export default { export default {
data() { data() {
return { return {
value: '', value1: '',
value2: '',
}; };
}, },
methods: { methods: {
@ -186,7 +194,7 @@ export default {
### 高度自适应 ### 高度自适应
对于 textarea可以通过`autosize`属性设置高度自适应 对于 textarea可以通过 `autosize` 属性设置高度自适应
```html ```html
<van-field <van-field
@ -201,7 +209,7 @@ export default {
### 显示字数统计 ### 显示字数统计
设置`maxlength``show-word-limit`属性后会在底部显示字数统计 设置 `maxlength` `show-word-limit` 属性后会在底部显示字数统计
```html ```html
<van-field <van-field
@ -218,7 +226,7 @@ export default {
### 输入框内容对齐 ### 输入框内容对齐
通过`input-align`属性可以设置输入框内容的对齐方式,可选值为`center``right` 通过 `input-align` 属性可以设置输入框内容的对齐方式,可选值为 `center``right`
```html ```html
<van-field <van-field
@ -255,6 +263,7 @@ export default {
| error | 是否将输入内容标红 | _boolean_ | `false` | | error | 是否将输入内容标红 | _boolean_ | `false` |
| error-message | 底部错误提示文案,为空时不展示 | _string_ | - | | error-message | 底部错误提示文案,为空时不展示 | _string_ | - |
| formatter `v2.4.2` | 输入内容格式化函数 | _Function_ | - | | formatter `v2.4.2` | 输入内容格式化函数 | _Function_ | - |
| format-trigger `v2.8.7` | 格式化函数触发的时机,可选值为 `onBlur` | _string_ | `onChange` |
| arrow-direction `v2.0.4` | 箭头方向,可选值为 `left` `up` `down` | _string_ | `right` | | arrow-direction `v2.0.4` | 箭头方向,可选值为 `left` `up` `down` | _string_ | `right` |
| label-class | 左侧文本额外类名 | _any_ | - | | label-class | 左侧文本额外类名 | _any_ | - |
| label-width | 左侧文本宽度,默认单位为`px` | _number \| string_ | `90px` | | label-width | 左侧文本宽度,默认单位为`px` | _number \| string_ | `90px` |

View File

@ -1,10 +1,17 @@
<template> <template>
<demo-block v-if="!isWeapp" :title="t('formatValue')"> <demo-block v-if="!isWeapp" :title="t('formatValue')">
<van-field <van-field
v-model="formatValue" v-model="value1"
:label="t('text')" :label="t('text')"
:formatter="formatter" :formatter="formatter"
:placeholder="t('formatValue')" :placeholder="t('formatOnChange')"
/>
<van-field
v-model="value2"
:label="t('text')"
:formatter="formatter"
format-trigger="onBlur"
:placeholder="t('formatOnBlur')"
/> />
</demo-block> </demo-block>
</template> </template>
@ -15,16 +22,21 @@ export default {
'zh-CN': { 'zh-CN': {
text: '文本', text: '文本',
formatValue: '格式化输入内容', formatValue: '格式化输入内容',
formatOnBlur: '在失焦时执行格式化',
formatOnChange: '在输入时执行格式化',
}, },
'en-US': { 'en-US': {
text: 'Text', text: 'Text',
formatValue: 'Format Value', formatValue: 'Format Value',
formatOnBlur: 'Format On Blur',
formatOnChange: 'Format On Change',
}, },
}, },
data() { data() {
return { return {
formatValue: '', value1: '',
value2: '',
}; };
}, },

View File

@ -69,6 +69,10 @@ export default createComponent({
type: Boolean, type: Boolean,
default: null, default: null,
}, },
formatTrigger: {
type: String,
default: 'onChange',
},
}, },
data() { data() {
@ -89,7 +93,7 @@ export default createComponent({
}, },
mounted() { mounted() {
this.updateValue(this.value); this.updateValue(this.value, this.formatTrigger);
this.$nextTick(this.adjustSize); this.$nextTick(this.adjustSize);
if (this.vanForm) { if (this.vanForm) {
@ -279,13 +283,9 @@ export default createComponent({
} }
}, },
updateValue(value) { updateValue(value, trigger = 'onChange') {
value = isDef(value) ? String(value) : ''; value = isDef(value) ? String(value) : '';
if (value === this.currentValue) {
return;
}
// native maxlength not work when type is number // native maxlength not work when type is number
const { maxlength } = this; const { maxlength } = this;
if (isDef(maxlength) && value.length > maxlength) { if (isDef(maxlength) && value.length > maxlength) {
@ -297,7 +297,7 @@ export default createComponent({
value = formatNumber(value, allowDot); value = formatNumber(value, allowDot);
} }
if (this.formatter) { if (this.formatter && trigger === this.formatTrigger) {
value = this.formatter(value); value = this.formatter(value);
} }
@ -335,6 +335,7 @@ export default createComponent({
onBlur(event) { onBlur(event) {
this.focused = false; this.focused = false;
this.updateValue(this.value, 'onBlur');
this.$emit('blur', event); this.$emit('blur', event);
this.validateWithTrigger('onBlur'); this.validateWithTrigger('onBlur');
resetScroll(); resetScroll();

View File

@ -112,7 +112,13 @@ exports[`renders demo correctly 1`] = `
<div class="van-cell van-field"> <div class="van-cell van-field">
<div class="van-cell__title van-field__label"><span>文本</span></div> <div class="van-cell__title van-field__label"><span>文本</span></div>
<div class="van-cell__value van-field__value"> <div class="van-cell__value van-field__value">
<div class="van-field__body"><input type="text" placeholder="格式化输入内容" class="van-field__control"></div> <div class="van-field__body"><input type="text" placeholder="在输入时执行格式化" class="van-field__control"></div>
</div>
</div>
<div class="van-cell van-field">
<div class="van-cell__title van-field__label"><span>文本</span></div>
<div class="van-cell__value van-field__value">
<div class="van-field__body"><input type="text" placeholder="在失焦时执行格式化" class="van-field__control"></div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -297,6 +297,29 @@ test('formatter prop', () => {
expect(wrapper.emitted('input')[1][0]).toEqual('efg'); expect(wrapper.emitted('input')[1][0]).toEqual('efg');
}); });
test('format-trigger prop', () => {
const wrapper = mount(Field, {
propsData: {
value: 'abc123',
formatTrigger: 'onBlur',
formatter: (value) => value.replace(/\d/g, ''),
},
});
wrapper.vm.$on('input', (value) => {
wrapper.setProps({ value });
});
expect(wrapper.emitted('input')[0][0]).toEqual('abc');
const input = wrapper.find('input');
input.element.value = '123efg';
input.trigger('input');
expect(wrapper.emitted('input')[1][0]).toEqual('123efg');
input.trigger('blur');
expect(wrapper.emitted('input')[2][0]).toEqual('efg');
});
test('reach max word-limit', () => { test('reach max word-limit', () => {
const wrapper = mount(Field, { const wrapper = mount(Field, {
propsData: { propsData: {