[Improvement] Field: support clearable (#1309)

This commit is contained in:
neverland
2018-06-20 20:09:04 +08:00
committed by GitHub
parent c368e36aea
commit 0a99da352e
19 changed files with 312 additions and 231 deletions
+8 -4
View File
@@ -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>
+8 -7
View File
@@ -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 tagsuch 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 resizecan accpet an object, e.g. { maxHeight: 100, minHeight: 50 } | `Boolean | Object` | `false` |
+55 -33
View File
@@ -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>
<!---->
+4 -6
View File
@@ -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();
+8 -7
View File
@@ -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` |