UNPKG

@form-create/core

Version:

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

179 lines (170 loc) 7.08 kB
import extend from '@form-create/utils/lib/extend'; import toCase from '@form-create/utils/lib/tocase'; import BaseParser from '../factory/parser'; import {$del} from '@form-create/utils/lib/modify'; import is, {hasProperty} from '@form-create/utils/lib/type'; import {invoke} from '../frame/util'; const noneKey = ['field', 'value', 'vm', 'template', 'name', 'config', 'control', 'inject', 'sync', 'payload', 'optionsTo', 'update', 'component', 'cache']; export default function useContext(Handler) { extend(Handler.prototype, { getCtx(id) { return this.getFieldCtx(id) || this.getNameCtx(id)[0] || this.ctxs[id]; }, getCtxs(id) { return this.fieldCtx[id] || this.nameCtx[id] || (this.ctxs[id] ? [this.ctxs[id]] : []); }, setIdCtx(ctx, key, type) { const field = `${type}Ctx`; if (!this[field][key]) { this[field][key] = [ctx]; } else { this[field][key].push(ctx); } }, rmIdCtx(ctx, key, type) { const field = `${type}Ctx`; const lst = this[field][key]; if (!lst) return false; const flag = lst.splice(lst.indexOf(ctx) >>> 0, 1).length > 0; if (!lst.length) { delete this[field][key]; } return flag; }, getFieldCtx(field) { return (this.fieldCtx[field] || [])[0]; }, getNameCtx(name) { return this.nameCtx[name] || []; }, setCtx(ctx) { let {id, field, name, rule} = ctx; this.ctxs[id] = ctx; name && this.setIdCtx(ctx, name, 'name'); if (!ctx.input) return; this.setIdCtx(ctx, field, 'field'); this.setFormData(ctx, ctx.parser.toFormValue(rule.value, ctx)); if (this.isMounted && !this.reloading) { this.vm.$emit('change', ctx.field, rule.value, ctx.origin, this.api); } }, getParser(ctx) { const list = this.fc.parsers; return list[ctx.originType] || list[toCase(ctx.type)] || list[ctx.trueType] || BaseParser; }, bindParser(ctx) { ctx.setParser(this.getParser(ctx)); }, getType(alias) { const map = this.fc.CreateNode.aliasMap; const type = map[alias] || map[toCase(alias)] || alias; return toCase(type); }, noWatch(fn) { if (!this.noWatchFn) { this.noWatchFn = fn; } invoke(fn); if (this.noWatchFn === fn) { this.noWatchFn = null; } }, watchCtx(ctx) { const vm = this.vm; Object.keys(ctx.rule).filter(k => k[0] !== '_' && k[0] !== '$' && noneKey.indexOf(k) === -1).forEach((key) => { const flag = key === 'children'; ctx.watch.push(vm.$watch(() => ctx.rule[key], (n, o) => { if (this.loading || this.noWatchFn || this.reloading) return; if (flag && ctx.parser.loadChildren === false) { this.$render.clearCache(ctx); this.nextRefresh(); return; } this.watching = true; // if (key === 'hidden') // ctx.updateKey(true); // else if (key === 'link') { ctx.link(); return; } else if (['props', 'on', 'nativeOn', 'deep'].indexOf(key) > -1) { this.parseInjectEvent(ctx.rule, n || {}); if (key === 'props' && ctx.input) { this.setFormData(ctx, ctx.parser.toFormValue(ctx.rule.value, ctx)); } } else if (['emit', 'nativeEmit'].indexOf(key) > -1) this.parseEmit(ctx, key === 'emit'); else if (['prefix', 'suffix'].indexOf(key) > -1) n && this.loadFn(n, ctx.rule); else if (key === 'type') { ctx.updateType(); this.bindParser(ctx); } else if (key === 'children') { const flag = is.trueArray(n); this.deferSyncValue(() => { if (n !== o) { this.rmSub(o, ctx); this.$render.initOrgChildren(); } flag && this.loadChildren(n, ctx); this.vm.$emit('update', this.api); }); } this.$render.clearCache(ctx); this.refresh(); this.watching = false; }, {deep: !flag, sync: flag})); }); this.watchEffect(ctx); }, rmSub(sub, ctx) { is.trueArray(sub) && sub.forEach(r => { r && r.__fc__ && r.__fc__.parent === ctx && this.rmCtx(r.__fc__); }) }, rmCtx(ctx) { if (ctx.deleted) return; const {id, field, input, name} = ctx; if (ctx.input) { Object.defineProperty(ctx.rule, 'value', { value: ctx.rule.value, writable: true }); } $del(this.ctxs, id); $del(this.$render.tempList, id); $del(this.$render.orgChildren, id); $del(this.vm.ctxInject, id); $del(this.formData, id); $del(this.subForm, id); $del(ctx, 'cacheValue'); input && this.rmIdCtx(ctx, field, 'field'); name && this.rmIdCtx(ctx, name, 'name'); if (input && !hasProperty(this.fieldCtx, field)) { $del(this.form, field); } this.deferSyncValue(() => { if (!this.reloading) { if (ctx.parser.loadChildren !== false) { if (is.trueArray(ctx.rule.children)) { ctx.rule.children.forEach(h => h.__fc__ && this.rmCtx(h.__fc__)); } } if (ctx.root === this.rules) { this.vm._renderRule(); } } }, input); const index = this.sort.indexOf(id); if (index > -1) { this.sort.splice(index, 1); } this.$render.clearCache(ctx); ctx.delete(); this.effect(ctx, 'deleted'); input && !this.fieldCtx[field] && this.vm.$emit('removeField', field, ctx.rule, this.api); ctx.rule.__ctrl || this.vm.$emit('removeRule', ctx.rule, this.api); return ctx; }, }) }