UNPKG

vxe-pc-ui

Version:
339 lines (338 loc) 12.8 kB
import { defineComponent, h, ref, computed, reactive, inject, nextTick, watch, createCommentVNode } from 'vue'; import XEUtils from 'xe-utils'; import { getConfig, getIcon, getI18n, createEvent, useSize } from '../../ui'; import { getFuncText } from '../../ui/src/utils'; import { getSlotVNs } from '../..//ui/src/vn'; export default defineComponent({ name: 'VxePasswordInput', props: { modelValue: String, immediate: { type: Boolean, default: true }, name: String, clearable: { type: Boolean, default: () => getConfig().passwordInput.clearable }, readonly: Boolean, disabled: Boolean, maxLength: [String, Number], placeholder: String, autoComplete: { type: String, default: 'off' }, className: String, size: { type: String, default: () => getConfig().passwordInput.size || getConfig().size }, prefixIcon: String, suffixIcon: String, controls: { type: Boolean, default: () => getConfig().passwordInput.controls }, // 已废弃 autocomplete: String }, emits: [ 'update:modelValue', 'input', 'change', 'click', 'focus', 'blur', 'clear', 'toggle-visible', 'prefix-click', 'suffix-click' ], setup(props, context) { const { emit, slots } = context; const $xeForm = inject('$xeForm', null); const formItemInfo = inject('xeFormItemInfo', null); const xID = XEUtils.uniqueId(); const { computeSize } = useSize(props); const reactData = reactive({ showPwd: false, isActivated: false, inputValue: props.modelValue }); const refElem = ref(); const refInputTarget = ref(); const refMaps = { refElem, refInput: refInputTarget }; const $xePasswordInput = { xID, props, context, reactData, getRefMaps: () => refMaps }; let passwordInputMethods = {}; const computeIsClearable = computed(() => { return props.clearable; }); const computeInpReadonly = computed(() => { const { readonly } = props; return readonly; }); const computeInpPlaceholder = computed(() => { const { placeholder } = props; if (placeholder) { return getFuncText(placeholder); } const globalPlaceholder = getConfig().passwordInput.placeholder; if (globalPlaceholder) { return getFuncText(globalPlaceholder); } return getI18n('vxe.base.pleaseInput'); }); const computeInputType = computed(() => { const { showPwd } = reactData; if (showPwd) { return 'text'; } return 'password'; }); const computeInpImmediate = computed(() => { const { immediate } = props; return immediate; }); const triggerEvent = (evnt) => { const { inputValue } = reactData; passwordInputMethods.dispatchEvent(evnt.type, { value: inputValue }, evnt); }; const emitInputEvent = (value, evnt) => { const inpImmediate = computeInpImmediate.value; reactData.inputValue = value; if (inpImmediate) { handleChange(value, evnt); } else { passwordInputMethods.dispatchEvent('input', { value }, evnt); } }; const inputEvent = (evnt) => { const inputElem = evnt.target; const value = inputElem.value; emitInputEvent(value, evnt); }; const handleChange = (value, evnt) => { reactData.inputValue = value; emit('update:modelValue', value); passwordInputMethods.dispatchEvent('input', { value }, evnt); if (XEUtils.toValueString(props.modelValue) !== value) { passwordInputMethods.dispatchEvent('change', { value }, evnt); // 自动更新校验状态 if ($xeForm && formItemInfo) { $xeForm.triggerItemEvent(evnt, formItemInfo.itemConfig.field, value); } } }; const changeEvent = (evnt) => { triggerEvent(evnt); const { inputValue } = reactData; // 自动更新校验状态 if ($xeForm && formItemInfo) { $xeForm.triggerItemEvent(evnt, formItemInfo.itemConfig.field, inputValue); } }; const focusEvent = (evnt) => { reactData.isActivated = true; triggerEvent(evnt); }; const blurEvent = (evnt) => { const { inputValue } = reactData; const value = inputValue; passwordInputMethods.dispatchEvent('blur', { value }, evnt); // 自动更新校验状态 if ($xeForm && formItemInfo) { $xeForm.triggerItemEvent(evnt, formItemInfo.itemConfig.field, value); } }; const passwordToggleEvent = (evnt) => { const { readonly, disabled } = props; const { showPwd } = reactData; if (!disabled && !readonly) { reactData.showPwd = !showPwd; } passwordInputMethods.dispatchEvent('toggle-visible', { visible: reactData.showPwd }, evnt); }; const clickEvent = (evnt) => { triggerEvent(evnt); }; const clearValueEvent = (evnt, value) => { focus(); handleChange('', evnt); passwordInputMethods.dispatchEvent('clear', { value }, evnt); }; const clickSuffixEvent = (evnt) => { const { disabled } = props; if (!disabled) { const { inputValue } = reactData; passwordInputMethods.dispatchEvent('suffix-click', { value: inputValue }, evnt); } }; const clickPrefixEvent = (evnt) => { const { disabled } = props; if (!disabled) { const { inputValue } = reactData; passwordInputMethods.dispatchEvent('prefix-click', { value: inputValue }, evnt); } }; const renderPasswordIcon = () => { const { showPwd } = reactData; return h('div', { class: 'vxe-password-input--control-icon', onClick: passwordToggleEvent }, [ h('i', { class: ['vxe-password-input--password-icon', showPwd ? getIcon().PASSWORD_INPUT_SHOW_PWD : getIcon().PASSWORD_INPUT_HIDE_PWD] }) ]); }; const renderPrefixIcon = () => { const { prefixIcon } = props; const prefixSlot = slots.prefix; return prefixSlot || prefixIcon ? h('div', { class: 'vxe-password-input--prefix', onClick: clickPrefixEvent }, [ h('div', { class: 'vxe-password-input--prefix-icon' }, prefixSlot ? getSlotVNs(prefixSlot({})) : [ h('i', { class: prefixIcon }) ]) ]) : null; }; const renderSuffixIcon = () => { const { disabled, suffixIcon, controls } = props; const { inputValue } = reactData; const suffixSlot = slots.suffix; const isClearable = computeIsClearable.value; return isClearable || controls || suffixSlot || suffixIcon ? h('div', { class: ['vxe-password-input--suffix', { 'is--clear': isClearable && !disabled && !(inputValue === '' || XEUtils.eqNull(inputValue)) }] }, [ isClearable ? h('div', { class: 'vxe-password-input--clear-icon', onClick: clearValueEvent }, [ h('i', { class: getIcon().INPUT_CLEAR }) ]) : createCommentVNode(), controls ? renderPasswordIcon() : createCommentVNode(), suffixSlot || suffixIcon ? h('div', { class: 'vxe-password-input--suffix-icon', onClick: clickSuffixEvent }, suffixSlot ? getSlotVNs(suffixSlot({})) : [ h('i', { class: suffixIcon }) ]) : createCommentVNode() ]) : null; }; passwordInputMethods = { dispatchEvent(type, params, evnt) { emit(type, createEvent(evnt, { $passwordInput: $xePasswordInput }, params)); }, focus() { const inputElem = refInputTarget.value; reactData.isActivated = true; inputElem.focus(); return nextTick(); }, blur() { const inputElem = refInputTarget.value; inputElem.blur(); reactData.isActivated = false; return nextTick(); }, select() { const inputElem = refInputTarget.value; inputElem.select(); reactData.isActivated = false; return nextTick(); } }; Object.assign($xePasswordInput, passwordInputMethods); watch(() => props.modelValue, (val) => { reactData.inputValue = val; }); const renderVN = () => { const { className, name, disabled, readonly, autocomplete, autoComplete, maxLength } = props; const { inputValue, isActivated } = reactData; const vSize = computeSize.value; const inpReadonly = computeInpReadonly.value; const inputType = computeInputType.value; const inpPlaceholder = computeInpPlaceholder.value; const isClearable = computeIsClearable.value; const prefix = renderPrefixIcon(); const suffix = renderSuffixIcon(); return h('div', { ref: refElem, class: ['vxe-password-input', className, { [`size--${vSize}`]: vSize, 'is--prefix': !!prefix, 'is--suffix': !!suffix, 'is--readonly': readonly, 'is--disabled': disabled, 'is--active': isActivated, 'show--clear': isClearable && !disabled && !(inputValue === '' || XEUtils.eqNull(inputValue)) }], spellcheck: false }, [ prefix || createCommentVNode(), h('div', { class: 'vxe-password-input--wrapper' }, [ h('input', { ref: refInputTarget, class: 'vxe-password-input--inner', value: inputValue, name, type: inputType, placeholder: inpPlaceholder, readonly: inpReadonly, disabled, autocomplete: autocomplete || autoComplete, maxlength: maxLength, onClick: clickEvent, onInput: inputEvent, onChange: changeEvent, onFocus: focusEvent, onBlur: blurEvent }) ]), suffix || createCommentVNode() ]); }; $xePasswordInput.renderVN = renderVN; return $xePasswordInput; }, render() { return this.renderVN(); } });