[Improvement] Field: add button slot (#772)

This commit is contained in:
neverland 2018-03-25 22:12:24 +08:00 committed by GitHub
parent 199ec0cd85
commit 45859cf0a6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 127 additions and 93 deletions

View File

@ -35,7 +35,12 @@
<demo-block :title="$t('title4')">
<van-cell-group>
<van-field :label="$t('username')" :placeholder="$t('usernamePlaceholder')" error />
<van-field
v-model="username2"
:label="$t('username')"
:placeholder="$t('usernamePlaceholder')"
error
/>
<van-field
v-model="phone"
:label="$t('phone')"
@ -53,10 +58,25 @@
type="textarea"
:placeholder="$t('messagePlaceholder')"
rows="1"
:autosize="{ maxHeight: 100, minHeight: 40 }"
autosize
/>
</van-cell-group>
</demo-block>
<demo-block :title="$t('title6')">
<van-cell-group>
<van-field
center
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>
</van-cell-group>
</demo-block>
</demo-section>
</template>
@ -68,8 +88,12 @@ export default {
title3: '禁用输入框',
title4: '错误提示',
title5: '高度自适应',
title6: '插入按钮',
message: '留言',
phone: '手机号',
sms: '短信验证码',
sendSMS: '发送验证码',
smsPlaceholder: '请输入短信验证码',
phonePlaceholder: '请输入手机号',
messagePlaceholder: '请输入留言',
inputDisabled: '输入框已禁用',
@ -80,8 +104,12 @@ export default {
title3: 'Disabled',
title4: 'Error info',
title5: 'Auto resize',
title6: 'Insert button',
message: 'Message',
phone: 'Phone',
sms: 'SMS',
sendSMS: 'Send SMS',
smsPlaceholder: 'SMS',
phonePlaceholder: 'Phone',
messagePlaceholder: 'Message',
inputDisabled: 'Disabled',
@ -91,9 +119,11 @@ export default {
data() {
return {
sms: '',
value: '',
password: '',
username: '',
username2: '',
message: '',
phone: '1365577'
};

View File

@ -60,11 +60,13 @@ Use `error` or `error-message` to show error info
```html
<van-cell-group>
<van-field
v-model="username"
label="Username"
placeholder="Username"
error
/>
<van-field
v-model="phone"
label="Phone"
placeholder="Phone"
error-message="Invalid phone"
@ -88,6 +90,24 @@ Textarea Filed can be auto resize when has `autosize` prop
</van-cell-group>
```
#### Insert button
Use button slot to insert button
```html
<van-cell-group>
<van-field
center
v-model="sms"
label="SMS"
placeholder="SMS"
icon="clear"
@click-icon="sms = ''"
>
<van-button slot="button" size="small" type="primary">Send SMS</van-button>
</van-field>
</van-cell-group>
```
### API
Filed support all native properties of input tagsuch as `maxlength``placeholder``readonly``autofocus`
@ -114,3 +134,4 @@ Filed support all native events of input tagsuch as `focus`、`blur`、`keypr
| name | Description |
|-----------|-----------|
| icon | Custom icon |
| button | Insert button |

View File

@ -62,11 +62,13 @@ Vue.use(Field);
```html
<van-cell-group>
<van-field
v-model="username"
label="用户名"
placeholder="请输入用户名"
error
/>
<van-field
v-model="phone"
label="手机号"
placeholder="请输入手机号"
error-message="手机号格式错误"
@ -90,6 +92,24 @@ Vue.use(Field);
</van-cell-group>
```
#### 插入按钮
通过 button slot 可以在输入框尾部插入按钮
```html
<van-cell-group>
<van-field
center
v-model="sms"
label="短信验证码"
placeholder="请输入短信验证码"
icon="clear"
@click-icon="sms = ''"
>
<van-button slot="button" size="small" type="primary">发送验证码</van-button>
</van-field>
</van-cell-group>
```
### API
Filed 默认支持 Input 标签所有的原生属性,比如 `maxlength``placeholder``readonly``autofocus`
@ -115,4 +135,5 @@ Filed 默认支持 Input 标签所有的原生事件,如 `focus`、`blur`、`k
| 名称 | 说明 |
|-----------|-----------|
| icon | 自定义icon |
| icon | 自定义输入框尾部图标 |
| button | 自定义输入框尾部按钮 |

View File

@ -1,17 +1,14 @@
<template>
<cell
:title="label"
:center="center"
:required="required"
class="van-field"
:class="{
'van-field--has-textarea': type === 'textarea',
'van-field--nolabel': !label,
'van-field--disabled': $attrs.disabled,
'van-field--error': error,
'van-field--border': border,
'van-field--autosize': autosize,
'van-field--has-icon': hasIcon,
'van-hairline--surround': border
'van-field--min-height': type === 'textarea' && !autosize,
'van-field--has-icon': hasIcon
}"
>
<textarea
@ -45,6 +42,9 @@
<icon :name="icon" />
</slot>
</div>
<div class="van-field__button" v-if="$slots.button" slot="extra">
<slot name="button" />
</div>
</cell>
</template>
@ -66,6 +66,7 @@ export default create({
icon: String,
label: String,
error: Boolean,
center: Boolean,
border: Boolean,
required: Boolean,
autosize: [Boolean, Object],

View File

@ -75,6 +75,10 @@
}
}
&--center {
align-items: center;
}
&__right-icon {
position: absolute;
top: 50%;

View File

@ -1,10 +1,43 @@
@import './common/var.css';
.van-field {
width: 100%;
.van-cell__title {
width: 90px;
min-width: 90px;
}
.van-cell__value {
position: relative;
}
&__control {
border: 0;
padding: 0;
display: block;
width: 100%;
resize: none;
box-sizing: border-box;
&:disabled {
opacity: 1;
color: $gray-darker;
background-color: transparent;
}
}
&__icon {
position: absolute;
right: 0;
top: 50%;
padding: 10px 0 10px 10px;
transform: translate3d(0, -50%, 0);
.van-icon {
display: block;
}
}
&__button {
padding-left: 10px;
}
&__error-message {
@ -13,23 +46,6 @@
text-align: left;
}
&--has-textarea {
.van-field__control {
min-height: 60px;
}
}
&--nolabel {
.van-cell__title {
display: none;
}
.van-cell__value {
width: 100%;
padding-left: 0;
}
}
&--disabled {
.van-field__control {
color: $gray-dark;
@ -45,54 +61,15 @@
}
}
&--border {
&--min-height {
.van-field__control {
padding-left: 10px;
}
&::after {
border-radius: 2px;
}
}
&--autosize {
.van-field__control {
min-height: 0;
min-height: 60px;
}
}
&--has-icon {
.van-field__control {
width: 90%;
}
}
&__control {
border: 0;
font-size: 14px;
line-height: 24px;
height: 24px;
padding: 0;
display: block;
width: 100%;
resize: none;
&:disabled {
opacity: 1;
color: $gray-darker;
background-color: transparent;
}
}
&__icon {
position: absolute;
right: 0;
top: 50%;
transform: translate3d(0, -50%, 0);
padding: 10px;
.van-icon {
display: block;
padding-right: 20px;
}
}
}

View File

@ -19,18 +19,6 @@ describe('Field', () => {
expect(wrapper.hasClass('van-field')).to.be.true;
});
it('create a border field', () => {
wrapper = mount(Field, {
propsData: {
type: 'text',
border: true
}
});
expect(wrapper.hasClass('van-field')).to.be.true;
expect(wrapper.hasClass('van-field--border')).to.be.true;
});
it('create a text field with initialize value', (done) => {
wrapper = mount(Field, {
propsData: {
@ -69,14 +57,12 @@ describe('Field', () => {
it('create a textarea field', (done) => {
wrapper = mount(Field, {
propsData: {
type: 'textarea',
autosize: true
type: 'textarea'
}
});
setTimeout(() => {
expect(wrapper.hasClass('van-field')).to.be.true;
expect(wrapper.hasClass('van-field--has-textarea')).to.be.true;
expect(wrapper.hasClass('van-field--min-height')).to.be.true;
done();
}, 50);
});
@ -93,9 +79,6 @@ describe('Field', () => {
wrapper.vm.value = val;
});
expect(wrapper.hasClass('van-field')).to.be.true;
expect(wrapper.hasClass('van-field--autosize')).to.be.true;
const textarea = wrapper.find('.van-field__control')[0];
const textareaElement = textarea.element;
const textAreaDiff = (parseInt(textareaElement.style.paddingBottom, 10) +
@ -128,9 +111,6 @@ describe('Field', () => {
wrapper.vm.value = val;
});
expect(wrapper.hasClass('van-field')).to.be.true;
expect(wrapper.hasClass('van-field--autosize')).to.be.true;
const textarea = wrapper.find('.van-field__control')[0];
const textareaElement = textarea.element;