mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
159 lines
3.1 KiB
Vue
159 lines
3.1 KiB
Vue
<template>
|
|
<cell
|
|
:icon="leftIcon"
|
|
:title="label"
|
|
:center="center"
|
|
:border="border"
|
|
:required="required"
|
|
: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="textarea"
|
|
:class="b('control')"
|
|
:value="value"
|
|
/>
|
|
<input
|
|
v-else
|
|
v-bind="$attrs"
|
|
v-on="listeners"
|
|
:class="b('control')"
|
|
:type="type"
|
|
:value="value"
|
|
>
|
|
<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>
|
|
|
|
<script>
|
|
import create from '../utils/create';
|
|
import { isObj } from '../utils';
|
|
|
|
export default create({
|
|
name: 'field',
|
|
|
|
inheritAttrs: false,
|
|
|
|
props: {
|
|
value: [String, Number],
|
|
icon: String,
|
|
label: String,
|
|
error: Boolean,
|
|
center: Boolean,
|
|
leftIcon: String,
|
|
required: Boolean,
|
|
onIconClick: Function,
|
|
autosize: [Boolean, Object],
|
|
errorMessage: String,
|
|
type: {
|
|
type: String,
|
|
default: 'text'
|
|
},
|
|
border: {
|
|
type: Boolean,
|
|
default: true
|
|
}
|
|
},
|
|
|
|
watch: {
|
|
value() {
|
|
this.$nextTick(this.adjustSize);
|
|
}
|
|
},
|
|
|
|
mounted() {
|
|
this.$nextTick(this.adjustSize);
|
|
},
|
|
|
|
computed: {
|
|
showIcon() {
|
|
return this.$slots.icon || (this.icon && this.value !== '' && this.isDef(this.value));
|
|
},
|
|
|
|
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 && this.onIconClick();
|
|
},
|
|
|
|
onKeypress(event) {
|
|
if (this.type === 'number') {
|
|
const { keyCode } = event;
|
|
const allowPoint = String(this.value).indexOf('.') === -1;
|
|
const isValidKey = (keyCode >= 48 && keyCode <= 57) || (keyCode === 46 && allowPoint) || keyCode === 45;
|
|
if (!isValidKey) {
|
|
event.preventDefault();
|
|
}
|
|
}
|
|
this.$emit('keypress', event);
|
|
},
|
|
|
|
adjustSize() {
|
|
if (!(this.type === 'textarea' && this.autosize)) {
|
|
return;
|
|
}
|
|
|
|
const el = this.$refs.textarea;
|
|
/* istanbul ignore if */
|
|
if (!el) {
|
|
return;
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
if (height) {
|
|
el.style.height = height + 'px';
|
|
}
|
|
}
|
|
}
|
|
});
|
|
</script>
|