[Improvement] Field: support clearable (#1309)
This commit is contained in:
@@ -11,10 +11,11 @@
|
||||
<van-field
|
||||
v-model="username"
|
||||
:label="$t('username')"
|
||||
icon="clear"
|
||||
:placeholder="$t('usernamePlaceholder')"
|
||||
clearable
|
||||
icon="question"
|
||||
required
|
||||
@click-icon="username = ''"
|
||||
@click-icon="$toast('question')"
|
||||
/>
|
||||
|
||||
<van-field
|
||||
@@ -72,11 +73,10 @@
|
||||
<van-cell-group>
|
||||
<van-field
|
||||
center
|
||||
clearable
|
||||
v-model="sms"
|
||||
:label="$t('sms')"
|
||||
:placeholder="$t('smsPlaceholder')"
|
||||
icon="clear"
|
||||
@click-icon="sms = ''"
|
||||
>
|
||||
<van-button slot="button" size="small" type="primary">{{ $t('sendSMS') }}</van-button>
|
||||
</van-field>
|
||||
@@ -139,5 +139,9 @@ export default {
|
||||
<style lang="postcss">
|
||||
.demo-field {
|
||||
padding-bottom: 30px;
|
||||
|
||||
.van-field__icon {
|
||||
color: #38f;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -25,11 +25,12 @@ Use `type` prop to custom diffrent type fields.
|
||||
<van-cell-group>
|
||||
<van-field
|
||||
v-model="username"
|
||||
label="Username"
|
||||
icon="clear"
|
||||
placeholder="Username"
|
||||
required
|
||||
@click-icon="username = ''"
|
||||
clearable
|
||||
label="Username"
|
||||
icon="question"
|
||||
placeholder="Username"
|
||||
@click-icon="$toast('question')"
|
||||
/>
|
||||
|
||||
<van-field
|
||||
@@ -97,12 +98,11 @@ Use button slot to insert button
|
||||
```html
|
||||
<van-cell-group>
|
||||
<van-field
|
||||
center
|
||||
v-model="sms"
|
||||
center
|
||||
clearable
|
||||
label="SMS"
|
||||
placeholder="SMS"
|
||||
icon="clear"
|
||||
@click-icon="sms = ''"
|
||||
>
|
||||
<van-button slot="button" size="small" type="primary">Send SMS</van-button>
|
||||
</van-field>
|
||||
@@ -119,6 +119,7 @@ Field support all native properties of input tag,such as `maxlength`、`placeh
|
||||
| label | Field label | `String` | - |
|
||||
| type | Input type | `String` | `text` |
|
||||
| disabled | Disable field | `Boolean` | `false` |
|
||||
| clearable | Whether to be clearable | `Boolean` | `false` |
|
||||
| error | Whether to show error info | `Boolean` | `false` |
|
||||
| error-message | Error message | `String` | `''` |
|
||||
| autosize | Textarea auto resize,can accpet an object, e.g. { maxHeight: 100, minHeight: 50 } | `Boolean | Object` | `false` |
|
||||
|
||||
+55
-33
@@ -8,45 +8,48 @@
|
||||
:class="b({
|
||||
error,
|
||||
disabled: $attrs.disabled,
|
||||
'has-icon': showIcon,
|
||||
'min-height': type === 'textarea' && !autosize
|
||||
})"
|
||||
>
|
||||
<slot name="label" slot="title" />
|
||||
<textarea
|
||||
v-if="type === 'textarea'"
|
||||
v-bind="$attrs"
|
||||
v-on="listeners"
|
||||
ref="input"
|
||||
:class="b('control')"
|
||||
:value="value"
|
||||
/>
|
||||
<input
|
||||
v-else
|
||||
v-bind="$attrs"
|
||||
v-on="listeners"
|
||||
ref="input"
|
||||
:class="b('control')"
|
||||
:type="type"
|
||||
:value="value"
|
||||
>
|
||||
<div :class="b('body')">
|
||||
<textarea
|
||||
v-if="type === 'textarea'"
|
||||
v-bind="$attrs"
|
||||
v-on="listeners"
|
||||
ref="input"
|
||||
:class="b('control')"
|
||||
:value="value"
|
||||
/>
|
||||
<input
|
||||
v-else
|
||||
v-bind="$attrs"
|
||||
v-on="listeners"
|
||||
ref="input"
|
||||
:class="b('control')"
|
||||
:type="type"
|
||||
:value="value"
|
||||
>
|
||||
<icon
|
||||
v-if="showClear"
|
||||
name="clear"
|
||||
:class="b('clear')"
|
||||
@touchstart.prevent="$emit('input', '')"
|
||||
/>
|
||||
<div v-if="$slots.icon || icon" :class="b('icon')" @click="onClickIcon">
|
||||
<slot name="icon">
|
||||
<icon :name="icon" />
|
||||
</slot>
|
||||
</div>
|
||||
<div v-if="$slots.button" :class="b('button')">
|
||||
<slot name="button" />
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="errorMessage"
|
||||
v-text="errorMessage"
|
||||
:class="b('error-message')"
|
||||
/>
|
||||
<div
|
||||
v-if="showIcon"
|
||||
:class="b('icon')"
|
||||
@touchstart.prevent="onClickIcon"
|
||||
>
|
||||
<slot name="icon">
|
||||
<icon :name="icon" />
|
||||
</slot>
|
||||
</div>
|
||||
<div v-if="$slots.button" :class="b('button')" slot="extra">
|
||||
<slot name="button" />
|
||||
</div>
|
||||
</cell>
|
||||
</template>
|
||||
|
||||
@@ -67,6 +70,7 @@ export default create({
|
||||
center: Boolean,
|
||||
leftIcon: String,
|
||||
required: Boolean,
|
||||
clearable: Boolean,
|
||||
onIconClick: Function,
|
||||
autosize: [Boolean, Object],
|
||||
errorMessage: String,
|
||||
@@ -80,6 +84,12 @@ export default create({
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
focused: false
|
||||
};
|
||||
},
|
||||
|
||||
watch: {
|
||||
value() {
|
||||
this.$nextTick(this.adjustSize);
|
||||
@@ -91,15 +101,17 @@ export default create({
|
||||
},
|
||||
|
||||
computed: {
|
||||
showIcon() {
|
||||
return this.$slots.icon || (this.icon && this.value !== '' && this.isDef(this.value));
|
||||
showClear() {
|
||||
return this.clearable && this.focused && this.value !== '' && this.isDef(this.value);
|
||||
},
|
||||
|
||||
listeners() {
|
||||
return {
|
||||
...this.$listeners,
|
||||
input: this.onInput,
|
||||
keypress: this.onKeypress
|
||||
keypress: this.onKeypress,
|
||||
focus: this.onFocus,
|
||||
blur: this.onBlur
|
||||
};
|
||||
}
|
||||
},
|
||||
@@ -113,6 +125,16 @@ export default create({
|
||||
this.$emit('input', event.target.value);
|
||||
},
|
||||
|
||||
onFocus(event) {
|
||||
this.focused = true;
|
||||
this.$emit('focus', event);
|
||||
},
|
||||
|
||||
onBlur(event) {
|
||||
this.focused = false;
|
||||
this.$emit('blur', event);
|
||||
},
|
||||
|
||||
onClickIcon() {
|
||||
this.$emit('click-icon');
|
||||
this.onIconClick && this.onIconClick();
|
||||
|
||||
@@ -8,9 +8,12 @@ exports[`renders demo correctly 1`] = `
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="van-cell__value van-cell__value--alone">
|
||||
<input type="text" placeholder="请输入用户名" value="" class="van-field__control">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="van-field__body">
|
||||
<input type="text" placeholder="请输入用户名" value="" class="van-field__control">
|
||||
<!---->
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
@@ -25,9 +28,16 @@ exports[`renders demo correctly 1`] = `
|
||||
<!---->
|
||||
</div>
|
||||
<div class="van-cell__value">
|
||||
<input type="text" placeholder="请输入用户名" value="" class="van-field__control">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="van-field__body">
|
||||
<input type="text" placeholder="请输入用户名" value="" class="van-field__control">
|
||||
<!---->
|
||||
<div class="van-field__icon">
|
||||
<i class="van-icon van-icon-question" style="color:undefined;">
|
||||
<!---->
|
||||
</i>
|
||||
</div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
@@ -38,9 +48,12 @@ exports[`renders demo correctly 1`] = `
|
||||
<!---->
|
||||
</div>
|
||||
<div class="van-cell__value">
|
||||
<input type="password" placeholder="请输入密码" value="" class="van-field__control">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="van-field__body">
|
||||
<input type="password" placeholder="请输入密码" value="" class="van-field__control">
|
||||
<!---->
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
@@ -57,9 +70,12 @@ exports[`renders demo correctly 1`] = `
|
||||
<!---->
|
||||
</div>
|
||||
<div class="van-cell__value">
|
||||
<input type="text" disabled="disabled" value="输入框已禁用" class="van-field__control">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="van-field__body">
|
||||
<input type="text" disabled="disabled" value="输入框已禁用" class="van-field__control">
|
||||
<!---->
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
@@ -74,9 +90,12 @@ exports[`renders demo correctly 1`] = `
|
||||
<!---->
|
||||
</div>
|
||||
<div class="van-cell__value">
|
||||
<input type="text" placeholder="请输入用户名" value="" class="van-field__control">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="van-field__body">
|
||||
<input type="text" placeholder="请输入用户名" value="" class="van-field__control">
|
||||
<!---->
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
@@ -87,10 +106,13 @@ exports[`renders demo correctly 1`] = `
|
||||
<!---->
|
||||
</div>
|
||||
<div class="van-cell__value">
|
||||
<input type="text" placeholder="请输入手机号" value="1365577" class="van-field__control">
|
||||
<div class="van-field__body">
|
||||
<input type="text" placeholder="请输入手机号" value="1365577" class="van-field__control">
|
||||
<!---->
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
<div class="van-field__error-message">手机号格式错误</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
</div>
|
||||
@@ -104,9 +126,12 @@ exports[`renders demo correctly 1`] = `
|
||||
<!---->
|
||||
</div>
|
||||
<div class="van-cell__value">
|
||||
<textarea placeholder="请输入留言" rows="1" class="van-field__control"></textarea>
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="van-field__body">
|
||||
<textarea placeholder="请输入留言" rows="1" class="van-field__control"></textarea>
|
||||
<!---->
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
@@ -121,15 +146,18 @@ exports[`renders demo correctly 1`] = `
|
||||
<!---->
|
||||
</div>
|
||||
<div class="van-cell__value">
|
||||
<input type="text" placeholder="请输入短信验证码" value="" class="van-field__control">
|
||||
<!---->
|
||||
<div class="van-field__body">
|
||||
<input type="text" placeholder="请输入短信验证码" value="" class="van-field__control">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="van-field__button">
|
||||
<button class="van-button van-button--primary van-button--small">
|
||||
<!----><span class="van-button__text">发送验证码</span></button>
|
||||
</div>
|
||||
</div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<div class="van-field__button">
|
||||
<button class="van-button van-button--primary van-button--small">
|
||||
<!----><span class="van-button__text">发送验证码</span></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -5,9 +5,12 @@ exports[`render textarea 1`] = `
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="van-cell__value van-cell__value--alone">
|
||||
<textarea class="van-field__control" style="height: auto;"></textarea>
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="van-field__body">
|
||||
<textarea class="van-field__control" style="height: auto;"></textarea>
|
||||
<!---->
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
|
||||
@@ -21,7 +21,7 @@ test('click icon event', () => {
|
||||
}
|
||||
});
|
||||
|
||||
wrapper.find('.van-field__icon').trigger('touchstart');
|
||||
wrapper.find('.van-field__icon').trigger('click');
|
||||
expect(wrapper.emitted('click-icon')).toBeTruthy();
|
||||
expect(onIconClick.mock.calls.length).toBe(1);
|
||||
});
|
||||
@@ -102,11 +102,9 @@ test('autosize object', async() => {
|
||||
|
||||
test('blur method', () => {
|
||||
const fn = jest.fn();
|
||||
const wrapper = mount(Field, {
|
||||
listeners: {
|
||||
blur: fn
|
||||
}
|
||||
});
|
||||
const wrapper = mount(Field);
|
||||
|
||||
wrapper.vm.$on('blur', fn);
|
||||
wrapper.find('input').element.focus();
|
||||
wrapper.vm.blur();
|
||||
|
||||
|
||||
@@ -27,11 +27,12 @@ Vue.use(Field);
|
||||
<van-cell-group>
|
||||
<van-field
|
||||
v-model="username"
|
||||
label="用户名"
|
||||
icon="clear"
|
||||
placeholder="请输入用户名"
|
||||
required
|
||||
@click-icon="username = ''"
|
||||
clearable
|
||||
label="用户名"
|
||||
icon="question"
|
||||
placeholder="请输入用户名"
|
||||
@click-icon="$toast('question')"
|
||||
/>
|
||||
|
||||
<van-field
|
||||
@@ -99,12 +100,11 @@ Vue.use(Field);
|
||||
```html
|
||||
<van-cell-group>
|
||||
<van-field
|
||||
center
|
||||
v-model="sms"
|
||||
center
|
||||
clearable
|
||||
label="短信验证码"
|
||||
placeholder="请输入短信验证码"
|
||||
icon="clear"
|
||||
@click-icon="sms = ''"
|
||||
>
|
||||
<van-button slot="button" size="small" type="primary">发送验证码</van-button>
|
||||
</van-field>
|
||||
@@ -121,6 +121,7 @@ Field 默认支持 Input 标签所有的原生属性,比如 `maxlength`、`pla
|
||||
| value | 当前输入的值 | `String | Number` | - |
|
||||
| type | 可设置为任意原生类型, 如 `number` `tel` `textarea` | `String` | `text` |
|
||||
| disabled | 是否禁用输入框 | `Boolean` | `false` |
|
||||
| clearable | 输入框内容是否可清除 | `Boolean` | `false` |
|
||||
| error | 是否将输入内容标红 | `Boolean` | `false` |
|
||||
| error-message | 底部错误提示文案 | `String` | `''` |
|
||||
| autosize | 自适应内容高度,只对 textarea 有效,可传入对象,如 { maxHeight: 100, minHeight: 50 },单位为 px | `Boolean | Object` | `false` |
|
||||
|
||||
Reference in New Issue
Block a user