mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
119 lines
2.4 KiB
Vue
119 lines
2.4 KiB
Vue
<template>
|
|
<van-cell
|
|
:title="label"
|
|
:required="required"
|
|
:class="['van-field', {
|
|
'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
|
|
}]">
|
|
<textarea
|
|
v-if="type === 'textarea'"
|
|
v-bind="$attrs"
|
|
v-on="$listeners"
|
|
ref="textarea"
|
|
class="van-field__control"
|
|
:value="value"
|
|
@input="onInput"
|
|
/>
|
|
<input
|
|
v-else
|
|
v-bind="$attrs"
|
|
v-on="$listeners"
|
|
class="van-field__control"
|
|
:type="type"
|
|
:value="value"
|
|
@input="onInput"
|
|
/>
|
|
<div
|
|
v-if="hasIcon"
|
|
v-show="$slots.icon || value"
|
|
class="van-field__icon"
|
|
@touchstart.prevent="onClickIcon"
|
|
>
|
|
<slot name="icon">
|
|
<van-icon :name="icon" />
|
|
</slot>
|
|
</div>
|
|
</van-cell>
|
|
</template>
|
|
|
|
<script>
|
|
import Cell from '../cell';
|
|
import Icon from '../icon';
|
|
|
|
const VALID_TYPES = ['text', 'number', 'email', 'url', 'tel', 'date', 'time', 'datetime', 'password', 'textarea'];
|
|
|
|
export default {
|
|
name: 'van-field',
|
|
|
|
components: {
|
|
[Cell.name]: Cell,
|
|
[Icon.name]: Icon
|
|
},
|
|
|
|
props: {
|
|
type: {
|
|
type: String,
|
|
default: 'text',
|
|
validator: value => VALID_TYPES.indexOf(value) > -1
|
|
},
|
|
value: {},
|
|
icon: String,
|
|
label: String,
|
|
error: Boolean,
|
|
required: Boolean,
|
|
border: Boolean,
|
|
autosize: Boolean,
|
|
onIconClick: {
|
|
type: Function,
|
|
default: () => {}
|
|
}
|
|
},
|
|
|
|
watch: {
|
|
value() {
|
|
if (this.autosize && this.type === 'textarea') {
|
|
this.$nextTick(this.adjustSize);
|
|
}
|
|
}
|
|
},
|
|
|
|
mounted() {
|
|
if (this.autosize && this.type === 'textarea') {
|
|
const el = this.$refs.textarea;
|
|
el.style.height = el.scrollHeight + 'px';
|
|
el.style.overflowY = 'hidden';
|
|
}
|
|
},
|
|
|
|
computed: {
|
|
hasIcon() {
|
|
return this.$slots.icon || this.icon;
|
|
}
|
|
},
|
|
|
|
methods: {
|
|
onInput(event) {
|
|
this.$emit('input', event.target.value);
|
|
},
|
|
|
|
onClickIcon() {
|
|
this.$emit('click-icon');
|
|
this.onIconClick();
|
|
},
|
|
|
|
adjustSize() {
|
|
const el = this.$refs.textarea;
|
|
el.style.height = 'auto';
|
|
el.style.height = el.scrollHeight + 'px';
|
|
}
|
|
}
|
|
};
|
|
</script>
|