UNPKG

jobsys-mpower

Version:

Enhanced component based on Taro & NutUI

265 lines (243 loc) 7.94 kB
import { inject } from "vue" import { MP__UPLOADER } from "../provider/MpProvider.jsx" import { isBoolean, isFunction, isString, pick } from "lodash-es" import MpField from "./MpField.jsx" import MpSelect from "./MpSelect.jsx" import MpDate from "./MpDate.jsx" import MpSwitch from "./MpSwitch.jsx" import MpCheckbox from "./MpCheckbox.jsx" import MpRadio from "./MpRadio.jsx" import MpDatetime from "./MpDatetime.jsx" import MpNumber from "./MpNumber.jsx" import MpRate from "./MpRate.jsx" import MpSlider from "./MpSlider.jsx" import MpAddress from "./MpAddress.jsx" import MpCascader from "./MpCascader.jsx" import MpTime from "./MpTime.jsx" import MpFieldUploader from "./MpFieldUploader.jsx" /** * * @param item * @param submitForm * @param props * @param slots * @return {*|JSX.Element} */ const render = (item, submitForm, { props, slots }) => { const uploaderProvider = inject(MP__UPLOADER, () => ({})) if (item.type === "slot" && slots[item.key]) { return slots[item.key]({ submitForm }) } let renderItem = null const pickerTypes = ["select", "date", "datetime", "time", "address", "cascade"] const isPicker = pickerTypes.includes(item.type) // 处理 hidden if ((isFunction(item.hidden) && item.hidden(submitForm)) || (isBoolean(item.hidden) && item.hidden)) { return null } // MpField 的 props let fieldProps = pick(item, ["placeholder", "help", "required", "disabled", "rules", "readonly", "isLink", "fieldProps"]) fieldProps.required = isFunction(fieldProps.required) ? fieldProps.required(submitForm) : fieldProps.required fieldProps.disabled = isFunction(fieldProps.disabled) ? fieldProps.disabled(submitForm) : fieldProps.disabled fieldProps = { readonly: props.readonly, disabled: props.disabled, ...fieldProps } if (fieldProps.readonly || fieldProps.disabled) { fieldProps.required = false } fieldProps.label = item.title fieldProps.name = item.key fieldProps.placeholder = fieldProps.placeholder || (isPicker ? `请选择${item.title}` : `请填写${item.title}`) fieldProps.rules = fieldProps.rules?.length ? fieldProps.rules.map((rule) => { if (rule.pattern) { return { ...rule, pattern: new RegExp(rule.pattern), } } return { ...rule } }) : [] // 具体组件的 props const componentProps = pick(item, ["options", "defaultProps"]) //混合了Field和input slot组件的slots组合 const componentSlots = item.defaultSlots || {} item.type = item.type ? item.type.toLowerCase() : item.type //特殊:readonly 的情况下不显示 required if (fieldProps.required) { fieldProps.rules.push({ required: true, message: isPicker ? `请选择${item.title}` : `请填写${item.title}`, trigger: isPicker ? "onChange" : "onBlur", //特意 }) } //特殊:readonly 情况下不显示 placeholder if (fieldProps.readonly || fieldProps.disabled) { fieldProps.placeholder = "--" } if (item.customRender) { renderItem = item.customRender({ submitForm, item }) if (!renderItem) { return null } } else if (item.match) { // 匹配模式, 合并选项后需要移除 match const matchItem = { ...item, ...item.match(submitForm), match: null } return render(matchItem, submitForm, { props, slots }) } else { switch (item.type) { case "select": renderItem = ( <MpSelect v-model={submitForm[item.key]} {...componentProps} {...fieldProps}> {componentSlots} </MpSelect> ) break case "date": renderItem = ( <MpDate v-model={submitForm[item.key]} {...componentProps} {...fieldProps}> {componentSlots} </MpDate> ) break case "datetime": renderItem = ( <MpDatetime v-model={submitForm[item.key]} {...componentProps} {...fieldProps}> {componentSlots} </MpDatetime> ) break case "time": renderItem = ( <MpTime v-model={submitForm[item.key]} {...componentProps} {...fieldProps}> {componentSlots} </MpTime> ) break case "switch": renderItem = ( <MpSwitch v-model={submitForm[item.key]} {...componentProps} {...fieldProps}> {componentSlots} </MpSwitch> ) break case "radio": renderItem = ( <MpRadio v-model={submitForm[item.key]} {...componentProps} {...fieldProps}> {componentSlots} </MpRadio> ) break case "checkbox": renderItem = ( <MpCheckbox v-model={submitForm[item.key]} {...componentProps} {...fieldProps}> {componentSlots} </MpCheckbox> ) break case "address": renderItem = ( <MpAddress v-model={submitForm[item.key]} {...fieldProps}> {componentSlots} </MpAddress> ) break case "cascade": renderItem = ( <MpCascader v-model={submitForm[item.key]} {...componentProps} {...fieldProps}> {componentSlots} </MpCascader> ) break case "number": renderItem = ( <MpNumber v-model={submitForm[item.key]} {...componentProps} {...fieldProps}> {componentSlots} </MpNumber> ) break case "rate": renderItem = ( <MpRate v-model={submitForm[item.key]} {...componentProps} {...fieldProps}> {componentSlots} </MpRate> ) break case "slider": renderItem = ( <MpSlider v-model={submitForm[item.key]} {...componentProps} {...fieldProps}> {componentSlots} </MpSlider> ) break case "uploader": renderItem = ( <MpFieldUploader v-model={submitForm[item.key]} {...componentProps} {...fieldProps}> {componentSlots} </MpFieldUploader> ) if (item.required) { if (!Object.keys(uploaderProvider).length) { console.error("请在根组件中注入 NEWBIE_UPLOADER 配置项") renderItem = null break } /*if (item.defaultProps?.maxNum && item.defaultProps?.maxNum > 1) { rules.type = "array" rules.message = `请上传${item.title}` } else { rules = { type: "object", required: true, message: `请上传${item.title}`, fields: { [uploaderProvider.path]: { type: "string", required: true, message: `请上传${item.title}`, }, }, } }*/ } break /* case "html": renderItem = Fields.createHtml(item, submitForm) break case "text": renderItem = Fields.createText(item, submitForm) break case "group": renderItem = Fields.createGroup(item, submitForm, { provider: { uploaderProvider } }) break*/ case "textarea": fieldProps.type = "textarea" renderItem = ( <MpField v-model={submitForm[item.key]} {...fieldProps}> {componentSlots} </MpField> ) break case "password": fieldProps.type = "password" renderItem = ( <MpField v-model={submitForm[item.key]} {...fieldProps}> {componentSlots} </MpField> ) break default: renderItem = ( <MpField v-model={submitForm[item.key]} {...fieldProps}> {componentSlots} </MpField> ) break } } const formItem = [renderItem] if (item.break) { formItem.unshift(<nut-divider {...props.dividerProps}>{() => (isString(item.break) ? item.break : null)}</nut-divider>) } return formItem } export default render