UNPKG

element-plus

Version:

A Component Library for Vue3.0

199 lines (192 loc) 6.43 kB
import { defineComponent, watch, reactive, toRefs, provide, ref, computed, openBlock, createBlock, renderSlot } from 'vue'; import mitt from 'mitt'; const elFormKey = 'elForm'; const elFormItemKey = 'elFormItem'; const elFormEvents = { addField: 'el.form.addField', removeField: 'el.form.removeField', }; function useFormLabelWidth() { const potentialLabelWidthArr = ref([]); const autoLabelWidth = computed(() => { if (!potentialLabelWidthArr.value.length) return '0'; const max = Math.max(...potentialLabelWidthArr.value); return max ? `${max}px` : ''; }); function getLabelWidthIndex(width) { const index = potentialLabelWidthArr.value.indexOf(width); if (index === -1) { console.warn('[Element Warn][ElementForm]unexpected width ' + width); } return index; } function registerLabelWidth(val, oldVal) { if (val && oldVal) { const index = getLabelWidthIndex(oldVal); potentialLabelWidthArr.value.splice(index, 1, val); } else if (val) { potentialLabelWidthArr.value.push(val); } } function deregisterLabelWidth(val) { const index = getLabelWidthIndex(val); index > -1 && potentialLabelWidthArr.value.splice(index, 1); } return { autoLabelWidth, registerLabelWidth, deregisterLabelWidth, }; } var script = defineComponent({ name: 'ElForm', props: { model: Object, rules: Object, labelPosition: String, labelWidth: String, labelSuffix: { type: String, default: '', }, inline: Boolean, inlineMessage: Boolean, statusIcon: Boolean, showMessage: { type: Boolean, default: true, }, size: String, disabled: Boolean, validateOnRuleChange: { type: Boolean, default: true, }, hideRequiredAsterisk: { type: Boolean, default: false, }, }, emits: ['validate'], setup(props, { emit }) { const formMitt = mitt(); const fields = []; watch(() => props.rules, () => { fields.forEach(field => { field.removeValidateEvents(); field.addValidateEvents(); }); if (props.validateOnRuleChange) { validate(() => ({})); } }); formMitt.on(elFormEvents.addField, field => { if (field) { fields.push(field); } }); formMitt.on(elFormEvents.removeField, field => { if (field.prop) { fields.splice(fields.indexOf(field), 1); } }); const resetFields = () => { if (!props.model) { console.warn('[Element Warn][Form]model is required for resetFields to work.'); return; } fields.forEach(field => { field.resetField(); }); }; const clearValidate = (props = []) => { const fds = props.length ? typeof props === 'string' ? fields.filter(field => props === field.prop) : fields.filter(field => props.indexOf(field.prop) > -1) : fields; fds.forEach(field => { field.clearValidate(); }); }; const validate = (callback) => { if (!props.model) { console.warn('[Element Warn][Form]model is required for validate to work!'); return; } let promise; if (typeof callback !== 'function') { promise = new Promise((resolve, reject) => { callback = function (valid, invalidFields) { if (valid) { resolve(true); } else { reject(invalidFields); } }; }); } if (fields.length === 0) { callback(true); } let valid = true; let count = 0; let invalidFields = {}; for (const field of fields) { field.validate('', (message, field) => { if (message) { valid = false; } invalidFields = Object.assign(Object.assign({}, invalidFields), field); if (++count === fields.length) { callback(valid, invalidFields); } }); } return promise; }; const validateField = (props, cb) => { props = [].concat(props); const fds = fields.filter(field => props.indexOf(field.prop) !== -1); if (!fields.length) { console.warn('[Element Warn]please pass correct props!'); return; } fds.forEach(field => { field.validate('', cb); }); }; const elForm = reactive(Object.assign(Object.assign(Object.assign({ formMitt }, toRefs(props)), { resetFields, clearValidate, validateField, emit }), useFormLabelWidth())); provide(elFormKey, elForm); return { validate, resetFields, clearValidate, validateField, }; }, }); function render(_ctx, _cache, $props, $setup, $data, $options) { return (openBlock(), createBlock("form", { class: ["el-form", [ _ctx.labelPosition ? 'el-form--label-' + _ctx.labelPosition : '', { 'el-form--inline': _ctx.inline } ]] }, [ renderSlot(_ctx.$slots, "default") ], 2 /* CLASS */)) } script.render = render; script.__file = "packages/form/src/form.vue"; script.install = (app) => { app.component(script.name, script); }; const _Form = script; export default _Form; export { elFormEvents, elFormItemKey, elFormKey };