114 lines
2.3 KiB
Vue
114 lines
2.3 KiB
Vue
<template>
|
||
<view class="textarea-row">
|
||
<view class="form-row__label">
|
||
{{ name }}<text v-if="required" class="form-cell--required"></text>
|
||
</view>
|
||
<view class="mt-10">
|
||
<textarea
|
||
:disabled="disableChange"
|
||
:value="value"
|
||
class="form-textarea"
|
||
:style="textareaStyle"
|
||
:placeholder="placeholder"
|
||
placeholder-class="form__placeholder"
|
||
:maxlength="wordLimit"
|
||
:auto-height="autoHeight"
|
||
@input="change($event)" />
|
||
<view v-if="wordLimit > 0" class="form-textarea__count">
|
||
{{ value && value.length ? value.length : 0 }} / {{ wordLimit }}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
<script setup>
|
||
import { computed } from 'vue';
|
||
|
||
const emits = defineEmits(['change']);
|
||
const props = defineProps({
|
||
form: {
|
||
type: Object,
|
||
default: () => ({})
|
||
},
|
||
name: {
|
||
default: ''
|
||
},
|
||
required: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
title: {
|
||
default: ''
|
||
},
|
||
disableChange: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
wordLimit: {
|
||
type: [Number, String],
|
||
default: 100
|
||
},
|
||
autoHeight: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
rows: {
|
||
type: [Number, String],
|
||
default: 3
|
||
}
|
||
})
|
||
|
||
const placeholder = computed(() => `请输入${props.name || ''}`)
|
||
const value = computed(() => {
|
||
const v = props.form?.[props.title];
|
||
return v === undefined || v === null ? '' : String(v);
|
||
})
|
||
const wordLimit = computed(() => {
|
||
if (typeof props.wordLimit === 'string' && Number(props.wordLimit) > 0) {
|
||
return Math.ceil(Number(props.wordLimit))
|
||
}
|
||
if (typeof props.wordLimit === 'number' && props.wordLimit > 0) {
|
||
return props.wordLimit
|
||
}
|
||
return 100
|
||
})
|
||
|
||
const textareaStyle = computed(() => {
|
||
const rowCount = typeof props.rows === 'number' ? props.rows : (Number(props.rows) || 3);
|
||
// 每行大约42rpx高度(28rpx字体 + 14rpx行距)
|
||
const minHeight = rowCount * 42;
|
||
return `min-height: ${minHeight}rpx;`;
|
||
})
|
||
|
||
function change(e) {
|
||
emits('change', {
|
||
title: props.title,
|
||
value: e.detail.value
|
||
})
|
||
}
|
||
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.textarea-row {
|
||
padding: 24rpx 30rpx;
|
||
border-bottom: 1px solid #eee;
|
||
font-size: 28rpx;
|
||
}
|
||
|
||
.form-textarea {
|
||
width: 100%;
|
||
font-size: 28rpx;
|
||
border: 1px solid #eee;
|
||
padding: 20rpx;
|
||
border-radius: 8rpx;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.form-textarea__count {
|
||
padding-top: 20rpx;
|
||
text-align: right;
|
||
color: #666;
|
||
font-size: 24rpx;
|
||
}
|
||
</style>
|