UNPKG

magiccube-vue3

Version:

vue3-js版组件库

104 lines (91 loc) 2.98 kB
import { ref, nextTick, computed, watchEffect, onMounted, getCurrentInstance } from 'vue' import getFormValidMethod from '../../utils/form-valid' const Textarea = { name: 'McTextarea', props: { modelValue: [String], max: { type: Number, default: () => null }, placeholder: { type: String, default: () => '请输入' }, rows: { type: Number, default: 4 }, readonly: Boolean, disabled: Boolean, }, emits: ['update:modelValue', 'focus', 'blur', 'change'], setup(props, { emit }) { const count = ref(0) const isFocus = ref(false) const instance = getCurrentInstance() const { fieldName, validator, errorMessage } = getFormValidMethod(instance) const fieldError = computed(() => { return fieldName && errorMessage?.value ? errorMessage.value[fieldName] : '' }) const handleInput = () => { nextTick(() => { count.value = model.value.length emit('change', props.modelValue) validator && validator('change', model.value) }) } const handleFocus = () => { isFocus.value = true emit('focus') } const handleBlur = () => { isFocus.value = false emit('blur') validator && validator('blur', model.value) } const model = computed({ set(val) { let _val = val if (props.max && val.length > props.max) _val = val.substring(0, props.max) emit('update:modelValue', _val) }, get() { return props.modelValue || '' } }) watchEffect(() => { count.value = props.modelValue?.length || 0 }) onMounted(() => { count.value = props.modelValue ? props.modelValue.length : 0 }) return () => ( <div class={{ 'mc-textarea': true, 'focus': isFocus.value, 'disabled': props.disabled, 'error': Boolean(fieldError.value) }}> <textarea v-model={model.value} {...props} maxlength={props.max} onInput={handleInput} onFocus={handleFocus} onBlur={handleBlur}></textarea> { props.max ? ( <div class="mc-textarea__count"> <em>{count.value || 0}</em> / {props.max} </div> ) : '' } </div> ) } } Textarea.install = (app) => { app.component(Textarea.name, Textarea) } const McTextarea = Textarea export { McTextarea, McTextarea as default }