@ryan-json-schema-vue3/form
Version:
基于 vue3 + element plus json schema 表单
2 lines (1 loc) • 10.4 kB
JavaScript
(function(d,n){typeof exports=="object"&&typeof module<"u"?n(exports,require("vue"),require("element-plus")):typeof define=="function"&&define.amd?define(["exports","vue","element-plus"],n):(d=typeof globalThis<"u"?globalThis:d||self,n(d.form={},d.Vue,d.elementPlus))})(this,function(d,n,u){"use strict";const _="ui:hidden",Q="ui:disabled",Z="ui:width",R="ui:options",y="ui:widget",$="ui:column";var f=(e=>(e.SELECT="select",e.RADIO="radio",e.CHECKBOX="checkbox",e.SWITCH="switch",e.INPUT="input",e.TEXTAREA="textarea",e))(f||{}),N=(e=>(e.STRING="string",e.NUMBER="number",e.ARRAY="array",e.BOOLEAN="boolean",e))(N||{});const B={schema:{type:Object,required:!0},uiSchema:{type:Object,required:!1,default:()=>({})}},k=(e,t)=>{if(t==null)return e;if(t.length===0)return{...e,properties:{}};const o={};return t.forEach(r=>{e.properties[r]&&(o[r]=e.properties[r])}),{...e,properties:o}};class E{constructor(t,o,r){this.schema=t,this.uiSchema=o,this.model=r,this.commonProps=this.initCommonProps(),this.prop=this.schema.prop}initCommonProps(){const t={...this.uiSchema[R]||{}};return t.disabled=this.uiSchema[Q]===!0,t.placeholder=t.placeholder||this.schema.description,t}}function v(e){return typeof e=="function"||Object.prototype.toString.call(e)==="[object Object]"&&!n.isVNode(e)}class W extends E{render(){let t;const{oneOf:o}=this.schema;return n.createVNode(u.ElRadioGroup,n.mergeProps(this.commonProps,{modelValue:this.model[this.prop],"onUpdate:modelValue":r=>this.model[this.prop]=r}),v(t=o.map(r=>n.createVNode(u.ElRadio,{label:r.const},{default:()=>[r.title]})))?t:{default:()=>[t]})}}function ee(e){return typeof e=="function"||Object.prototype.toString.call(e)==="[object Object]"&&!n.isVNode(e)}class D extends E{render(){let t;const{oneOf:o,anyOf:r}=this.schema,s=!!r,i=o||r||[];return n.createVNode(u.ElSelect,n.mergeProps(this.commonProps,{modelValue:this.model[this.prop],"onUpdate:modelValue":c=>this.model[this.prop]=c,style:{width:"100%"},multiple:s,clearable:!0}),ee(t=i.map(c=>n.createVNode(u.ElOption,{label:c.title,value:c.const},null)))?t:{default:()=>[t]})}}class L extends E{render(){let{format:t}=this.schema;const{type:o}=this.schema;return o===N.ARRAY&&(t+="range",this.commonProps["range-separator"]=this.commonProps["range-separator"]||"-"),n.createVNode(u.ElDatePicker,n.mergeProps(this.commonProps,{modelValue:this.model[this.prop],"onUpdate:modelValue":r=>this.model[this.prop]=r,type:t,clearable:!0}),null)}}class te extends E{render(){const t=this.uiSchema[y]==="textarea"?"textarea":"text";return n.createVNode(u.ElInput,n.mergeProps(this.commonProps,{type:t,modelValue:this.model[this.prop],"onUpdate:modelValue":o=>this.model[this.prop]=o,clearable:!0}),null)}}class re extends E{render(){return n.createVNode(u.ElInputNumber,n.mergeProps({style:{width:"100%"}},this.commonProps,{modelValue:this.model[this.prop],"onUpdate:modelValue":t=>this.model[this.prop]=t}),null)}}class H extends E{render(){return n.createVNode(u.ElSwitch,n.mergeProps(this.commonProps,{modelValue:this.model[this.prop],"onUpdate:modelValue":t=>this.model[this.prop]=t}),null)}}function oe(e){return typeof e=="function"||Object.prototype.toString.call(e)==="[object Object]"&&!n.isVNode(e)}class ne extends E{render(){let t;const{anyOf:o=[]}=this.schema;return n.createVNode(u.ElCheckboxGroup,n.mergeProps(this.commonProps,{modelValue:this.model[this.prop],"onUpdate:modelValue":r=>this.model[this.prop]=r}),oe(t=o.map(r=>n.createVNode(u.ElCheckbox,{label:r.const},{default:()=>[r.title]})))?t:{default:()=>[t]})}}function se(e){return typeof e=="function"||Object.prototype.toString.call(e)==="[object Object]"&&!n.isVNode(e)}const ie=(e,t={},o,r,s,i)=>{let c;const l=e.prop;if(t[_])return null;const p={...t,[y]:t[y],[R]:{...t[R]||{},onKeyup:a=>{a.code==="Enter"&&i.enter(a)},onChange:a=>i.change(l,a)}};e.prop==="startTime"&&console.log(e);const m={item:e,uiItem:p,model:o},h=()=>{if(r&&r[l])return()=>r[l](o);switch(e.type){case N.STRING:return J(m);case N.NUMBER:return ce(m);case N.BOOLEAN:return ae(m);case N.ARRAY:return le(m)}return J(m)},b=t[$]||1,C=(t[R]||{}).labelWidth||"auto";return n.createVNode(u.ElCol,{span:s*b},{default:()=>[n.createVNode(u.ElFormItem,{label:e.description,prop:l,"label-width":C},se(c=h())?c:{default:()=>[c]})]})},I=(e="不支持该类型")=>n.createVNode("div",null,[e]),J=e=>{const{model:t,item:o,uiItem:r}=e;if(o.oneOf){const s=r[y]||f.SELECT;return s===f.RADIO?new W(o,r,t).render():s===f.SELECT?new D(o,r,t).render():I()}return o.format&&(o.format==="date"||o.format==="datetime")?new L(o,r,t).render():new te(o,r,t).render()},ce=e=>{const{model:t,item:o,uiItem:r}=e;return r&&r[y]===f.SWITCH?new H(o,r,t).render():new re(o,r,t).render()},ae=e=>{const{model:t,item:o,uiItem:r}=e,s=r[y]||f.SWITCH,i=[{const:!0,title:"是"},{const:!1,title:"否"}];return o.oneOf=o.oneOf?o.oneOf:i,s===f.SWITCH?new H(o,r,t).render():s===f.RADIO?new W(o,r,t).render():s===f.SELECT?new D(o,r,t).render():I()},le=e=>{const{model:t,item:o,uiItem:r}=e;if(o.anyOf){const s=r[y]||"select";if(s===f.SELECT)return new D(o,r,t).render();if(s===f.CHECKBOX)return new ne(o,r,t).render()}return o.format&&(o.format==="date"||o.format==="datetime")?new L(o,r,t).render():I()},de=(e={},t)=>{const o={...e},{properties:r}=t,{required:s=[]}=t;return s.forEach(i=>{if(r[i]){const c=r[i].prop||i;G(o,c,x(r[i].description))}}),Object.keys(r).forEach(i=>{const c=r[i],l=c.prop||i;c.required&&s.findIndex(p=>p===l)<0&&G(o,l,x(r[i].description))}),o},G=(e,t,o)=>{e[t]||(e[t]=[]),e[t].push(o)},x=e=>({required:!0,message:`${e}不能为空`,trigger:"blur"}),T={...B,model:{type:Object,required:!0},column:{type:Number,required:!1,default:3},rules:{type:Object,required:!1,default:()=>({})},labelPosition:{type:String,required:!1,default:"right"}},q={...T,fields:{type:Array,required:!1}},M={...B,model:{type:Object,required:!0},column:{type:Number,required:!1,default:3},size:{type:String,required:!1,default:"default"},border:{type:Boolean,required:!1,default:!0}},F={...M,fields:{type:Array,required:!1}},K={...q,...F,readMode:{type:Boolean,required:!1,default:!1}};function pe(e){return typeof e=="function"||Object.prototype.toString.call(e)==="[object Object]"&&!n.isVNode(e)}const X="ry-json-form",O=n.defineComponent({name:X,props:T,setup(e,t){const o=n.ref();let r=n.reactive(e.model);const s=()=>{o.value&&o.value.resetFields()},i=a=>{o.value&&o.value.validate(a)};t.expose({reset:s,validate:i});let c=24/e.column;n.watchEffect(()=>{r=n.reactive(e.model),c=24/e.column});const m={change:(a,g)=>{t.emit("data-change",a,g,r)},enter:a=>{t.emit("enter-up",a,e.model)}},h=()=>{o.value&&o.value.clearValidate();const{properties:a}=e.schema,g=[];return Object.keys(a).forEach(A=>{const w=a[A];w.prop=w.prop||A;const z=e.uiSchema[A],U=ie(w,z,e.model,t.slots,c,m);U&&g.push(U)}),g},b=n.computed(()=>{const{schema:a,rules:g}=e;return de(g,a)}),C=a=>{a&&(a.stopPropagation&&a.stopPropagation(),a.preventDefault&&a.preventDefault())};return()=>{let a;const{schema:g,uiSchema:A,model:w,column:z,rules:U,labelPosition:ye,...Ee}=e;return n.createVNode("div",{className:X},[n.createVNode(u.ElForm,n.mergeProps(Ee,{ref:o,model:r,rules:b.value,labelWidth:"auto",onSubmit:C,labelPosition:ye}),{default:()=>[n.createVNode(u.ElRow,{gutter:20},pe(a=h())?a:{default:()=>[a]})]})])}}});O.install=e=>{e.component(O.name,O)};const Y=e=>({reset:()=>{const r=e();r&&r.reset()},validate:r=>{const s=e();s&&s.validate(r)}}),me=(e,t)=>({onDataChange:(s,i)=>{e.emit("data-change",s,i,t)},onEnterUp:s=>{e.emit("enter-up",s,t)}}),S=n.defineComponent({name:"ry-pro-form",props:q,setup(e,t){const o=n.ref(),{reset:r,validate:s}=Y(()=>o.value);t.expose({reset:r,validate:s});const i=n.computed(()=>{if(!e.fields)return e.schema;const l={};return e.schema&&e.schema.properties&&e.fields.forEach(p=>{e.schema.properties[p]&&(l[p]=e.schema.properties[p])}),{...e.schema,properties:l}}),c=n.computed(()=>{const l={...e};return delete l.fields,l});return()=>n.createVNode(O,n.mergeProps({ref:o},c.value,{schema:i.value}),t.slots)}});S.install=e=>{e.component(S.name,S)};const ue=(e,t={},o,r)=>{if(t[_]===!0)return null;const s=e.prop,i=()=>{const l=o[s];if(e.oneOf){const p=e.oneOf.find(m=>m.const===l);return p?p.title:l}return e.anyOf?typeof l=="string"?l.split(",").map(m=>{var b;const h=(b=e.anyOf)==null?void 0:b.find(C=>C.const===m);return h?h.title:m}).join(","):l.map(p=>{var h;const m=(h=e.anyOf)==null?void 0:h.find(b=>b.const===p);return m?m.title:p}).join(","):l},c=t[R]||{};return n.createVNode(n.resolveComponent("el-descriptions-item"),n.mergeProps(c,{span:t[$]||1,width:t[Z]||100,label:e.description||""}),{default:()=>[r[s]?r[s](o):i()]})};function fe(e){return typeof e=="function"||Object.prototype.toString.call(e)==="[object Object]"&&!n.isVNode(e)}const V=n.defineComponent({name:"ry-json-description",props:M,setup(e,t){const o=()=>{const{properties:r}=e.schema,s=[];return Object.keys(r).forEach(i=>{const c=r[i];c.prop=c.prop||i;const l=e.uiSchema[i],p=ue(c,l,e.model,t.slots);p&&s.push(p)}),s};return()=>{let r;const{column:s}=e;return n.createVNode(n.resolveComponent("el-descriptions"),n.mergeProps(t.attrs,{column:s,border:!0}),fe(r=o())?r:{default:()=>[r]})}}});V.install=e=>{e.component(V.name,V)};const P=n.defineComponent({name:"ry-pro-description",props:F,setup(e,t){const o=t.attrs,r=n.computed(()=>k(e.schema,e.fields)),s=n.computed(()=>{const i={...e};return delete i.fields,i});return()=>n.createVNode(V,n.mergeProps(o,s.value,{schema:r.value}),t.slots)}});P.install=e=>{e.component(P.name,P)};const j=n.defineComponent({name:"ry-json-form-description",props:K,setup(e,t){const o=n.ref(),r=()=>{o.value&&o.value.reset()},s=i=>{o.value&&o.value.validate(i)};return t.expose({reset:r,validate:s}),()=>{const{readMode:i,...c}=e;return i?n.createVNode(P,c,{default:()=>[n.createTextVNode("description")],...t.slots}):n.createVNode(S,n.mergeProps({ref:o},c),{default:()=>[n.createTextVNode("form")],...t.slots})}}});j.install=e=>{e.component(j.name,j)};const he=[O,S,V,P,j],be={install:e=>{he.forEach(t=>{e.component(t.name,t)})}};d.JsonDescription=V,d.JsonForm=O,d.JsonFormDescription=j,d.ProDescription=P,d.ProForm=S,d.basicDescriptionProps=M,d.basicFormProps=T,d.bindEvent=me,d.bindMethod=Y,d.default=be,d.jsonFormDescriptionProps=K,d.proDescriptionProps=F,d.proFormProps=q,Object.defineProperties(d,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});