UNPKG

@form-create/core

Version:

FormCreate低代码表单渲染引擎,可以通过 JSON 生成具有动态渲染、数据收集、验证和提交功能的低代码表单。支持6个UI框架,适配移动端,并且支持生成任何 Vue 组件。

170 lines (164 loc) 6.14 kB
import extend from '@form-create/utils/lib/extend'; import {$set} from '@form-create/utils/lib/modify'; import is, {hasProperty} from '@form-create/utils/lib/type'; import {invoke} from '../frame/util'; import toArray from '@form-create/utils/lib/toarray'; export default function useInput(Handler) { extend(Handler.prototype, { getValue(ctx) { if (is.Undef(ctx.cacheValue)) { ctx.cacheValue = ctx.parser.toValue(this.getFormData(ctx), ctx); } return ctx.cacheValue; }, setValue(ctx, value, formValue, setFlag) { if (ctx.deleted) return; ctx.cacheValue = value; this.changeStatus = true; this.nextRefresh(); this.$render.clearCache(ctx); this.setFormData(ctx, formValue); this.syncValue(); this.valueChange(ctx, value); this.vm.$emit('change', ctx.field, value, ctx.origin, this.api, setFlag || false); this.effect(ctx, 'value'); this.emitEvent('change', ctx.field, value, { rule: ctx.origin, api: this.api, setFlag: setFlag || false }) }, onInput(ctx, value) { let val; if (ctx.input && (this.isQuote(ctx, val = ctx.parser.toValue(value, ctx)) || this.isChange(ctx, val))) { this.setValue(ctx, val, value); } }, setFormData(ctx, value) { $set(this.formData, ctx.id, value === null ? undefined : value); }, getFormData(ctx) { return this.formData[ctx.id]; }, validate() { toEmpty(this.vm.validate); this.fields().forEach(id => { this.fieldCtx[id].forEach(ctx => { this.vm.validate[ctx.id] = toArray(ctx.rule.validate); }); }); return this.vm.validate; }, syncForm() { toEmpty(this.form); Object.defineProperties(this.form, this.fields().reduce((initial, field) => { const ctx = this.getFieldCtx(field); const handle = this.valueHandle(ctx); handle.configurable = true; initial[field] = handle; return initial; }, this.options.appendValue !== false ? Object.keys(this.appendData).reduce((initial, field) => { initial[field] = { enumerable: true, configurable: true, get: () => { return this.appendData[field]; }, set: (val) => { this.appendData[field] = val; } } return initial; }, {}) : {})); this.syncValue(); }, valueHandle(ctx) { return { enumerable: true, get: () => { return this.getValue(ctx); }, set: (value) => { if (this.isChange(ctx, value)) { this.setValue(ctx, value, ctx.parser.toFormValue(value, ctx), true); } } }; }, appendValue(rule) { if (!rule.field || !hasProperty(this.appendData, rule.field)) return; rule.value = this.appendData[rule.field]; delete this.appendData[rule.field]; }, addSubForm(ctx, subForm) { this.subForm[ctx.id] = subForm; }, deferSyncValue(fn, sync) { if (!this.deferSyncFn) { this.deferSyncFn = fn; } if (!this.deferSyncFn.sync) { this.deferSyncFn.sync = sync; } invoke(fn); if (this.deferSyncFn === fn) { this.deferSyncFn = null; if (fn.sync) { this.syncValue(); } } }, syncValue() { if (this.deferSyncFn) { return this.deferSyncFn.sync = true; } this.vm._updateValue({...(this.options.appendValue !== false ? this.appendData : {}), ...this.form}); }, isChange(ctx, value) { return JSON.stringify(ctx.rule.value, strFn) !== JSON.stringify(value === null ? undefined : value, strFn); }, isQuote(ctx, value) { return (is.Object(value) || Array.isArray(value)) && value === ctx.rule.value; }, refreshUpdate(ctx, val, origin, field) { if (is.Function(ctx.rule.update)) { const state = invoke(() => ctx.rule.update(val, ctx.origin, this.api, { origin: origin || 'change', linkField: field })); if (state === undefined) return; ctx.rule.hidden = state === true; } }, valueChange(ctx, val) { this.refreshRule(ctx, val); this.bus.$emit('change-' + ctx.field, val); }, refreshRule(ctx, val, origin, field) { if (this.refreshControl(ctx)) { this.$render.clearCacheAll(); this.loadRule(); this.vm.$emit('update', this.api); this.refresh(); } this.refreshUpdate(ctx, val, origin, field); }, appendLink(ctx) { const link = ctx.rule.link; is.trueArray(link) && link.forEach(field => { const fn = () => this.refreshRule(ctx, ctx.rule.value, 'link', field); this.bus.$on('change-' + field, fn); ctx.linkOn.push(() => this.bus.$off('change-' + field, fn)); }); }, fields() { return Object.keys(this.fieldCtx); }, }); } function strFn(key, val) { return typeof val === 'function' ? '' + val : val; } function toEmpty(obj) { Object.keys(obj).forEach(k => delete obj[k]); }