UNPKG

magiccube-vue3

Version:

vue3-js版组件库

187 lines (168 loc) 6.17 kB
import { ref, computed, getCurrentInstance, watch, onMounted, onUnmounted } from 'vue' import getFormValidMethod from '../../utils/form-valid' import CLEAR_ICON from '../../img/icon_clear.svg' const Input = { name: 'McInput', props: { modelValue: [String, Number], type: { type: String, default: 'text' }, name: String, readonly: Boolean, disabled: Boolean, placeholder: { type: String, default: '请输入' }, autofocus: Boolean, clear: Boolean, prefixIcon: String, suffixIcon: String, click: { type: Function, default: () => { } }, errorStatus: Boolean, maxlength: Number, unchecked: Boolean, }, setup(props, { emit, slots }) { const isFocus = ref(false) const mouseIn = ref(false) const inputEl = ref(null) let isPinyinInput = null const instance = getCurrentInstance() const { fieldName, validator, errorMessage } = getFormValidMethod(instance) const fieldError = computed(() => fieldName && errorMessage?.value && !props.unchecked ? errorMessage.value[fieldName] : '') /* 监听外部改变参数 清空校验器报错 */ watch(() => props.modelValue, (n, o) => n && n !== o && validator && validator('change', n)) const model = computed({ get() { return props.modelValue || props.modelValue === 0? props.modelValue : '' }, set(value) { emit('update:modelValue', value) } }) const handleKeyup = (e) => { emit('keyup', e.target.value) if(e.keyCode === 13) { inputEl.value.blur() } } const handleFocus = (e) => { isFocus.value = true emit('focus', e) } const handleBlur = (e) => { model.value = e.target.value isFocus.value = false emit('change', model.value) emit('blur', e) validator && validator('blur', model.value) } const handleClear = (e) => { e.stopPropagation() model.value = '' inputEl.value.focus() emit('clear', e) } const handleInput = (e) => { // 如果是拼音输入需要判断是不是拼音正在输入中 if(isPinyinInput) return model.value = e.target.value validator && validator('change', model.value) } // 拼音输入开始 const handlePinyinInputStart = () => { isPinyinInput = true } // 拼音输入结束 结束后调用emit触发input事件 并进行赋值 const handlePinyinInputEnd = (e) => { isPinyinInput = false model.value = e.target.value validator && validator('change', model.value) emit('input', model.value) } // 监听拼音输入识别器事件compositionstart、compositionupdate、compositionend onMounted(() => { inputEl.value?.addEventListener?.('compositionstart', handlePinyinInputStart) inputEl.value?.addEventListener?.('compositionend', handlePinyinInputEnd) }) onUnmounted(() => { inputEl.value?.removeEventListener?.('compositionstart', handlePinyinInputStart) inputEl.value?.removeEventListener?.('compositionend', handlePinyinInputEnd) }) return () => ( <div class={[ 'mc-input', { 'focus': isFocus.value || mouseIn.value, 'disabled': props.disabled, 'error': Boolean(fieldError.value) || props.errorStatus } ]} onMouseenter={() => mouseIn.value = true} onMouseleave={() => mouseIn.value = false}> { slots.prefix? ( <i class="mc-input__prefix"> {slots.prefix()} </i> ) : props.prefixIcon ? ( <i class="mc-input__prefix"> <img src={props.prefixIcon} /> </i> ) : '' } <input ref={inputEl} class="mc-input__inner" v-model={model.value} type={props.type} {...props} onFocus={handleFocus} onBlur={handleBlur} onClick={props.click} onInput={handleInput} onKeyup={handleKeyup} autocomplete="off" /> { props.clear && mouseIn.value && model.value ? ( <i class="mc-input__clear" onClick={handleClear}> <img src={CLEAR_ICON} /> </i> ) : '' } { slots.suffix? ( <i class={[ 'mc-input__suffix', { 'has-clear': props.clear && mouseIn.value } ]}> {slots.suffix()} </i> ) : props.suffixIcon ? ( <i class={[ 'mc-input__suffix', { 'has-clear': props.clear && mouseIn.value } ]}> <img src={props.suffixIcon} /> </i> ) : '' } </div> ) } } Input.install = (app) => { app.component(Input.name, Input) } const McInput = Input export { McInput, McInput as default }