UNPKG

jobsys-mpower

Version:

Enhanced component based on Taro & NutUI

124 lines (106 loc) 3.14 kB
import { computed, defineComponent, getCurrentInstance, reactive, watch } from "vue" import { defaultFieldProps, defaultFieldSlots } from "../utils" import { omit, pick } from "lodash-es" import { Issue } from "@nutui/icons-vue-taro" /** * MpField 输入框 * @version 1.0.0 */ export default defineComponent({ name: "MpField", props: { ...defaultFieldProps, /** * 输入框内容 */ modelValue: { type: [String, Number, Array, Object, Boolean], default: () => "" }, /** * 输入框类型, 支持原生 input 标签的所有 */ type: { type: String, default: "" }, /** * 是否作为 Picker 的 Trigger */ mask: { type: Boolean, default: false }, }, emits: ["update:modelValue", "click"], setup(props, { slots, emit }) { const instance = getCurrentInstance() const displayText = instance.parent?.parent?.exposed?.displayText const state = reactive({ value: props.mask ? displayText : props.modelValue, showHelp: false, }) watch( () => props.modelValue, () => { state.value = props.modelValue }, ) const isLink = computed(() => (props.mask && !props.disabled && !props.readonly ? true : props.isLink)) const isReadonly = computed(() => (props.mask ? true : props.readonly)) const onUpdateValue = (value) => { emit("update:modelValue", value) } /****************** render **********************/ const labelElem = () => ( <div class={"mp-field__label"}> <text>{props.label || slots.label?.()}</text> <nut-popover v-model:visible={state.showHelp} theme={"dark"} placement={"bottom-start"}> {{ content: () => <div class={"mp-field__help"}>{props.help}</div>, reference: () => props.help ? ( <text class={"mp-field__help-handler"}> <Issue /> </text> ) : null, }} </nut-popover> </div> ) const inputElem = () => { let inputSlots = omit(slots, Object.keys(defaultFieldSlots)) let InputElem = slots.input ? slots.input() : null if (Object.keys(inputSlots).length) { if (InputElem.length > 1) { console.warn("More than one root element wrapped in MpField with input slots!") } InputElem = InputElem[0] return <InputElem>{inputSlots}</InputElem> } return InputElem } return () => { let fieldSlots = pick(slots, Object.keys(defaultFieldSlots)) if (!fieldSlots.label) { fieldSlots.label = labelElem } if (fieldSlots.input) { fieldSlots.input = inputElem } return ( <div class={`mp-field`}> <nut-input v-model={state.value} type={props.type} name={props.name} placeholder={props.placeholder} readonly={isReadonly.value} disabled={props.disabled} required={props.required} isLink={isLink.value} rules={props.rules} onClickInput={() => emit("click")} onUpdate:modelValue={onUpdateValue} {...props.fieldProps} > {{ ...fieldSlots, }} </nut-input> </div> ) } }, })