magiccube-vue3
Version:
vue3-js版组件库
104 lines (91 loc) • 2.98 kB
JavaScript
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 }