vant/packages/field/index.vue

148 lines
2.9 KiB
Vue

<template>
<cell
:title="label"
: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
}"
>
<textarea
v-if="type === 'textarea'"
v-bind="$attrs"
v-on="listeners"
ref="textarea"
class="van-field__control"
:value="value"
/>
<input
v-else
v-bind="$attrs"
v-on="listeners"
class="van-field__control"
:type="type"
:value="value"
>
<div
v-if="errorMessage"
v-text="errorMessage"
class="van-field__error-message"
/>
<div
v-if="hasIcon"
v-show="$slots.icon || value"
class="van-field__icon"
@touchstart.prevent="onClickIcon"
>
<slot name="icon">
<icon :name="icon" />
</slot>
</div>
</cell>
</template>
<script>
import { create, isObj } from '../utils';
export default create({
name: 'field',
inheritAttrs: false,
props: {
type: {
type: String,
default: 'text'
},
value: {},
icon: String,
label: String,
error: Boolean,
border: Boolean,
required: Boolean,
autosize: [Boolean, Object],
errorMessage: String,
onIconClick: {
type: Function,
default: () => {}
}
},
watch: {
value() {
this.$nextTick(this.adjustSize);
}
},
mounted() {
this.$nextTick(this.adjustSize);
},
computed: {
hasIcon() {
return this.$slots.icon || this.icon;
},
listeners() {
return {
...this.$listeners,
input: this.onInput,
keypress: this.onKeypress
};
}
},
methods: {
onInput(event) {
this.$emit('input', event.target.value);
},
onClickIcon() {
this.$emit('click-icon');
this.onIconClick();
},
onKeypress(event) {
if (this.type === 'number') {
const { keyCode } = event;
const allowPoint = this.value.indexOf('.') === -1;
const isValidKey = (keyCode >= 48 && keyCode <= 57) || (keyCode === 46 && allowPoint);
if (!isValidKey) {
event.preventDefault();
}
}
this.$emit('keypress', event);
},
adjustSize() {
if (!(this.type === 'textarea' && this.autosize)) {
return;
}
const el = this.$refs.textarea;
el.style.height = 'auto';
let height = el.scrollHeight;
if (isObj(this.autosize)) {
const { maxHeight, minHeight } = this.autosize;
if (maxHeight) {
height = Math.min(height, maxHeight);
}
if (minHeight) {
height = Math.max(height, minHeight);
}
}
el.style.height = height + 'px';
}
}
});
</script>