UNPKG

@caxa-form/core

Version:

vue动态表单,助你轻松搞定表单|form-create is a form generation component that can generate dynamic rendering, data collection, verification and submission functions through JSON. Supports 3 UI frameworks, and supports the generation of any Vue components. Built-in 20

143 lines (135 loc) 5.55 kB
import extend from '@caxa-form/utils/lib/extend'; import toCase from '@caxa-form/utils/lib/tocase'; import BaseParser from '../factory/parser'; import {$del, $set} from '@caxa-form/utils/lib'; import is from '@caxa-form/utils/lib/type'; import {invoke} from '../frame/util'; export default function useContext(Handler) { extend(Handler.prototype, { getCtx(id) { return this.fieldCtx[id] || this.nameCtx[id] || this.ctxs[id]; }, setCtx(ctx) { let {id, field, name, rule} = ctx; this.ctxs[id] = ctx; if (name) $set(this.nameCtx, name, ctx); if (!ctx.input) return; this.fieldCtx[field] = ctx; 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; const none = ['field', 'value', 'vm', 'template', 'name', 'config', 'control', 'inject', 'sync', 'payload', 'optionsTo']; Object.keys(ctx.rule).filter(k => none.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; this.watching = true; // if (key === 'hidden') // ctx.updateKey(true); // else if (key === 'link') { ctx.link(); return; } else if (['props', 'on', 'nativeOn'].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 (key === 'type') { ctx.updateType(); this.bindParser(ctx); } else if (key === 'children') { const flag = is.trueArray(n); this.deferSyncValue(() => { if (n !== o) { this.rmSub(o); this.$render.initOrgChildren(); } flag && this.loadChildren(n, ctx); }); } this.$render.clearCache(ctx); this.watching = false; }, {deep: !flag, sync: flag})); }); this.watchEffect(ctx); }, rmSub(sub) { is.trueArray(sub) && sub.forEach(r => { r && r.__fc__ && this.rmCtx(r.__fc__); }) }, rmCtx(ctx) { if (ctx.deleted) return; const {id, field, name} = ctx; if (ctx.input) { Object.defineProperty(ctx.rule, 'value', { value: ctx.rule.value, writable: true }); } $del(this.ctxs, id); $del(this.$render.renderList, id); $del(this.$render.orgChildren, id); $del(ctx, 'cacheValue'); const f = this.fieldCtx[field]; if (field && (!f || f === ctx)) { $del(this.formData, field); $del(this.form, field); $del(this.fieldCtx, field); $del(this.subForm, field); this.vm.$nextTick(() => this.vm.$emit('removeField', field, ctx.rule, this.api)); } if (name && this.nameCtx[name] === ctx) { $del(this.nameCtx, name); } if (!this.reloading) { this.deferSyncValue(() => { if (is.trueArray(ctx.rule.children)) { ctx.rule.children.forEach(h => h.__fc__ && this.rmCtx(h.__fc__)); } this.syncValue(); }) if (ctx.root === this.rules) { this.vm._renderRule(); } } const index = this.sort.indexOf(id); if (index > -1) { this.sort.splice(index, 1); } this.$render.clearCache(ctx); ctx.delete(); this.effect(ctx, 'deleted'); this.vm.$nextTick(() => this.vm.$emit('removeRule', ctx.rule, this.api)); return ctx; }, }) }