├── packages ├── lib │ ├── vue3 │ │ ├── vue3-form-ant │ │ │ ├── .keep │ │ │ ├── .npmignore │ │ │ ├── .eslintignore │ │ │ ├── babel.config.js │ │ │ ├── types │ │ │ │ ├── i18n.d.ts │ │ │ │ ├── modelValueComponent.d.ts │ │ │ │ ├── getDefaultFormState.d.ts │ │ │ │ ├── globalOptions.d.ts │ │ │ │ ├── vueForm.d.ts │ │ │ │ ├── schemaValidate.d.ts │ │ │ │ ├── index.d.ts │ │ │ │ ├── fieldProps.d.ts │ │ │ │ └── vueUtils.d.ts │ │ │ ├── src │ │ │ │ └── config │ │ │ │ │ └── widgets │ │ │ │ │ ├── CheckboxesWidget │ │ │ │ │ ├── readme.md │ │ │ │ │ └── index.js │ │ │ │ │ ├── TimePickerWidget │ │ │ │ │ └── index.js │ │ │ │ │ ├── DatePickerWidget │ │ │ │ │ └── index.js │ │ │ │ │ ├── DateTimePickerWidget │ │ │ │ │ └── index.js │ │ │ │ │ ├── RadioWidget │ │ │ │ │ └── index.js │ │ │ │ │ ├── WIDGET_MAP.js │ │ │ │ │ └── SelectWidget │ │ │ │ │ └── index.js │ │ │ └── scripts │ │ │ │ ├── config.js │ │ │ │ ├── build.js │ │ │ │ └── watch.js │ │ ├── vue3-form-naive │ │ │ ├── .npmignore │ │ │ ├── .eslintignore │ │ │ ├── babel.config.js │ │ │ ├── types │ │ │ │ ├── i18n.d.ts │ │ │ │ ├── modelValueComponent.d.ts │ │ │ │ ├── getDefaultFormState.d.ts │ │ │ │ ├── globalOptions.d.ts │ │ │ │ ├── vueForm.d.ts │ │ │ │ ├── schemaValidate.d.ts │ │ │ │ ├── fieldProps.d.ts │ │ │ │ ├── vueUtils.d.ts │ │ │ │ └── index.d.ts │ │ │ ├── src │ │ │ │ ├── config │ │ │ │ │ └── widgets │ │ │ │ │ │ ├── CheckboxesWidget │ │ │ │ │ │ └── readme.md │ │ │ │ │ │ ├── SelectWidget │ │ │ │ │ │ └── index.js │ │ │ │ │ │ ├── TimePickerWidget │ │ │ │ │ │ └── index.js │ │ │ │ │ │ ├── RadioWidget │ │ │ │ │ │ └── index.js │ │ │ │ │ │ └── WIDGET_MAP.js │ │ │ │ └── style.css │ │ │ └── scripts │ │ │ │ ├── config.js │ │ │ │ ├── build.js │ │ │ │ └── watch.js │ │ ├── vue3-form-element │ │ │ ├── .npmignore │ │ │ ├── .eslintignore │ │ │ ├── babel.config.js │ │ │ ├── types │ │ │ │ ├── i18n.d.ts │ │ │ │ ├── getDefaultFormState.d.ts │ │ │ │ ├── globalOptions.d.ts │ │ │ │ ├── vueForm.d.ts │ │ │ │ ├── index.d.ts │ │ │ │ ├── schemaValidate.d.ts │ │ │ │ ├── fieldProps.d.ts │ │ │ │ └── vueUtils.d.ts │ │ │ ├── src │ │ │ │ ├── config │ │ │ │ │ └── widgets │ │ │ │ │ │ ├── CheckboxesWidget │ │ │ │ │ │ ├── readme.md │ │ │ │ │ │ └── index.vue │ │ │ │ │ │ ├── SelectWidget │ │ │ │ │ │ └── index.vue │ │ │ │ │ │ ├── RadioWidget │ │ │ │ │ │ └── index.vue │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ └── WIDGET_MAP.js │ │ │ │ └── style.css │ │ │ └── scripts │ │ │ │ ├── config.js │ │ │ │ ├── build.js │ │ │ │ └── watch.js │ │ └── vue3-core │ │ │ ├── .eslintignore │ │ │ ├── src │ │ │ ├── fields │ │ │ │ ├── IntegerField │ │ │ │ │ └── index.js │ │ │ │ ├── NumberField │ │ │ │ │ └── index.js │ │ │ │ ├── combiningSchemas │ │ │ │ │ ├── AnyOfField │ │ │ │ │ │ └── index.js │ │ │ │ │ └── OneOfField │ │ │ │ │ │ └── index.js │ │ │ │ └── ArrayField │ │ │ │ │ └── arrayTypes │ │ │ │ │ └── ArrayFieldSpecialFormat.js │ │ │ └── props.js │ │ │ └── package.json │ ├── vue2 │ │ ├── vue2-form-element │ │ │ ├── .npmignore │ │ │ ├── .eslintignore │ │ │ ├── babel.config.js │ │ │ ├── types │ │ │ │ ├── i18n.d.ts │ │ │ │ ├── getDefaultFormState.d.ts │ │ │ │ ├── globalOptions.d.ts │ │ │ │ ├── vueForm.d.ts │ │ │ │ ├── index.d.ts │ │ │ │ ├── schemaValidate.d.ts │ │ │ │ ├── fieldProps.d.ts │ │ │ │ └── vueUtils.d.ts │ │ │ ├── src │ │ │ │ ├── config │ │ │ │ │ └── widgets │ │ │ │ │ │ ├── CheckboxesWidget │ │ │ │ │ │ ├── readme.md │ │ │ │ │ │ └── index.vue │ │ │ │ │ │ ├── SelectWidget │ │ │ │ │ │ └── index.vue │ │ │ │ │ │ ├── RadioWidget │ │ │ │ │ │ └── index.vue │ │ │ │ │ │ ├── TimePickerWidget │ │ │ │ │ │ └── index.js │ │ │ │ │ │ ├── DatePickerWidget │ │ │ │ │ │ └── index.js │ │ │ │ │ │ ├── WIDGET_MAP.js │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ └── DateTimePickerWidget │ │ │ │ │ │ └── index.js │ │ │ │ └── style.css │ │ │ └── scripts │ │ │ │ ├── config.js │ │ │ │ ├── build.js │ │ │ │ └── watch.js │ │ ├── vue2-core │ │ │ ├── .eslintignore │ │ │ ├── src │ │ │ │ ├── fields │ │ │ │ │ ├── IntegerField │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── NumberField │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── combiningSchemas │ │ │ │ │ │ ├── AnyOfField │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ └── OneOfField │ │ │ │ │ │ │ └── index.js │ │ │ │ │ └── ArrayField │ │ │ │ │ │ └── arrayTypes │ │ │ │ │ │ └── ArrayFieldSpecialFormat.js │ │ │ │ ├── components │ │ │ │ │ └── FieldGroupWrap.vue │ │ │ │ └── props.js │ │ │ └── package.json │ │ └── vue2-form-iview3 │ │ │ ├── .eslintignore │ │ │ ├── babel.config.js │ │ │ ├── types │ │ │ ├── i18n.d.ts │ │ │ ├── getDefaultFormState.d.ts │ │ │ ├── globalOptions.d.ts │ │ │ ├── vueForm.d.ts │ │ │ ├── index.d.ts │ │ │ ├── schemaValidate.d.ts │ │ │ ├── fieldProps.d.ts │ │ │ └── vueUtils.d.ts │ │ │ ├── src │ │ │ ├── config │ │ │ │ └── widgets │ │ │ │ │ ├── CheckboxesWidget │ │ │ │ │ ├── readme.md │ │ │ │ │ └── index.vue │ │ │ │ │ ├── DateTimePickerWidget │ │ │ │ │ └── index.js │ │ │ │ │ ├── InputNumberWidget │ │ │ │ │ └── index.js │ │ │ │ │ ├── TimePickerWidget │ │ │ │ │ └── index.js │ │ │ │ │ ├── RadioWidget │ │ │ │ │ └── index.vue │ │ │ │ │ ├── SelectWidget │ │ │ │ │ └── index.vue │ │ │ │ │ ├── SwitchWidget │ │ │ │ │ └── index.js │ │ │ │ │ ├── index.js │ │ │ │ │ └── WIDGET_MAP.js │ │ │ └── style.css │ │ │ └── scripts │ │ │ ├── config.js │ │ │ ├── build.js │ │ │ └── watch.js │ ├── babel.config.js │ ├── utils │ │ ├── icons │ │ │ ├── IconCaretDown.vue │ │ │ ├── IconCaretUp.vue │ │ │ ├── index.js │ │ │ ├── IconClose.vue │ │ │ ├── IconPlus.vue │ │ │ └── IconQuestion.vue │ │ ├── i18n │ │ │ └── index.js │ │ ├── README.md │ │ ├── package.json │ │ ├── vueUtils.js │ │ ├── vueCommonUtils.js │ │ └── schema │ │ │ └── findSchemaDefinition.js │ ├── .eslintrc.js │ └── postcss.config.js ├── demo │ ├── demo-common │ │ ├── bootstrap.js │ │ ├── components │ │ │ ├── iView │ │ │ │ ├── styles │ │ │ │ │ └── fonts │ │ │ │ │ │ ├── ionicons.ttf │ │ │ │ │ │ ├── ionicons.woff │ │ │ │ │ │ └── ionicons.woff2 │ │ │ │ └── index.js │ │ │ ├── ElementUi │ │ │ │ ├── theme │ │ │ │ │ └── fonts │ │ │ │ │ │ ├── element-icons.ttf │ │ │ │ │ │ └── element-icons.woff │ │ │ │ └── index.js │ │ │ ├── ElementPlus │ │ │ │ ├── theme │ │ │ │ │ └── fonts │ │ │ │ │ │ ├── element-icons.ttf │ │ │ │ │ │ └── element-icons.woff │ │ │ │ └── index.js │ │ │ ├── Naive │ │ │ │ └── index.js │ │ │ └── Antdv │ │ │ │ └── index.js │ │ ├── utils │ │ │ ├── obj.js │ │ │ ├── id.js │ │ │ └── url.js │ │ ├── schemaTypes │ │ │ ├── 90.Test │ │ │ │ └── index.js │ │ │ ├── index.js │ │ │ └── 25.hidden(隐藏表单项) │ │ │ │ └── index.js │ │ ├── postcss.config.js │ │ ├── package.json │ │ └── .eslintrc.js │ ├── demo-v2 │ │ ├── .eslintignore │ │ ├── src │ │ │ └── pages │ │ │ │ ├── vue-editor │ │ │ │ ├── views │ │ │ │ │ └── editor │ │ │ │ │ │ ├── viewComponents │ │ │ │ │ │ ├── _commonConfig │ │ │ │ │ │ │ ├── readme.md │ │ │ │ │ │ │ ├── error │ │ │ │ │ │ │ │ └── genImgItem.js │ │ │ │ │ │ │ └── ui │ │ │ │ │ │ │ │ └── genImgItem.js │ │ │ │ │ │ ├── Coupon │ │ │ │ │ │ │ ├── uiSchema.json │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ ├── Coupon.json │ │ │ │ │ │ │ └── component │ │ │ │ │ │ │ │ └── View.vue │ │ │ │ │ │ ├── RecommendedGoodsList │ │ │ │ │ │ │ ├── uiSchema.json │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ ├── RecommendedGoodsList.json │ │ │ │ │ │ │ └── component │ │ │ │ │ │ │ │ └── View.vue │ │ │ │ │ │ ├── MultipleImg5 │ │ │ │ │ │ │ ├── uiSchema.js │ │ │ │ │ │ │ ├── errorSchema.js │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ └── schema.json │ │ │ │ │ │ ├── AllGoodsList │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ ├── AllGoodsList.json │ │ │ │ │ │ │ └── component │ │ │ │ │ │ │ │ └── View.vue │ │ │ │ │ │ ├── Text │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ ├── View.vue │ │ │ │ │ │ │ ├── uiSchema.js │ │ │ │ │ │ │ └── propsSchema.js │ │ │ │ │ │ ├── CategoryGoods │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ └── uiSchema.js │ │ │ │ │ │ ├── CarouselImg │ │ │ │ │ │ │ ├── errSchema.js │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ ├── uiSchema.js │ │ │ │ │ │ │ └── CarouselImg.json │ │ │ │ │ │ ├── FlashSaleGoodsList │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ └── uiSchema.js │ │ │ │ │ │ ├── MultipleImg1_3 │ │ │ │ │ │ │ ├── errorSchema.js │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ ├── uiSchema.js │ │ │ │ │ │ │ └── schema.json │ │ │ │ │ │ └── MultipleImg2_3 │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ ├── errorSchema.js │ │ │ │ │ │ │ ├── uiSchema.js │ │ │ │ │ │ │ └── schema.json │ │ │ │ │ │ ├── assets │ │ │ │ │ │ └── img │ │ │ │ │ │ │ └── empty-tip.png │ │ │ │ │ │ ├── viewComponentsM │ │ │ │ │ │ ├── Test │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ └── View.vue │ │ │ │ │ │ ├── CategoryList │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ ├── RecommendGoods │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ ├── Text │ │ │ │ │ │ │ ├── uiSchema.js │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ ├── propsSchema.json │ │ │ │ │ │ │ └── View.vue │ │ │ │ │ │ └── CarouselImg │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ ├── uiSchema.js │ │ │ │ │ │ │ └── CarouselImg.json │ │ │ │ │ │ ├── common │ │ │ │ │ │ └── registerExtraElementComponent.js │ │ │ │ │ │ └── data.js │ │ │ │ ├── App.vue │ │ │ │ ├── router │ │ │ │ │ ├── index.js │ │ │ │ │ └── routes │ │ │ │ │ │ └── index.js │ │ │ │ ├── vue-editor.css │ │ │ │ ├── vue-editor.js │ │ │ │ └── vue-editor.html │ │ │ │ ├── schema-generator │ │ │ │ ├── App.vue │ │ │ │ ├── views │ │ │ │ │ └── editor │ │ │ │ │ │ ├── viewComponents │ │ │ │ │ │ ├── Color │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ ├── Date │ │ │ │ │ │ │ ├── string.js │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ ├── DateTime │ │ │ │ │ │ │ ├── string.js │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ ├── MultiSelect │ │ │ │ │ │ │ ├── elSelect.js │ │ │ │ │ │ │ └── elCheckbox.js │ │ │ │ │ │ ├── SingleSelect │ │ │ │ │ │ │ ├── elRadio.js │ │ │ │ │ │ │ └── elSelect.js │ │ │ │ │ │ ├── DateRange │ │ │ │ │ │ │ ├── string.js │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ ├── DateTimeRange │ │ │ │ │ │ │ ├── string.js │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ ├── Object │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ ├── Array │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ ├── SelectBoolean │ │ │ │ │ │ │ ├── elCheckbox.js │ │ │ │ │ │ │ ├── elSwitch.js │ │ │ │ │ │ │ ├── elRadio.js │ │ │ │ │ │ │ └── elSelect.js │ │ │ │ │ │ ├── Time │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ └── Upload │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ ├── common │ │ │ │ │ │ └── utils.js │ │ │ │ │ │ ├── components │ │ │ │ │ │ └── ImportSchemaView.vue │ │ │ │ │ │ └── data.js │ │ │ │ ├── router │ │ │ │ │ ├── index.js │ │ │ │ │ └── routes │ │ │ │ │ │ └── index.js │ │ │ │ ├── schema-generator.js │ │ │ │ └── schema-generator.html │ │ │ │ └── index │ │ │ │ ├── style.css │ │ │ │ ├── App.vue │ │ │ │ ├── routes.js │ │ │ │ └── index.js │ │ ├── scripts │ │ │ ├── utils.js │ │ │ ├── log.js │ │ │ └── envConfig.js │ │ ├── postcss.config.js │ │ ├── babel.config.js │ │ ├── README.md │ │ └── .eslintrc.js │ └── demo-v3 │ │ ├── .eslintignore │ │ ├── index.d.ts │ │ ├── postcss.config.js │ │ ├── scripts │ │ ├── utils.js │ │ ├── log.js │ │ └── envConfig.js │ │ ├── babel.config.js │ │ ├── src │ │ └── pages │ │ │ └── index │ │ │ ├── style.css │ │ │ ├── App.vue │ │ │ ├── routes.js │ │ │ └── index.js │ │ ├── README.md │ │ └── .eslintrc.js └── docs │ ├── docs │ ├── zh │ │ ├── guide │ │ │ ├── getting-started.md │ │ │ ├── why.md │ │ │ ├── demo.md │ │ │ ├── todo.md │ │ │ └── datetime-config.md │ │ └── rules │ │ │ └── null.md │ └── .vuepress │ │ ├── public │ │ ├── logo.png │ │ ├── vjsf.jpg │ │ ├── icons │ │ │ └── ico.png │ │ ├── pathName.png │ │ ├── vjsf-vaidate.jpg │ │ └── manifest.json │ │ ├── plugins │ │ └── demo-container │ │ │ └── src │ │ │ ├── enhanceAppFile.js │ │ │ ├── i18n │ │ │ └── default_lang.json │ │ │ ├── common │ │ │ └── fence.js │ │ │ └── index.js │ │ ├── styles │ │ ├── palette.styl │ │ └── index.styl │ │ └── enhanceApp.js │ └── package.json ├── .editorconfig ├── .commitlintrc.js ├── lerna.json ├── .github ├── ISSUE_TEMPLATE │ └── ----------.md └── workflows │ ├── dev-docs-demo.yml │ └── docs-demo.yml └── .gitignore /packages/lib/vue3/vue3-form-ant/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-ant/.npmignore: -------------------------------------------------------------------------------- 1 | src/ 2 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-naive/.npmignore: -------------------------------------------------------------------------------- 1 | src/ 2 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-element/.npmignore: -------------------------------------------------------------------------------- 1 | src/ 2 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-element/.npmignore: -------------------------------------------------------------------------------- 1 | src/ 2 | -------------------------------------------------------------------------------- /packages/demo/demo-common/bootstrap.js: -------------------------------------------------------------------------------- 1 | import './css/bootstrap.css'; 2 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/.eslintignore: -------------------------------------------------------------------------------- 1 | /**/node_modules/* 2 | /**/dist/* 3 | -------------------------------------------------------------------------------- /packages/demo/demo-v3/.eslintignore: -------------------------------------------------------------------------------- 1 | /**/node_modules/* 2 | /**/dist/* 3 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-core/.eslintignore: -------------------------------------------------------------------------------- 1 | /**/node_modules/* 2 | /**/dist/* 3 | /**/*.css 4 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-core/.eslintignore: -------------------------------------------------------------------------------- 1 | /**/node_modules/* 2 | /**/dist/* 3 | /**/*.css 4 | -------------------------------------------------------------------------------- /packages/lib/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['@lljj/babel-preset'] 3 | }; 4 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-ant/.eslintignore: -------------------------------------------------------------------------------- 1 | /**/node_modules/* 2 | /**/dist/* 3 | /**/*.css 4 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-element/.eslintignore: -------------------------------------------------------------------------------- 1 | /**/node_modules/* 2 | /**/dist/* 3 | /**/*.css 4 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-iview3/.eslintignore: -------------------------------------------------------------------------------- 1 | /**/node_modules/* 2 | /**/dist/* 3 | /**/*.css 4 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-element/.eslintignore: -------------------------------------------------------------------------------- 1 | /**/node_modules/* 2 | /**/dist/* 3 | /**/*.css 4 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-naive/.eslintignore: -------------------------------------------------------------------------------- 1 | /**/node_modules/* 2 | /**/dist/* 3 | /**/*.css 4 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/_commonConfig/readme.md: -------------------------------------------------------------------------------- 1 | 通用的配置文件 2 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-ant/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['@lljj/babel-preset'] 3 | }; 4 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-element/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['@lljj/babel-preset'] 3 | }; 4 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-iview3/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['@lljj/babel-preset'] 3 | }; 4 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-element/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['@lljj/babel-preset'] 3 | }; 4 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-naive/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['@lljj/babel-preset'] 3 | }; 4 | -------------------------------------------------------------------------------- /packages/demo/demo-v3/index.d.ts: -------------------------------------------------------------------------------- 1 | // 屏蔽掉 vue css module中 $style 未定义提示 2 | declare const $style: { [index: string]: string }; 3 | -------------------------------------------------------------------------------- /packages/docs/docs/zh/guide/getting-started.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 快速上手 3 | --- 4 | 5 | # 快速上手 6 | 7 | 8 | ## 依赖 9 | elementUi 10 | -------------------------------------------------------------------------------- /packages/docs/docs/.vuepress/public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lljj-x/vue-json-schema-form/HEAD/packages/docs/docs/.vuepress/public/logo.png -------------------------------------------------------------------------------- /packages/docs/docs/.vuepress/public/vjsf.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lljj-x/vue-json-schema-form/HEAD/packages/docs/docs/.vuepress/public/vjsf.jpg -------------------------------------------------------------------------------- /packages/docs/docs/.vuepress/public/icons/ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lljj-x/vue-json-schema-form/HEAD/packages/docs/docs/.vuepress/public/icons/ico.png -------------------------------------------------------------------------------- /packages/docs/docs/.vuepress/public/pathName.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lljj-x/vue-json-schema-form/HEAD/packages/docs/docs/.vuepress/public/pathName.png -------------------------------------------------------------------------------- /packages/docs/docs/.vuepress/public/vjsf-vaidate.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lljj-x/vue-json-schema-form/HEAD/packages/docs/docs/.vuepress/public/vjsf-vaidate.jpg -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/Coupon/uiSchema.json: -------------------------------------------------------------------------------- 1 | { 2 | "show": { 3 | "ui:options": { 4 | 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/RecommendedGoodsList/uiSchema.json: -------------------------------------------------------------------------------- 1 | { 2 | "show": { 3 | "ui:options": { 4 | 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/demo/demo-common/components/iView/styles/fonts/ionicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lljj-x/vue-json-schema-form/HEAD/packages/demo/demo-common/components/iView/styles/fonts/ionicons.ttf -------------------------------------------------------------------------------- /packages/demo/demo-common/components/iView/styles/fonts/ionicons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lljj-x/vue-json-schema-form/HEAD/packages/demo/demo-common/components/iView/styles/fonts/ionicons.woff -------------------------------------------------------------------------------- /packages/demo/demo-common/components/iView/styles/fonts/ionicons.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lljj-x/vue-json-schema-form/HEAD/packages/demo/demo-common/components/iView/styles/fonts/ionicons.woff2 -------------------------------------------------------------------------------- /packages/docs/docs/.vuepress/plugins/demo-container/src/enhanceAppFile.js: -------------------------------------------------------------------------------- 1 | import DemoBlock from './DemoBlock.vue' 2 | export default ({ Vue }) => { 3 | Vue.component('DemoBlock', DemoBlock) 4 | } 5 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-ant/types/i18n.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace i18n { 2 | function getCurrentLocalize(): object; 3 | 4 | function useLocal(fn): object; 5 | } 6 | 7 | export default i18n; 8 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 4 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-element/types/i18n.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace i18n { 2 | function getCurrentLocalize(): object; 3 | 4 | function useLocal(fn): object; 5 | } 6 | 7 | export default i18n; 8 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-iview3/types/i18n.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace i18n { 2 | function getCurrentLocalize(): object; 3 | 4 | function useLocal(fn): object; 5 | } 6 | 7 | export default i18n; 8 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-element/types/i18n.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace i18n { 2 | function getCurrentLocalize(): object; 3 | 4 | function useLocal(fn): object; 5 | } 6 | 7 | export default i18n; 8 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-naive/types/i18n.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace i18n { 2 | function getCurrentLocalize(): object; 3 | 4 | function useLocal(fn): object; 5 | } 6 | 7 | export default i18n; 8 | -------------------------------------------------------------------------------- /packages/demo/demo-common/components/ElementUi/theme/fonts/element-icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lljj-x/vue-json-schema-form/HEAD/packages/demo/demo-common/components/ElementUi/theme/fonts/element-icons.ttf -------------------------------------------------------------------------------- /packages/demo/demo-common/components/ElementUi/theme/fonts/element-icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lljj-x/vue-json-schema-form/HEAD/packages/demo/demo-common/components/ElementUi/theme/fonts/element-icons.woff -------------------------------------------------------------------------------- /packages/demo/demo-common/components/ElementPlus/theme/fonts/element-icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lljj-x/vue-json-schema-form/HEAD/packages/demo/demo-common/components/ElementPlus/theme/fonts/element-icons.ttf -------------------------------------------------------------------------------- /packages/demo/demo-common/components/ElementPlus/theme/fonts/element-icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lljj-x/vue-json-schema-form/HEAD/packages/demo/demo-common/components/ElementPlus/theme/fonts/element-icons.woff -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/assets/img/empty-tip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lljj-x/vue-json-schema-form/HEAD/packages/demo/demo-v2/src/pages/vue-editor/views/editor/assets/img/empty-tip.png -------------------------------------------------------------------------------- /packages/docs/docs/zh/guide/why.md: -------------------------------------------------------------------------------- 1 | # 为何开发 2 | 3 | * 基于elementUi 和 Vue 可满足需求并且在维护的项目已经没有了... 4 | 5 | * 项目需要就临时写了一个只支持普通object的版本 6 | 7 | * 后续看了 [react-jsonschema-form](https://github.com/rjsf-team/react-jsonschema-form) 的实现决定逐步完善,然后就成这样了... 8 | -------------------------------------------------------------------------------- /packages/demo/demo-common/components/Naive/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2021/2/1 10:00 下午. 3 | */ 4 | 5 | import NaiveUI from 'naive-ui'; 6 | 7 | export default { 8 | install(app) { 9 | app.use(NaiveUI); 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-ant/types/modelValueComponent.d.ts: -------------------------------------------------------------------------------- 1 | declare function modelValueComponent( 2 | baseComponent: object | String | Function, 3 | options?: { 4 | model?: String 5 | } 6 | ): any; 7 | 8 | export default modelValueComponent; 9 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-naive/types/modelValueComponent.d.ts: -------------------------------------------------------------------------------- 1 | declare function modelValueComponent( 2 | baseComponent: object | String | Function, 3 | options?: { 4 | model?: String 5 | } 6 | ): any; 7 | 8 | export default modelValueComponent; 9 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-ant/types/getDefaultFormState.d.ts: -------------------------------------------------------------------------------- 1 | declare function getDefaultFormState( 2 | schema: object, 3 | formData: object, 4 | rootSchema: object, 5 | includeUndefinedValues?: boolean, 6 | ): any; 7 | 8 | export default getDefaultFormState; 9 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-naive/types/getDefaultFormState.d.ts: -------------------------------------------------------------------------------- 1 | declare function getDefaultFormState( 2 | schema: object, 3 | formData: object, 4 | rootSchema: object, 5 | includeUndefinedValues?: boolean, 6 | ): any; 7 | 8 | export default getDefaultFormState; 9 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-element/types/getDefaultFormState.d.ts: -------------------------------------------------------------------------------- 1 | declare function getDefaultFormState( 2 | schema: object, 3 | formData: object, 4 | rootSchema: object, 5 | includeUndefinedValues?: boolean, 6 | ): any; 7 | 8 | export default getDefaultFormState; 9 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-iview3/types/getDefaultFormState.d.ts: -------------------------------------------------------------------------------- 1 | declare function getDefaultFormState( 2 | schema: object, 3 | formData: object, 4 | rootSchema: object, 5 | includeUndefinedValues?: boolean, 6 | ): any; 7 | 8 | export default getDefaultFormState; 9 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-element/types/getDefaultFormState.d.ts: -------------------------------------------------------------------------------- 1 | declare function getDefaultFormState( 2 | schema: object, 3 | formData: object, 4 | rootSchema: object, 5 | includeUndefinedValues?: boolean, 6 | ): any; 7 | 8 | export default getDefaultFormState; 9 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/schema-generator/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 15 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponentsM/Test/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2019/9/29 19:01. 3 | */ 4 | 5 | import Form from './Form'; 6 | import View from './View'; 7 | 8 | export default { 9 | View, 10 | Form, // 自定义Form 11 | }; 12 | -------------------------------------------------------------------------------- /packages/demo/demo-common/components/iView/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/12/28 12:07. 3 | */ 4 | 5 | import './styles/iview.css'; 6 | import iView from 'iview'; 7 | 8 | export default { 9 | install(Vue) { 10 | // debugger; 11 | Vue.use(iView); 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 14 | 15 | 17 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/MultipleImg5/uiSchema.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/4/30 17:13. 3 | */ 4 | 5 | import genImgItem from '../_commonConfig/ui/genImgItem'; 6 | 7 | export default { 8 | imgList: { 9 | items: genImgItem() 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/Coupon/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2019/12/4 15:06. 3 | */ 4 | 5 | import propsSchema from './Coupon.json'; 6 | 7 | const View = () => import('./component/View.vue'); 8 | 9 | export default { 10 | View, 11 | propsSchema 12 | }; 13 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/MultipleImg5/errorSchema.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/4/30 17:40. 3 | */ 4 | 5 | import genImgItem from '../_commonConfig/error/genImgItem'; 6 | 7 | export default { 8 | imgList: { 9 | items: genImgItem() 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /packages/demo/demo-common/utils/obj.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/11/22 9:48 下午. 3 | */ 4 | 5 | export function isEmptyObject(obj) { 6 | for (const key in obj) { 7 | if (Object.prototype.hasOwnProperty.call(obj, key)) { 8 | return false; 9 | } 10 | } 11 | return true; 12 | } 13 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponentsM/CategoryList/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2019/12/4 15:06. 3 | */ 4 | 5 | import propsSchema from './propsSchema.json'; 6 | 7 | const View = () => import('./View.vue'); 8 | 9 | export default { 10 | View, 11 | propsSchema 12 | }; 13 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponentsM/RecommendGoods/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2019/12/4 15:06. 3 | */ 4 | 5 | import propsSchema from './propsSchema.json'; 6 | 7 | const View = () => import('./View.vue'); 8 | 9 | export default { 10 | View, 11 | propsSchema 12 | }; 13 | -------------------------------------------------------------------------------- /packages/demo/demo-common/schemaTypes/90.Test/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/7/22 11:07 下午. 3 | */ 4 | 5 | export default { 6 | schema: { 7 | title: '测试专用页', 8 | type: 'object', 9 | description: '输入你的Schema,顶部分享按钮即可快速生成链接', 10 | properties: { 11 | } 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponentsM/Text/uiSchema.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/7/25 11:25. 3 | */ 4 | 5 | export default { 6 | txt: { 7 | 'ui:placeholder': '输入你的内容' 8 | }, 9 | txtColor: { 10 | 'ui:widget': 'el-color-picker' 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/AllGoodsList/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2019/12/4 15:06. 3 | */ 4 | 5 | import propsSchema from './AllGoodsList.json'; 6 | 7 | const View = () => import('./component/View.vue'); 8 | 9 | export default { 10 | View, 11 | propsSchema 12 | }; 13 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/scripts/utils.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2019/11/27 9:57. 3 | */ 4 | 5 | exports.getSingle = function getSingle(fn) { 6 | let result; 7 | return function proxySingle(...args) { 8 | if (!result) { 9 | result = fn.apply(this, args); 10 | } 11 | return result; 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/RecommendedGoodsList/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/04/28 14:24. 3 | */ 4 | 5 | import propsSchema from './RecommendedGoodsList.json'; 6 | 7 | const View = () => import('./component/View.vue'); 8 | 9 | export default { 10 | View, 11 | propsSchema 12 | }; 13 | -------------------------------------------------------------------------------- /packages/docs/docs/zh/guide/demo.md: -------------------------------------------------------------------------------- 1 | # 使用场景 2 | 3 | ## 前端可视化数据配置 4 | 原本开发就是为了前端可视化数据配置系统,解决需要大量配置表单数据,以及如何和服务端的数据保持一致的场景。 5 | 6 | * 地址: 7 | [可视化页面(H5)活动编辑器](https://form.lljj.me/vue-editor.html) 8 | 9 | ## demo页面 10 | * 说明 11 | 12 | 演示和测试目前支持的 JSON Schema 格式 13 | 14 | * 地址: 15 | [vjsf demo 演示页面](https://form.lljj.me) 16 | 17 | 18 | ## 其它场景 19 | .... 20 | -------------------------------------------------------------------------------- /packages/demo/demo-common/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | require('postcss-import')(), 4 | require('postcss-mixins'), 5 | require('postcss-nested'), 6 | require('postcss-color-mod-function'), 7 | require('postcss-cssnext')({ 8 | warnForDuplicates: false, 9 | }), 10 | ] 11 | }; 12 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | require('postcss-import')(), 4 | require('postcss-mixins'), 5 | require('postcss-nested'), 6 | require('postcss-color-mod-function'), 7 | require('postcss-cssnext')({ 8 | warnForDuplicates: false, 9 | }), 10 | ] 11 | }; 12 | -------------------------------------------------------------------------------- /packages/demo/demo-v3/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | require('postcss-import')(), 4 | require('postcss-mixins'), 5 | require('postcss-nested'), 6 | require('postcss-color-mod-function'), 7 | require('postcss-cssnext')({ 8 | warnForDuplicates: false, 9 | }), 10 | ] 11 | }; 12 | -------------------------------------------------------------------------------- /packages/demo/demo-v3/scripts/utils.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2019/11/27 9:57. 3 | */ 4 | 5 | exports.getSingle = function getSingle(fn) { 6 | let result; 7 | return function proxySingle(...args) { 8 | if (!result) { 9 | result = fn.apply(this, args); 10 | } 11 | return result; 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-ant/src/config/widgets/CheckboxesWidget/readme.md: -------------------------------------------------------------------------------- 1 | ### 文件说明 2 | > 默认widget直接使用element的组件,这里附加一些不能直接满足场景而使用的组件 3 | 4 | ### 组件说明 5 | 单文件夹为单个组件,组件需要统一为v-model双向绑定值 6 | 7 | #### CheckboxesWidget 8 | 说明:多选列表,接受value 和 enumOptions参数 9 | > value - array,选中的值 10 | > enumOptions - Array ,下拉选项 11 | 12 | 示例: 13 | ```js 14 | console.log(1); 15 | ``` 16 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-element/src/config/widgets/CheckboxesWidget/readme.md: -------------------------------------------------------------------------------- 1 | ### 文件说明 2 | > 默认widget直接使用element的组件,这里附加一些不能直接满足场景而使用的组件 3 | 4 | ### 组件说明 5 | 单文件夹为单个组件,组件需要统一为v-model双向绑定值 6 | 7 | #### CheckboxesWidget 8 | 说明:多选列表,接受value 和 enumOptions参数 9 | > value - array,选中的值 10 | > enumOptions - Array ,下拉选项 11 | 12 | 示例: 13 | ```js 14 | console.log(1); 15 | ``` 16 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-iview3/src/config/widgets/CheckboxesWidget/readme.md: -------------------------------------------------------------------------------- 1 | ### 文件说明 2 | > 默认widget直接使用element的组件,这里附加一些不能直接满足场景而使用的组件 3 | 4 | ### 组件说明 5 | 单文件夹为单个组件,组件需要统一为v-model双向绑定值 6 | 7 | #### CheckboxesWidget 8 | 说明:多选列表,接受value 和 enumOptions参数 9 | > value - array,选中的值 10 | > enumOptions - Array ,下拉选项 11 | 12 | 示例: 13 | ```js 14 | console.log(1); 15 | ``` 16 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-element/src/config/widgets/CheckboxesWidget/readme.md: -------------------------------------------------------------------------------- 1 | ### 文件说明 2 | > 默认widget直接使用element的组件,这里附加一些不能直接满足场景而使用的组件 3 | 4 | ### 组件说明 5 | 单文件夹为单个组件,组件需要统一为v-model双向绑定值 6 | 7 | #### CheckboxesWidget 8 | 说明:多选列表,接受value 和 enumOptions参数 9 | > value - array,选中的值 10 | > enumOptions - Array ,下拉选项 11 | 12 | 示例: 13 | ```js 14 | console.log(1); 15 | ``` 16 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-naive/src/config/widgets/CheckboxesWidget/readme.md: -------------------------------------------------------------------------------- 1 | ### 文件说明 2 | > 默认widget直接使用element的组件,这里附加一些不能直接满足场景而使用的组件 3 | 4 | ### 组件说明 5 | 单文件夹为单个组件,组件需要统一为v-model双向绑定值 6 | 7 | #### CheckboxesWidget 8 | 说明:多选列表,接受value 和 enumOptions参数 9 | > value - array,选中的值 10 | > enumOptions - Array ,下拉选项 11 | 12 | 示例: 13 | ```js 14 | console.log(1); 15 | ``` 16 | -------------------------------------------------------------------------------- /.commitlintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['@commitlint/config-conventional'], 3 | rules: { 4 | 'type-enum': [2, 'always', [ 5 | "feat", "fix", "docs", "style", "refactor", "perf", "test", "build", "ci", "chore", "revert" 6 | ]], 7 | 'subject-full-stop': [0, 'never'], 8 | 'subject-case': [0, 'never'] 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/Text/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2019/9/29 19:01. 3 | */ 4 | 5 | import propsSchema from './propsSchema.js'; 6 | import uiSchema from './uiSchema.js'; 7 | 8 | const View = () => import('./View.vue'); 9 | 10 | export default { 11 | View, 12 | propsSchema, 13 | uiSchema 14 | }; 15 | -------------------------------------------------------------------------------- /packages/lib/utils/icons/IconCaretDown.vue: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/CategoryGoods/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/7/25 15:23. 3 | */ 4 | 5 | import propsSchema from './schema.json'; 6 | import uiSchema from './uiSchema'; 7 | 8 | const View = () => import('./View.vue'); 9 | 10 | export default { 11 | View, 12 | propsSchema, 13 | uiSchema 14 | }; 15 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponentsM/Text/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2019/9/29 19:01. 3 | */ 4 | 5 | import propsSchema from './propsSchema.json'; 6 | import uiSchema from './uiSchema.js'; 7 | 8 | const View = () => import('./View.vue'); 9 | 10 | export default { 11 | View, 12 | propsSchema, 13 | uiSchema 14 | }; 15 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-element/src/style.css: -------------------------------------------------------------------------------- 1 | /* elementUi 重置样式*/ 2 | .genFromComponent { 3 | &.el-form--label-top { 4 | .el-form-item__label { 5 | line-height: 26px; 6 | padding-bottom: 6px; 7 | font-size: 14px; 8 | } 9 | } 10 | .el-checkbox, .el-color-picker{ 11 | vertical-align: top; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/CarouselImg/errSchema.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/7/24 10:00 下午. 3 | */ 4 | export default { 5 | imgList: { 6 | items: { 7 | imgLink: { 8 | 'err:format': '请输入正确的的链接地址', 9 | 'err:required': '不能为空' 10 | } 11 | } 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/FlashSaleGoodsList/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2019/12/4 15:06. 3 | */ 4 | 5 | import propsSchema from './schema.js'; 6 | import uiSchema from './uiSchema.js'; 7 | 8 | const View = () => import('./View.vue'); 9 | 10 | export default { 11 | View, 12 | propsSchema, 13 | uiSchema 14 | }; 15 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponentsM/CarouselImg/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2019/12/4 15:06. 3 | */ 4 | 5 | import propsSchema from './CarouselImg.json'; 6 | import uiSchema from './uiSchema.js'; 7 | 8 | const View = () => import('./View.vue'); 9 | 10 | export default { 11 | View, 12 | propsSchema, 13 | uiSchema 14 | }; 15 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "npmClient": "yarn", 3 | "useWorkspaces": true, 4 | "version": "1.19.1", 5 | "command": { 6 | "version": { 7 | "allowBranch": "master", 8 | "exact": true, 9 | "ignoreChanges": [ 10 | "**/*.md" 11 | ], 12 | "message": "build: release version %v" 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/demo/demo-common/components/Antdv/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2021/2/1 10:00 下午. 3 | */ 4 | 5 | import Antd from 'ant-design-vue'; 6 | 7 | // eslint-disable-next-line import/no-webpack-loader-syntax 8 | import '!vue-style-loader!css-loader!ant-design-vue/dist/antd.css'; 9 | 10 | export default { 11 | install(app) { 12 | app.use(Antd); 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/schema-generator/views/editor/viewComponents/Color/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2019/9/29 19:01. 3 | */ 4 | 5 | import genSchema from '../genSchema.js'; 6 | 7 | const viewSchema = { 8 | title: '颜色选择器', 9 | type: 'string', 10 | format: 'color' 11 | }; 12 | export default { 13 | viewSchema, 14 | propsSchema: genSchema() 15 | }; 16 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/schema-generator/views/editor/viewComponents/Date/string.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/10/30 17:11. 3 | */ 4 | 5 | import baseData from './index'; 6 | 7 | export default { 8 | viewSchema: { 9 | ...baseData.viewSchema, 10 | title: 'Date(字符串)', 11 | type: 'string' 12 | }, 13 | propsSchema: baseData.propsSchema 14 | }; 15 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | // '@babel/plugin-proposal-export-default-from' 4 | ], 5 | presets: [ 6 | [ 7 | '@lljj/babel-preset-app', 8 | { 9 | useBuiltIns: false, 10 | regenerator: true, 11 | helpers: true 12 | } 13 | ] 14 | ] 15 | }; 16 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/schema-generator/views/editor/viewComponents/DateTime/string.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/10/30 17:11. 3 | */ 4 | 5 | import baseData from './index'; 6 | 7 | export default { 8 | viewSchema: { 9 | ...baseData.viewSchema, 10 | title: 'DateTime(字符串)', 11 | type: 'string' 12 | }, 13 | propsSchema: baseData.propsSchema 14 | }; 15 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import VueRouter from 'VueRouter'; 3 | import routes from './routes/index.js'; 4 | 5 | Vue.use(VueRouter); 6 | 7 | /** 8 | * 路由入口 9 | * 10 | */ 11 | export default new VueRouter({ 12 | mode: 'hash', 13 | routes: [...routes], 14 | scrollBehavior() { 15 | return { x: 0, y: 0 }; 16 | } 17 | }); 18 | -------------------------------------------------------------------------------- /packages/demo/demo-v3/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | // '@babel/plugin-proposal-export-default-from' 4 | ], 5 | presets: [ 6 | [ 7 | '@lljj/babel-preset-app', 8 | { 9 | useBuiltIns: false, 10 | regenerator: true, 11 | helpers: true 12 | } 13 | ] 14 | ] 15 | }; 16 | -------------------------------------------------------------------------------- /packages/lib/utils/icons/IconCaretUp.vue: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/schema-generator/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import VueRouter from 'VueRouter'; 3 | import routes from './routes/index.js'; 4 | 5 | Vue.use(VueRouter); 6 | 7 | /** 8 | * 路由入口 9 | * 10 | */ 11 | export default new VueRouter({ 12 | mode: 'hash', 13 | routes: [...routes], 14 | scrollBehavior() { 15 | return { x: 0, y: 0 }; 16 | } 17 | }); 18 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/schema-generator/views/editor/viewComponents/MultiSelect/elSelect.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/12/10 15:53. 3 | */ 4 | 5 | import baseMulti from './index'; 6 | 7 | export default { 8 | viewSchema: { 9 | ...baseMulti.viewSchema, 10 | title: '多选(Select)', 11 | 'ui:widget': 'SelectWidget' 12 | }, 13 | propsSchema: baseMulti.propsSchema 14 | }; 15 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/schema-generator/views/editor/viewComponents/SingleSelect/elRadio.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/12/10 15:41. 3 | */ 4 | 5 | import baseRadio from './index'; 6 | 7 | const viewSchema = { 8 | title: '单选(Radio)', 9 | type: 'string', 10 | 'ui:widget': 'RadioWidget' 11 | }; 12 | 13 | export default { 14 | viewSchema, 15 | propsSchema: baseRadio.propsSchema 16 | }; 17 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/schema-generator/views/editor/viewComponents/MultiSelect/elCheckbox.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/12/10 15:53. 3 | */ 4 | 5 | import baseMulti from './index'; 6 | 7 | export default { 8 | viewSchema: { 9 | ...baseMulti.viewSchema, 10 | title: '多选(Checkbox)', 11 | 'ui:widget': 'CheckboxesWidget' 12 | }, 13 | propsSchema: baseMulti.propsSchema 14 | }; 15 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/schema-generator/views/editor/viewComponents/SingleSelect/elSelect.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/12/10 15:41. 3 | */ 4 | 5 | 6 | import baseRadio from './index'; 7 | 8 | const viewSchema = { 9 | title: '单选(Select)', 10 | type: 'string', 11 | 'ui:widget': 'SelectWidget' 12 | }; 13 | 14 | export default { 15 | viewSchema, 16 | propsSchema: baseRadio.propsSchema 17 | }; 18 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/scripts/log.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2019/11/27 13:57. 3 | */ 4 | 5 | const envConfig = require('./envConfig').getConfig(); 6 | 7 | module.exports = function fn({ data, des }) { 8 | if (envConfig.log) { 9 | console.log(`\n---------- ↓↓↓↓ ${des || ''} ↓↓↓↓ ----------`); 10 | console.log(data); 11 | console.log(`---------- ↑↑↑↑ ${des || ''} ↑↑↑↑ ----------\n`); 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /packages/demo/demo-v3/scripts/log.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2019/11/27 13:57. 3 | */ 4 | 5 | const envConfig = require('./envConfig').getConfig(); 6 | 7 | module.exports = function fn({ data, des }) { 8 | if (envConfig.log) { 9 | console.log(`\n---------- ↓↓↓↓ ${des || ''} ↓↓↓↓ ----------`); 10 | console.log(data); 11 | console.log(`---------- ↑↑↑↑ ${des || ''} ↑↑↑↑ ----------\n`); 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/----------.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 问题反馈或者功能建议 3 | about: 请详细描述你的问题 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 反馈问题请先查看文档和务必提供详细的复现代码,遵循如下格式,描述不清楚的问题将会直接关闭。 11 | 12 | ### vue和ui框架 13 | vue2或者vue3、ui框架element antd、vjsf 使用版本说明 14 | 15 | ### 问题描述 16 | 对错误是什么的清晰简洁的描述。 17 | 18 | ### 如何复现 19 | 可以详细介绍你的复现场景或者相关代码。 20 | 21 | 必要时提供复现demo,如codepen,github 复现仓库,playground分享链接等 22 | 23 | ### 期望的结果 24 | .... 25 | -------------------------------------------------------------------------------- /packages/demo/demo-common/schemaTypes/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/5/13 9:06 下午. 3 | */ 4 | 5 | const files = require.context('.', true, /\.js$/); 6 | 7 | const modules = files.keys().reduce((preVal, curKey) => { 8 | if (curKey !== './index.js') { 9 | preVal[curKey.replace(/(\.\/\d+\.|\/index\.js)/g, '')] = files(curKey).default; 10 | } 11 | return preVal; 12 | }, {}); 13 | 14 | export default modules; 15 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/schema-generator/views/editor/viewComponents/DateRange/string.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/12/10 16:57. 3 | */ 4 | 5 | import baseData from './index'; 6 | 7 | export default { 8 | viewSchema: { 9 | ...baseData.viewSchema, 10 | title: 'Date范围(字符串)', 11 | items: { 12 | type: 'string' 13 | } 14 | }, 15 | propsSchema: baseData.propsSchema 16 | }; 17 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-core/src/fields/IntegerField/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/4/21 9:24. 3 | * IntegerField 复用StringField 4 | */ 5 | 6 | import vueProps from '../props'; 7 | import StringField from '../StringField'; 8 | 9 | export default { 10 | name: 'IntegerField', 11 | props: vueProps, 12 | functional: true, 13 | render(h, context) { 14 | return h(StringField, context.data); 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-core/src/fields/NumberField/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/4/21 9:24. 3 | * NumberField 复用StringField 4 | */ 5 | 6 | import vueProps from '../props'; 7 | import StringField from '../StringField'; 8 | 9 | export default { 10 | name: 'NumberField', 11 | props: vueProps, 12 | functional: true, 13 | render(h, context) { 14 | return h(StringField, context.data); 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/index/style.css: -------------------------------------------------------------------------------- 1 | .siteScroll, 2 | .siteHeader_currencyList, 3 | * { 4 | &::-webkit-scrollbar { 5 | width: 6px; 6 | height: 6px; 7 | } 8 | &::-webkit-scrollbar-track { 9 | background-color: white; 10 | } 11 | &::-webkit-scrollbar-thumb { 12 | border-radius: 10px; 13 | background-color: #999999; 14 | } 15 | } 16 | 17 | .hide{ 18 | display: none; 19 | } 20 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/MultipleImg5/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2019/12/4 15:06. 3 | */ 4 | 5 | import propsSchema from './schema.json'; 6 | import uiSchema from './uiSchema.js'; 7 | import errorSchema from './errorSchema.js'; 8 | 9 | const View = () => import('./View.vue'); 10 | 11 | export default { 12 | View, 13 | propsSchema, 14 | uiSchema, 15 | errorSchema 16 | }; 17 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-element/types/globalOptions.d.ts: -------------------------------------------------------------------------------- 1 | interface HELPERS { 2 | isMiniDes: (formProps: object) => boolean; 3 | } 4 | 5 | declare namespace globalOptions { 6 | 7 | /** WIDGET_MAP 配置 */ 8 | export const WIDGET_MAP:object 9 | 10 | /** COMPONENT_MAP 配置 */ 11 | export const COMPONENT_MAP:object 12 | 13 | /** HELPERS 配置 */ 14 | export const HELPERS: HELPERS 15 | } 16 | 17 | export default globalOptions; 18 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-iview3/types/globalOptions.d.ts: -------------------------------------------------------------------------------- 1 | interface HELPERS { 2 | isMiniDes: (formProps: object) => boolean; 3 | } 4 | 5 | declare namespace globalOptions { 6 | 7 | /** WIDGET_MAP 配置 */ 8 | export const WIDGET_MAP:object 9 | 10 | /** COMPONENT_MAP 配置 */ 11 | export const COMPONENT_MAP:object 12 | 13 | /** HELPERS 配置 */ 14 | export const HELPERS: HELPERS 15 | } 16 | 17 | export default globalOptions; 18 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-ant/types/globalOptions.d.ts: -------------------------------------------------------------------------------- 1 | interface HELPERS { 2 | isMiniDes: (formProps: object) => boolean; 3 | } 4 | 5 | declare namespace globalOptions { 6 | 7 | /** WIDGET_MAP 配置 */ 8 | export const WIDGET_MAP:object 9 | 10 | /** COMPONENT_MAP 配置 */ 11 | export const COMPONENT_MAP:object 12 | 13 | /** HELPERS 配置 */ 14 | export const HELPERS: HELPERS 15 | } 16 | 17 | export default globalOptions; 18 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-element/types/globalOptions.d.ts: -------------------------------------------------------------------------------- 1 | interface HELPERS { 2 | isMiniDes: (formProps: object) => boolean; 3 | } 4 | 5 | declare namespace globalOptions { 6 | 7 | /** WIDGET_MAP 配置 */ 8 | export const WIDGET_MAP:object 9 | 10 | /** COMPONENT_MAP 配置 */ 11 | export const COMPONENT_MAP:object 12 | 13 | /** HELPERS 配置 */ 14 | export const HELPERS: HELPERS 15 | } 16 | 17 | export default globalOptions; 18 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-naive/types/globalOptions.d.ts: -------------------------------------------------------------------------------- 1 | interface HELPERS { 2 | isMiniDes: (formProps: object) => boolean; 3 | } 4 | 5 | declare namespace globalOptions { 6 | 7 | /** WIDGET_MAP 配置 */ 8 | export const WIDGET_MAP:object 9 | 10 | /** COMPONENT_MAP 配置 */ 11 | export const COMPONENT_MAP:object 12 | 13 | /** HELPERS 配置 */ 14 | export const HELPERS: HELPERS 15 | } 16 | 17 | export default globalOptions; 18 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/schema-generator/views/editor/viewComponents/DateTimeRange/string.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/10/30 17:11. 3 | */ 4 | 5 | import baseData from './index'; 6 | 7 | export default { 8 | viewSchema: { 9 | ...baseData.viewSchema, 10 | title: 'DateTime范围(字符串)', 11 | items: { 12 | type: 'string' 13 | } 14 | }, 15 | propsSchema: baseData.propsSchema 16 | }; 17 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/CarouselImg/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2019/12/4 15:06. 3 | */ 4 | 5 | import propsSchema from './CarouselImg.json'; 6 | import uiSchema from './uiSchema.js'; 7 | import errorSchema from './errSchema.js'; 8 | 9 | const View = () => import('./View.vue'); 10 | 11 | export default { 12 | View, 13 | propsSchema, 14 | uiSchema, 15 | errorSchema 16 | }; 17 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/MultipleImg1_3/errorSchema.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/4/30 17:40. 3 | */ 4 | 5 | import genImgItem from '../_commonConfig/error/genImgItem'; 6 | 7 | const errorItemSchema = genImgItem(); 8 | 9 | export default { 10 | imgItem1_1: errorItemSchema, 11 | imgItem2_1: errorItemSchema, 12 | imgItem2_2: errorItemSchema, 13 | imgItem2_3: errorItemSchema 14 | }; 15 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/MultipleImg2_3/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2019/12/4 15:06. 3 | */ 4 | 5 | import propsSchema from './schema.json'; 6 | import uiSchema from './uiSchema.js'; 7 | import errorSchema from './errorSchema.js'; 8 | 9 | const View = () => import('./View.vue'); 10 | 11 | export default { 12 | View, 13 | propsSchema, 14 | uiSchema, 15 | errorSchema 16 | }; 17 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/schema-generator/views/editor/viewComponents/Object/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/10/30 17:11. 3 | */ 4 | 5 | import genSchema from '../genSchema.js'; 6 | 7 | const viewSchema = { 8 | title: 'Object', 9 | type: 'object', 10 | required: [], 11 | properties: {}, 12 | 'ui:order': [] 13 | }; 14 | 15 | export default { 16 | viewSchema, 17 | propsSchema: genSchema({}, 'object') 18 | }; 19 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/common/registerExtraElementComponent.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/4/24 10:59. 3 | */ 4 | 5 | import Vue from 'vue'; 6 | 7 | const ExtraComponents = { 8 | // 需要额外注册的 Field,通过图片选择图片加链接 9 | LinkImgField: () => import('../fieldComponents/linkImgField/LinkImgField') 10 | }; 11 | 12 | Object.entries(ExtraComponents).forEach(([key, value]) => { 13 | Vue.component(key, value); 14 | }); 15 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/schema-generator/router/routes/index.js: -------------------------------------------------------------------------------- 1 | const routes = [ 2 | { 3 | path: '/index', 4 | name: 'editor', 5 | meta: { 6 | title: 'Schema generator' 7 | }, 8 | component: () => import('../../views/editor/Editor.vue'), 9 | }, 10 | { 11 | path: '*', 12 | hidden: true, 13 | redirect: { name: 'editor' } 14 | } 15 | ]; 16 | 17 | export default routes; 18 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/MultipleImg1_3/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2019/12/4 15:06. 3 | */ 4 | 5 | import propsSchema from './schema.json'; 6 | import uiSchema from './uiSchema.js'; 7 | import errorSchema from './errorSchema.js'; 8 | 9 | const View = () => import('./component/View.vue'); 10 | 11 | export default { 12 | View, 13 | propsSchema, 14 | uiSchema, 15 | errorSchema 16 | }; 17 | -------------------------------------------------------------------------------- /packages/docs/docs/.vuepress/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Vjsf", 3 | "short_name": "Vue JSON Schema form", 4 | "start_url": "index.html", 5 | "display": "standalone", 6 | "background_color": "#ffffff", 7 | "description": "Vue JSON Schema form", 8 | "theme_color": "blue", 9 | "icons": [ 10 | { 11 | "src": "/logo.png", 12 | "sizes": "144x144", 13 | "type": "image/png" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/schema-generator/schema-generator.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/10/24 9:21 下午. 3 | */ 4 | 5 | import 'demo-common/bootstrap.js'; 6 | 7 | import Vue from 'vue'; 8 | import elementUI from 'demo-common/components/ElementUi/index.js'; 9 | import router from './router'; 10 | import App from './App'; 11 | 12 | // Ui 13 | Vue.use(elementUI); 14 | 15 | new Vue({ 16 | router, 17 | render: h => h(App) 18 | }).$mount('#app'); 19 | -------------------------------------------------------------------------------- /packages/demo/demo-v3/src/pages/index/style.css: -------------------------------------------------------------------------------- 1 | .siteScroll, 2 | .siteHeader_currencyList, 3 | * { 4 | &::-webkit-scrollbar { 5 | width: 6px; 6 | height: 6px; 7 | } 8 | &::-webkit-scrollbar-track { 9 | background-color: white; 10 | } 11 | &::-webkit-scrollbar-thumb { 12 | border-radius: 10px; 13 | background-color: #999999; 14 | } 15 | } 16 | 17 | .hide{ 18 | display: none; 19 | } 20 | -------------------------------------------------------------------------------- /packages/lib/utils/icons/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2021/3/6 2:58 下午. 3 | */ 4 | 5 | import IconCaretDown from './IconCaretDown.vue'; 6 | import IconCaretUp from './IconCaretUp.vue'; 7 | import IconClose from './IconClose.vue'; 8 | import IconPlus from './IconPlus.vue'; 9 | import IconQuestion from './IconQuestion.vue'; 10 | 11 | export { 12 | IconCaretDown, 13 | IconCaretUp, 14 | IconClose, 15 | IconPlus, 16 | IconQuestion 17 | }; 18 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-iview3/src/config/widgets/DateTimePickerWidget/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/7/22 13:21. 3 | */ 4 | 5 | import DatePickerWidget from '../DatePickerWidget'; 6 | 7 | export default { 8 | name: 'DateTimePickerWidget', 9 | functional: true, 10 | render(h, context) { 11 | context.data.attrs.isDatetime = true; 12 | 13 | return h(DatePickerWidget, context.data, context.children); 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | stats.html 4 | 5 | packages/lib/vue2-form-element/stats.html 6 | /packages/docs/docs/.vuepress/dist/ 7 | /packages/demo/demo-v2/dist 8 | /packages/demo/demo-v3/dist 9 | 10 | # local env files 11 | .env.local 12 | .env.*.local 13 | 14 | # Log files 15 | npm-debug.log* 16 | yarn-debug.log* 17 | yarn-error.log* 18 | 19 | # Editor directories and files 20 | .idea 21 | .vscode 22 | *.suo 23 | *.ntvs* 24 | *.njsproj 25 | *.sln 26 | *.sw? 27 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/MultipleImg2_3/errorSchema.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/4/30 17:40. 3 | */ 4 | 5 | import genImgItem from '../_commonConfig/error/genImgItem'; 6 | 7 | const errorItemSchema = genImgItem(); 8 | 9 | export default { 10 | imgItem1_1: errorItemSchema, 11 | imgItem1_2: errorItemSchema, 12 | imgItem2_1: errorItemSchema, 13 | imgItem2_2: errorItemSchema, 14 | imgItem2_3: errorItemSchema 15 | }; 16 | -------------------------------------------------------------------------------- /packages/docs/docs/.vuepress/styles/palette.styl: -------------------------------------------------------------------------------- 1 | // 颜色 2 | $accentColor = #2b9939 3 | $textColor = #303133 4 | $borderColor = #eaecef 5 | $arrowBgColor = #ccc 6 | $codeBgColor = #282c34 7 | $badgeTipColor = #67C23A 8 | $badgeWarningColor = darken(#E6A23C, 35%) 9 | $badgeErrorColor = #F56C6C 10 | 11 | // 布局 12 | $navbarHeight = 3.6rem 13 | $sidebarWidth = 20rem 14 | $contentWidth = 740px 15 | $homePageWidth = 960px 16 | 17 | // 响应式变化点 18 | $MQNarrow = 959px 19 | $MQMobile = 719px 20 | $MQMobileNarrow = 419px 21 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/_commonConfig/error/genImgItem.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/4/30 17:04. 3 | */ 4 | 5 | // errorSchema imgItem 6 | export default function () { 7 | return { 8 | imgUrl: { 9 | 'err:format': '请正常选择图片', 10 | 'err:required': '请选择你要配置的图片' 11 | }, 12 | imgLink: { 13 | 'err:format': '请输入合法的链接地址', 14 | 'err:required': '请输入合法的链接地址' 15 | } 16 | }; 17 | } 18 | -------------------------------------------------------------------------------- /packages/lib/utils/i18n/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/4/30 11:22. 3 | */ 4 | 5 | // 使用 ajv-i18n 这里只为初始化默认可以设置语言 6 | // 也可以自己使用官方的语言包 7 | // https://github.com/epoberezkin/ajv-i18n/tree/master/localize 8 | 9 | import localizeZh from './localize/zh'; 10 | 11 | export default { 12 | $$currentLocalizeFn: localizeZh, 13 | getCurrentLocalize() { 14 | return this.$$currentLocalizeFn; 15 | }, 16 | useLocal(fn) { 17 | this.$$currentLocalizeFn = fn; 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-core/src/fields/IntegerField/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/4/21 9:24. 3 | * IntegerField 复用StringField 4 | */ 5 | 6 | import { h } from 'vue'; 7 | import vueProps from '../props'; 8 | import StringField from '../StringField'; 9 | 10 | export default { 11 | name: 'IntegerField', 12 | props: vueProps, 13 | setup(props, { attrs }) { 14 | return () => h(StringField, { 15 | ...props, 16 | ...attrs 17 | }); 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-core/src/fields/NumberField/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/4/21 9:24. 3 | * NumberField 复用StringField 4 | */ 5 | 6 | import { h } from 'vue'; 7 | import vueProps from '../props'; 8 | import StringField from '../StringField'; 9 | 10 | export default { 11 | name: 'NumberField', 12 | props: vueProps, 13 | setup(props, { attrs }) { 14 | return () => h(StringField, { 15 | ...props, 16 | ...attrs 17 | }); 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/schema-generator/views/editor/viewComponents/Array/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/10/30 17:11. 3 | */ 4 | 5 | import genSchema from '../genSchema.js'; 6 | 7 | const viewSchema = { 8 | title: 'Array', 9 | type: 'array', 10 | items: { 11 | type: 'object', 12 | required: [], 13 | properties: {}, 14 | 'ui:order': [] 15 | } 16 | }; 17 | 18 | export default { 19 | viewSchema, 20 | propsSchema: genSchema({}, 'array') 21 | }; 22 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/Coupon/Coupon.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "type": "object", 4 | "properties": { 5 | "show": { 6 | "title": "显示状态", 7 | "description": "优惠券模块不可编辑,系统会自动抓取您已经创建的优惠券,按照优惠券力度由大到小进行排列 。", 8 | "type": "boolean", 9 | "default": true, 10 | "ui:disabled": true 11 | } 12 | }, 13 | "required": [ 14 | "show" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-core/src/fields/combiningSchemas/AnyOfField/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/5/19 9:49 下午. 3 | */ 4 | 5 | import { h } from 'vue'; 6 | import SelectLinkageField from '../SelectLinkageField'; 7 | 8 | export default { 9 | name: 'AnyOfField', 10 | setup(props, { attrs, slots }) { 11 | return () => h(SelectLinkageField, { 12 | ...attrs, 13 | combiningType: 'anyOf', 14 | selectList: attrs.schema.anyOf 15 | }, slots); 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-core/src/fields/combiningSchemas/OneOfField/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/5/19 9:49 下午. 3 | */ 4 | 5 | import { h } from 'vue'; 6 | import SelectLinkageField from '../SelectLinkageField'; 7 | 8 | export default { 9 | name: 'oneOfField', 10 | setup(props, { attrs, slots }) { 11 | return () => h(SelectLinkageField, { 12 | ...attrs, 13 | combiningType: 'oneOf', 14 | selectList: attrs.schema.oneOf 15 | }, slots); 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/router/routes/index.js: -------------------------------------------------------------------------------- 1 | const routes = [ 2 | { 3 | path: '/editor', 4 | name: 'editor', 5 | component: () => import('../../views/editor/Editor.vue'), 6 | }, 7 | { 8 | path: '/editor-m', 9 | name: 'editorM', 10 | component: () => import('../../views/editor/EditorM.vue'), 11 | }, 12 | { 13 | path: '*', 14 | hidden: true, 15 | redirect: { name: 'editor' } 16 | } 17 | ]; 18 | 19 | export default routes; 20 | -------------------------------------------------------------------------------- /packages/demo/demo-v3/README.md: -------------------------------------------------------------------------------- 1 | # Vue3 Demo 演示相关 2 | 3 | ## 同时运行 `Playground/表单Schema生成器/活动编辑器` 4 | ```ssh 5 | # Playground http://127.0.0.1:8800/ 6 | # 可视化表单Schema编辑器 http://127.0.0.1:8800/schema-generator.html 7 | # (H5)活动编辑器 http://127.0.0.1:8800/vue-editor.html 8 | 9 | yarn run demo:dev 10 | ``` 11 | 12 | ## 单个运行(指定entry编译更快) 13 | ```ssh 14 | # 只运行 Playground 15 | yarn run demo:dev --dir=index 16 | 17 | # 只运行 表单Schema生成器 18 | yarn run demo:dev --dir=schema-generator 19 | 20 | # 只运行(H5)活动编辑器 21 | yarn run demo:dev --dir=vue-editor 22 | ``` 23 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/README.md: -------------------------------------------------------------------------------- 1 | # Vue2 Demo 演示相关 2 | 3 | 4 | ## 同时运行 `Playground/表单Schema生成器/活动编辑器` 5 | ```ssh 6 | # Playground http://127.0.0.1:8800/ 7 | # 可视化表单Schema编辑器 http://127.0.0.1:8800/schema-generator.html 8 | # (H5)活动编辑器 http://127.0.0.1:8800/vue-editor.html 9 | 10 | yarn run demo:dev 11 | ``` 12 | 13 | ## 单个运行(指定entry编译更快) 14 | ```ssh 15 | # 只运行 Playground 16 | yarn run demo:dev --dir=index 17 | 18 | # 只运行 表单Schema生成器 19 | yarn run demo:dev --dir=schema-generator 20 | 21 | # 只运行(H5)活动编辑器 22 | yarn run demo:dev --dir=vue-editor 23 | ``` 24 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/AllGoodsList/AllGoodsList.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "type": "object", 4 | "properties": { 5 | "show": { 6 | "type": "boolean", 7 | "title": "添加全部商品", 8 | "description": "全部商品模块不可编辑,不可移除,自动置底;系统会获取全部商品。", 9 | "default": true, 10 | "ui:label": true, 11 | "ui:disabled": true 12 | } 13 | }, 14 | "required": [ 15 | "show" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-element/src/style.css: -------------------------------------------------------------------------------- 1 | /* element plus 重置样式*/ 2 | .genFromComponent { 3 | &.el-form--label-top { 4 | .el-form-item__label { 5 | line-height: 26px; 6 | } 7 | .genFromWidget_des { 8 | margin-bottom: 4px; 9 | margin-top: -4px; 10 | } 11 | } 12 | .el-checkbox, .el-color-picker{ 13 | vertical-align: top; 14 | } 15 | .formFooter_item { 16 | .el-form-item__content { 17 | justify-content: flex-end; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/index/App.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 15 | 16 | 23 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/RecommendedGoodsList/RecommendedGoodsList.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "type": "object", 4 | "properties": { 5 | "show": { 6 | "title": "添加推荐商品", 7 | "description": "推荐商品模块不可编辑,系统自动基于大数据做商品推荐", 8 | "type": "boolean", 9 | "default": true, 10 | "ui:label": true, 11 | "ui:disabled": true 12 | } 13 | }, 14 | "required": [ 15 | "show" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /packages/demo/demo-v3/src/pages/index/App.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 15 | 16 | 23 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponentsM/Text/propsSchema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "title": "单文本输入组件", 4 | "description":"单文本输入组件,用于在页面配置一条文字信息" , 5 | "type": "object", 6 | "required": ["txt"], 7 | "properties": { 8 | "txt": { 9 | "title": "文字", 10 | "type": "string" 11 | }, 12 | "txtColor": { 13 | "title": "选择文字颜色", 14 | "type": "string", 15 | "default": "#ff0132" 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/vue-editor.css: -------------------------------------------------------------------------------- 1 | @import "demo-common/css/variable.css"; 2 | 3 | body{ 4 | background: #FFFFFF; 5 | box-sizing: border-box; 6 | } 7 | div, ul, li{ 8 | box-sizing: border-box; 9 | } 10 | .hover-animation { 11 | transition: opacity .3s ease-out; 12 | &:hover { 13 | opacity: .7; 14 | } 15 | } 16 | 17 | .module-name-tip { 18 | position: absolute; 19 | top: 0; 20 | right: 0; 21 | font-size: 16px; 22 | padding: 8px 15px; 23 | background: rgba(0,0,0,0.8); 24 | color: #FFFFFF; 25 | } 26 | -------------------------------------------------------------------------------- /packages/docs/docs/.vuepress/styles/index.styl: -------------------------------------------------------------------------------- 1 | // placeholder for test, dont't remove it. 2 | 3 | //.content { 4 | // font-size 30px; 5 | //} 6 | 7 | .contains-task-list 8 | li { 9 | list-style-type:none; 10 | } 11 | 12 | .custom-page-home 13 | .home 14 | .hero 15 | padding: 50px 0; 16 | img { 17 | width 200px; 18 | margin-bottom: 3rem; 19 | } 20 | .description 21 | font-size: 1.1rem; 22 | h3 { 23 | color: $accentColor; 24 | } 25 | -------------------------------------------------------------------------------- /packages/demo/demo-v3/src/pages/index/routes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/5/13 8:47 下午. 3 | */ 4 | 5 | const routes = [ 6 | { 7 | path: '/demo', 8 | name: 'demo', 9 | meta: { 10 | title: 'Demo' 11 | }, 12 | component: () => import('./views/Demo/index'), 13 | }, 14 | { 15 | path: '/:pathMatch(.*)*', 16 | redirect: { 17 | name: 'demo', 18 | query: { 19 | type: 'Simple' 20 | } 21 | } 22 | } 23 | ]; 24 | 25 | export default routes; 26 | -------------------------------------------------------------------------------- /packages/demo/demo-common/utils/id.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/4/28 18:06. 3 | */ 4 | 5 | 6 | // 只保证同时生成不重复 7 | export default function genIdFn() { 8 | let preKey = `${+new Date()}`; 9 | let key = 0; 10 | return () => { 11 | const curTimestamp = `${+new Date()}`; 12 | if (curTimestamp === preKey) { 13 | key += 1; 14 | } else { 15 | // 重置 key 16 | key = 0; 17 | } 18 | 19 | preKey = curTimestamp; 20 | return `${preKey}x${key}`; 21 | }; 22 | } 23 | 24 | export const genId = genIdFn(); 25 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/index/routes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/5/13 8:47 下午. 3 | */ 4 | 5 | const routes = [ 6 | { 7 | path: '/demo', 8 | name: 'demo', 9 | meta: { 10 | title: 'Demo' 11 | }, 12 | component: () => import('./views/Demo/index'), 13 | }, 14 | { 15 | path: '*', 16 | hidden: true, 17 | redirect: { 18 | name: 'demo', 19 | query: { 20 | type: 'Simple' 21 | } 22 | } 23 | } 24 | ]; 25 | 26 | export default routes; 27 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-iview3/src/config/widgets/InputNumberWidget/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2021/1/2 10:56 下午. 3 | */ 4 | 5 | export default { 6 | name: 'SwitchWidget', 7 | functional: true, 8 | render(h, context) { 9 | // iview3 input number undefined 会默认为 1,需要抹平差异 10 | 11 | // 实际的数据为 undefined 保持和jsonSchema 一致 12 | // 传递给 iview 时转换为 null,兼容iview3清空场景 13 | if (context.data.attrs.value === undefined) context.data.attrs.value = null; 14 | 15 | return h('input-number', context.data, context.children); 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/vue-editor.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2019/9/29 15:29. 3 | */ 4 | 5 | // bootstrap 6 | import 'demo-common/bootstrap.js'; 7 | import Vue from 'vue'; 8 | import elementUI from 'demo-common/components/ElementUi/index.js'; 9 | 10 | import './vue-editor.css'; 11 | import router from './router'; 12 | import routerGuards from './router/guards'; 13 | import App from './App'; 14 | 15 | // Ui 16 | Vue.use(elementUI); 17 | 18 | // 添加路由守卫 19 | routerGuards(router); // 路由守卫 20 | 21 | new Vue({ 22 | router, 23 | render: h => h(App) 24 | }).$mount('#app'); 25 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/AllGoodsList/component/View.vue: -------------------------------------------------------------------------------- 1 | 8 | 24 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-element/src/config/widgets/SelectWidget/index.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 25 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-ant/types/vueForm.d.ts: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | 3 | declare class VueForm extends Vue { 4 | /** formFooter 配置 */ 5 | formFooter: object 6 | 7 | /** value / v-model */ 8 | value: object 9 | 10 | /** 传递给form的props */ 11 | formProps: object 12 | 13 | /** schema 配置 */ 14 | schema: object 15 | 16 | /** uiSchema 配置 */ 17 | uiSchema: object 18 | 19 | /** 重置自定义错误 */ 20 | errorSchema: object 21 | 22 | /** 自定义校验规则 */ 23 | customFormats: object 24 | 25 | /** 自定义校验规则 */ 26 | customRule: null 27 | } 28 | 29 | export default VueForm; 30 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/RecommendedGoodsList/component/View.vue: -------------------------------------------------------------------------------- 1 | 8 | 24 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-element/types/vueForm.d.ts: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | 3 | declare class VueForm extends Vue { 4 | /** formFooter 配置 */ 5 | formFooter: object 6 | 7 | /** value / v-model */ 8 | value: object 9 | 10 | /** 传递给form的props */ 11 | formProps: object 12 | 13 | /** schema 配置 */ 14 | schema: object 15 | 16 | /** uiSchema 配置 */ 17 | uiSchema: object 18 | 19 | /** 重置自定义错误 */ 20 | errorSchema: object 21 | 22 | /** 自定义校验规则 */ 23 | customFormats: object 24 | 25 | /** 自定义校验规则 */ 26 | customRule: null 27 | } 28 | 29 | export default VueForm; 30 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-iview3/src/config/widgets/TimePickerWidget/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/7/22 13:22. 3 | */ 4 | 5 | export default { 6 | name: 'TimePickerWidget', 7 | functional: true, 8 | render(h, context) { 9 | const oldInputCall = context.data.on.input; 10 | context.data.on = { 11 | ...context.data.on, 12 | input(val) { 13 | oldInputCall.apply(context.data.on, [val === null ? undefined : val]); 14 | } 15 | }; 16 | 17 | return h('time-picker', context.data, context.children); 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-iview3/types/vueForm.d.ts: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | 3 | declare class VueForm extends Vue { 4 | /** formFooter 配置 */ 5 | formFooter: object 6 | 7 | /** value / v-model */ 8 | value: object 9 | 10 | /** 传递给form的props */ 11 | formProps: object 12 | 13 | /** schema 配置 */ 14 | schema: object 15 | 16 | /** uiSchema 配置 */ 17 | uiSchema: object 18 | 19 | /** 重置自定义错误 */ 20 | errorSchema: object 21 | 22 | /** 自定义校验规则 */ 23 | customFormats: object 24 | 25 | /** 自定义校验规则 */ 26 | customRule: null 27 | } 28 | 29 | export default VueForm; 30 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-element/types/vueForm.d.ts: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | 3 | declare class VueForm extends Vue { 4 | /** formFooter 配置 */ 5 | formFooter: object 6 | 7 | /** value / v-model */ 8 | value: object 9 | 10 | /** 传递给form的props */ 11 | formProps: object 12 | 13 | /** schema 配置 */ 14 | schema: object 15 | 16 | /** uiSchema 配置 */ 17 | uiSchema: object 18 | 19 | /** 重置自定义错误 */ 20 | errorSchema: object 21 | 22 | /** 自定义校验规则 */ 23 | customFormats: object 24 | 25 | /** 自定义校验规则 */ 26 | customRule: null 27 | } 28 | 29 | export default VueForm; 30 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-naive/types/vueForm.d.ts: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | 3 | declare class VueForm extends Vue { 4 | /** formFooter 配置 */ 5 | formFooter: object 6 | 7 | /** value / v-model */ 8 | value: object 9 | 10 | /** 传递给form的props */ 11 | formProps: object 12 | 13 | /** schema 配置 */ 14 | schema: object 15 | 16 | /** uiSchema 配置 */ 17 | uiSchema: object 18 | 19 | /** 重置自定义错误 */ 20 | errorSchema: object 21 | 22 | /** 自定义校验规则 */ 23 | customFormats: object 24 | 25 | /** 自定义校验规则 */ 26 | customRule: null 27 | } 28 | 29 | export default VueForm; 30 | -------------------------------------------------------------------------------- /packages/lib/utils/icons/IconClose.vue: -------------------------------------------------------------------------------- 1 | 14 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-element/src/config/widgets/RadioWidget/index.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 26 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-element/src/config/widgets/SelectWidget/index.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 26 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-iview3/src/config/widgets/RadioWidget/index.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 27 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-iview3/src/config/widgets/SelectWidget/index.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 27 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-element/src/config/widgets/CheckboxesWidget/index.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 26 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/_commonConfig/ui/genImgItem.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/4/30 17:04. 3 | */ 4 | 5 | // uiSchema imgItem 6 | export default function ({ 7 | field = 'LinkImgField', 8 | width = 580, 9 | height = 580, 10 | } = { }) { 11 | return { 12 | 'ui:field': field, 13 | // 'ui:description': `宽度${width}px,高度${height}x。支持JPG、PNG 图片格式,大小不得超过 2 MB。
`, 14 | 'ui:options': { 15 | type: ['jpg', 'jpeg', 'png'], 16 | size: 2048, 17 | width, 18 | height, 19 | limit: 1 20 | } 21 | }; 22 | } 23 | -------------------------------------------------------------------------------- /packages/docs/docs/.vuepress/plugins/demo-container/src/i18n/default_lang.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "lang": "zh-CN", 4 | "demo-block": { 5 | "online-run": "在线运行", 6 | "hide-text": "隐藏代码", 7 | "show-text": "显示代码", 8 | "copy-text": "复制代码", 9 | "copy-success": "复制成功" 10 | } 11 | }, 12 | { 13 | "lang": "en-US", 14 | "demo-block": { 15 | "online-run": "Try it!", 16 | "hide-text": "Hide", 17 | "show-text": "Expand", 18 | "copy-text": "Copy", 19 | "copy-success": "Successful" 20 | } 21 | } 22 | ] 23 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-element/types/index.d.ts: -------------------------------------------------------------------------------- 1 | import JsonSchemaForm from './vueForm'; 2 | import getDefaultFormState from './getDefaultFormState'; 3 | import fieldProps from './fieldProps'; 4 | import vueUtils from './vueUtils'; 5 | import formUtils from './formUtils'; 6 | import schemaValidate from './schemaValidate'; 7 | import i18n from './i18n'; 8 | import globalOptions from './globalOptions'; 9 | 10 | export default JsonSchemaForm; 11 | 12 | export { 13 | globalOptions, 14 | getDefaultFormState, 15 | fieldProps, 16 | vueUtils, 17 | formUtils, 18 | schemaValidate, 19 | i18n 20 | }; 21 | 22 | export class SchemaField {} 23 | -------------------------------------------------------------------------------- /packages/docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docs", 3 | "version": "1.19.0", 4 | "private": true, 5 | "license": "Apache-2.0", 6 | "scripts": { 7 | "dev": "vuepress dev docs", 8 | "dev:debug": "vuepress dev docs --no-cache --debug", 9 | "build": "vuepress build docs" 10 | }, 11 | "dependencies": { 12 | "@lljj/vue-json-schema-form": "1.19.0", 13 | "element-ui": "^2.13.2", 14 | "v-distpicker": "^1.2.7" 15 | }, 16 | "devDependencies": { 17 | "@vuepress/plugin-medium-zoom": "^1.5.2", 18 | "@vuepress/plugin-pwa": "^1.5.2", 19 | "vuepress": "^1.5.4" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-core/src/fields/combiningSchemas/AnyOfField/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/5/19 9:49 下午. 3 | */ 4 | 5 | import SelectLinkageField from '../SelectLinkageField'; 6 | 7 | export default { 8 | name: 'AnyOfField', 9 | functional: true, 10 | render(h, context) { 11 | const { props, ...otherData } = context.data; 12 | return h(SelectLinkageField, { 13 | ...otherData, 14 | props: { 15 | ...props, 16 | combiningType: 'anyOf', 17 | selectList: props.schema.anyOf 18 | } 19 | }, context.children); 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-core/src/fields/combiningSchemas/OneOfField/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/5/19 9:49 下午. 3 | */ 4 | 5 | import SelectLinkageField from '../SelectLinkageField'; 6 | 7 | export default { 8 | name: 'oneOfField', 9 | functional: true, 10 | render(h, context) { 11 | const { props, ...otherData } = context.data; 12 | return h(SelectLinkageField, { 13 | ...otherData, 14 | props: { 15 | ...props, 16 | combiningType: 'oneOf', 17 | selectList: props.schema.oneOf 18 | } 19 | }, context.children); 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-element/src/config/widgets/RadioWidget/index.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 27 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-element/types/index.d.ts: -------------------------------------------------------------------------------- 1 | import JsonSchemaForm from './vueForm'; 2 | import getDefaultFormState from './getDefaultFormState'; 3 | import fieldProps from './fieldProps'; 4 | import vueUtils from './vueUtils'; 5 | import formUtils from './formUtils'; 6 | import schemaValidate from './schemaValidate'; 7 | import i18n from './i18n'; 8 | import globalOptions from './globalOptions'; 9 | 10 | 11 | export default JsonSchemaForm; 12 | 13 | export { 14 | globalOptions, 15 | getDefaultFormState, 16 | fieldProps, 17 | vueUtils, 18 | formUtils, 19 | schemaValidate, 20 | i18n 21 | }; 22 | 23 | export class SchemaField {} 24 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-iview3/types/index.d.ts: -------------------------------------------------------------------------------- 1 | import JsonSchemaForm from './vueForm'; 2 | import getDefaultFormState from './getDefaultFormState'; 3 | import fieldProps from './fieldProps'; 4 | import vueUtils from './vueUtils'; 5 | import formUtils from './formUtils'; 6 | import schemaValidate from './schemaValidate'; 7 | import i18n from './i18n'; 8 | import globalOptions from './globalOptions'; 9 | 10 | 11 | export default JsonSchemaForm; 12 | 13 | export { 14 | globalOptions, 15 | getDefaultFormState, 16 | fieldProps, 17 | vueUtils, 18 | formUtils, 19 | schemaValidate, 20 | i18n 21 | }; 22 | 23 | export class SchemaField {} 24 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/CarouselImg/uiSchema.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/4/30 17:13. 3 | */ 4 | 5 | import genImgItem from '../_commonConfig/ui/genImgItem'; 6 | 7 | export default { 8 | imgList: { 9 | 'ui:options': { 10 | title: '添加图片', 11 | description: '图片宽度1920px,高度固定500px。这里使用默认的field和校验提示', 12 | showIndexNumber: true 13 | }, 14 | items: { 15 | ...genImgItem({ 16 | width: 1920, 17 | height: 500, 18 | }), 19 | 'ui:title': '轮播图片配置' 20 | } 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-iview3/src/config/widgets/CheckboxesWidget/index.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 27 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-element/src/config/widgets/CheckboxesWidget/index.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 27 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-ant/types/schemaValidate.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace schemaValidate { 2 | /** schema通过ajv校验formData并返回错误信息 */ 3 | function ajvValidateFormData(options: object): object; 4 | 5 | /** 校验formData 并转换错误信息 */ 6 | function validateFormDataAndTransformMsg(options: object): object; 7 | 8 | /** schema 是否通过校验 */ 9 | function isValid(schema: object, data: any): boolean; 10 | 11 | /** ajv validate 方法 */ 12 | function ajvValid(schema: object, data: any): boolean; 13 | 14 | /** oneOf anyOf 通过formData的值来找到当前匹配项索引 */ 15 | function getMatchingOption(formData: object, options: object, rootSchema: object): boolean; 16 | } 17 | 18 | export default schemaValidate; 19 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/index/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/5/13 15:52. 3 | */ 4 | 5 | import 'demo-common/bootstrap.js'; 6 | import Vue from 'vue'; 7 | import VueRouter from 'VueRouter'; 8 | import elementUI from 'demo-common/components/ElementUi/index.js'; 9 | 10 | import routes from './routes'; 11 | 12 | import App from './App'; 13 | 14 | import './style.css'; 15 | 16 | Vue.use(VueRouter); 17 | 18 | // Ui 19 | Vue.use(elementUI); 20 | 21 | new Vue({ 22 | router: new VueRouter({ 23 | mode: 'hash', 24 | routes, 25 | scrollBehavior() { 26 | return { x: 0, y: 0 }; 27 | } 28 | }), 29 | render: h => h(App) 30 | }).$mount('#app'); 31 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-element/types/schemaValidate.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace schemaValidate { 2 | /** schema通过ajv校验formData并返回错误信息 */ 3 | function ajvValidateFormData(options: object): object; 4 | 5 | /** 校验formData 并转换错误信息 */ 6 | function validateFormDataAndTransformMsg(options: object): object; 7 | 8 | /** schema 是否通过校验 */ 9 | function isValid(schema: object, data: any): boolean; 10 | 11 | /** ajv validate 方法 */ 12 | function ajvValid(schema: object, data: any): boolean; 13 | 14 | /** oneOf anyOf 通过formData的值来找到当前匹配项索引 */ 15 | function getMatchingOption(formData: object, options: object, rootSchema: object): boolean; 16 | } 17 | 18 | export default schemaValidate; 19 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-iview3/types/schemaValidate.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace schemaValidate { 2 | /** schema通过ajv校验formData并返回错误信息 */ 3 | function ajvValidateFormData(options: object): object; 4 | 5 | /** 校验formData 并转换错误信息 */ 6 | function validateFormDataAndTransformMsg(options: object): object; 7 | 8 | /** schema 是否通过校验 */ 9 | function isValid(schema: object, data: any): boolean; 10 | 11 | /** ajv validate 方法 */ 12 | function ajvValid(schema: object, data: any): boolean; 13 | 14 | /** oneOf anyOf 通过formData的值来找到当前匹配项索引 */ 15 | function getMatchingOption(formData: object, options: object, rootSchema: object): boolean; 16 | } 17 | 18 | export default schemaValidate; 19 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-element/types/schemaValidate.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace schemaValidate { 2 | /** schema通过ajv校验formData并返回错误信息 */ 3 | function ajvValidateFormData(options: object): object; 4 | 5 | /** 校验formData 并转换错误信息 */ 6 | function validateFormDataAndTransformMsg(options: object): object; 7 | 8 | /** schema 是否通过校验 */ 9 | function isValid(schema: object, data: any): boolean; 10 | 11 | /** ajv validate 方法 */ 12 | function ajvValid(schema: object, data: any): boolean; 13 | 14 | /** oneOf anyOf 通过formData的值来找到当前匹配项索引 */ 15 | function getMatchingOption(formData: object, options: object, rootSchema: object): boolean; 16 | } 17 | 18 | export default schemaValidate; 19 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-naive/types/schemaValidate.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace schemaValidate { 2 | /** schema通过ajv校验formData并返回错误信息 */ 3 | function ajvValidateFormData(options: object): object; 4 | 5 | /** 校验formData 并转换错误信息 */ 6 | function validateFormDataAndTransformMsg(options: object): object; 7 | 8 | /** schema 是否通过校验 */ 9 | function isValid(schema: object, data: any): boolean; 10 | 11 | /** ajv validate 方法 */ 12 | function ajvValid(schema: object, data: any): boolean; 13 | 14 | /** oneOf anyOf 通过formData的值来找到当前匹配项索引 */ 15 | function getMatchingOption(formData: object, options: object, rootSchema: object): boolean; 16 | } 17 | 18 | export default schemaValidate; 19 | -------------------------------------------------------------------------------- /packages/demo/demo-common/components/ElementUi/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/11/20 9:43. 3 | */ 4 | 5 | import './theme/index.css'; 6 | import ELEMENT from 'ELEMENT'; 7 | 8 | const { 9 | Loading, 10 | MessageBox, 11 | Message 12 | } = ELEMENT; 13 | 14 | export default { 15 | install(Vue) { 16 | Vue.use(Loading.directive); 17 | // 原型方法 18 | Vue.prototype.$loading = Loading.service; 19 | Vue.prototype.$alert = MessageBox.alert; 20 | Vue.prototype.$confirm = MessageBox.confirm; 21 | Vue.prototype.$prompt = MessageBox.prompt; 22 | Vue.prototype.$msgbox = MessageBox; 23 | Vue.prototype.$message = Message; 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /packages/demo/demo-common/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-common", 3 | "version": "1.17.1", 4 | "description": "vue json schema form demo公共代码", 5 | "keywords": [ 6 | "@lljj/vjsf-utils", 7 | "vue", 8 | "vuejs", 9 | "form", 10 | "jsonSchema" 11 | ], 12 | "repository": "https://github.com/lljj-x/vue-json-schema-form", 13 | "homepage": "https://github.com/lljj-x/vue-json-schema-form", 14 | "license": "Apache-2.0", 15 | "private": true, 16 | "author": "Liu.Jun", 17 | "browserslist": [ 18 | "> 1%", 19 | "last 2 versions", 20 | "not ie <= 8" 21 | ], 22 | "gitHead": "92795075169c879e1c1fabfe26f1d3c10b861060" 23 | } 24 | -------------------------------------------------------------------------------- /packages/docs/docs/.vuepress/plugins/demo-container/src/common/fence.js: -------------------------------------------------------------------------------- 1 | // 覆盖默认的 fence 渲染策略 2 | module.exports = md => { 3 | const defaultRender = md.renderer.rules.fence; 4 | md.renderer.rules.fence = (tokens, idx, options, env, self) => { 5 | const token = tokens[idx]; 6 | // 判断该 fence 是否在 :::demo 内 7 | const prevToken = tokens[idx - 1]; 8 | const isInDemoContainer = prevToken && prevToken.nesting === 1 && prevToken.info.trim().match(/^demo\s*(.*)$/); 9 | if (token.info === 'html' && isInDemoContainer) { 10 | return ``; 11 | } 12 | return defaultRender(tokens, idx, options, env, self); 13 | }; 14 | }; -------------------------------------------------------------------------------- /packages/lib/utils/icons/IconPlus.vue: -------------------------------------------------------------------------------- 1 | 23 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponentsM/Test/View.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 20 | 21 | 32 | -------------------------------------------------------------------------------- /packages/lib/.eslintrc.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = { 4 | root: true, 5 | env: { 6 | browser: true, 7 | worker: true, 8 | }, 9 | parserOptions: { 10 | parser: 'babel-eslint', 11 | sourceType: 'module' 12 | }, 13 | plugins: ['vue'], 14 | extends: [ 15 | '@lljj/eslint-config', 16 | '@lljj/eslint-config/vue' 17 | ], 18 | rules: { 19 | // 递归组件导致了循环依赖 20 | 'import/no-cycle': 'off', 21 | }, 22 | globals: { 23 | 'self': true 24 | }, 25 | overrides: [ 26 | { 27 | files: ["*.vue"], 28 | rules: { 29 | "indent": "off", 30 | } 31 | } 32 | ] 33 | }; 34 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-ant/src/config/widgets/TimePickerWidget/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/7/22 13:22. 3 | */ 4 | 5 | import { h } from 'vue'; 6 | import { resolveComponent } from '@lljj/vjsf-utils/vue3Utils'; 7 | import { modelValueComponent } from '../../utils'; 8 | 9 | const baseComponent = { 10 | name: 'TimePickerWidget', 11 | inheritAttrs: false, 12 | setup(props, { attrs }) { 13 | return () => h(resolveComponent('a-time-picker'), { 14 | 'value-format': 'HH:mm:ss', 15 | ...attrs 16 | }); 17 | } 18 | }; 19 | 20 | const moduleValeComponent = modelValueComponent(baseComponent, { 21 | model: 'value' 22 | }); 23 | 24 | export default moduleValeComponent; 25 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-ant/types/index.d.ts: -------------------------------------------------------------------------------- 1 | import JsonSchemaForm from './vueForm'; 2 | import getDefaultFormState from './getDefaultFormState'; 3 | import modelValueComponent from './modelValueComponent'; 4 | import fieldProps from './fieldProps'; 5 | import vueUtils from './vueUtils'; 6 | import formUtils from './formUtils'; 7 | import schemaValidate from './schemaValidate'; 8 | import i18n from './i18n'; 9 | import globalOptions from './globalOptions'; 10 | 11 | export default JsonSchemaForm; 12 | 13 | export { 14 | globalOptions, 15 | getDefaultFormState, 16 | fieldProps, 17 | vueUtils, 18 | formUtils, 19 | schemaValidate, 20 | i18n, 21 | modelValueComponent 22 | }; 23 | 24 | export class SchemaField {} 25 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/.eslintrc.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = { 4 | root: true, 5 | env: { 6 | browser: true, 7 | worker: true, 8 | }, 9 | parserOptions: { 10 | parser: 'babel-eslint', 11 | sourceType: 'module' 12 | }, 13 | plugins: ['vue'], 14 | extends: [ 15 | '@lljj/eslint-config', 16 | '@lljj/eslint-config/vue' 17 | ], 18 | rules: { 19 | // 递归组件导致了循环依赖 20 | 'import/no-cycle': 'off', 21 | }, 22 | globals: { 23 | 'self': true 24 | }, 25 | overrides: [ 26 | { 27 | files: ["*.vue"], 28 | rules: { 29 | "indent": "off", 30 | } 31 | } 32 | ] 33 | }; 34 | -------------------------------------------------------------------------------- /packages/demo/demo-v3/.eslintrc.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = { 4 | root: true, 5 | env: { 6 | browser: true, 7 | worker: true, 8 | }, 9 | parserOptions: { 10 | parser: 'babel-eslint', 11 | sourceType: 'module' 12 | }, 13 | plugins: ['vue'], 14 | extends: [ 15 | '@lljj/eslint-config', 16 | '@lljj/eslint-config/vue' 17 | ], 18 | rules: { 19 | // 递归组件导致了循环依赖 20 | 'import/no-cycle': 'off', 21 | }, 22 | globals: { 23 | 'self': true 24 | }, 25 | overrides: [ 26 | { 27 | files: ["*.vue"], 28 | rules: { 29 | "indent": "off", 30 | } 31 | } 32 | ] 33 | }; 34 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-iview3/src/style.css: -------------------------------------------------------------------------------- 1 | .genFromComponent { 2 | &.ivu-form-label-top { 3 | .ivu-form-item-label { 4 | line-height: 26px; 5 | padding-bottom: 6px; 6 | } 7 | } 8 | .ivu-form-item-error-tip { 9 | padding-top: 2px; 10 | position: absolute; 11 | display: -webkit-box!important; 12 | text-overflow: ellipsis; 13 | overflow: hidden; 14 | -webkit-box-orient: vertical; 15 | -webkit-line-clamp: 2; 16 | white-space: normal; 17 | text-align: left; 18 | line-height: 1.2; 19 | } 20 | .validateWidget .ivu-form-item-error-tip { 21 | padding: 5px 0; 22 | position: relative; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/demo/demo-common/.eslintrc.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = { 4 | root: true, 5 | env: { 6 | browser: true, 7 | worker: true, 8 | }, 9 | parserOptions: { 10 | parser: 'babel-eslint', 11 | sourceType: 'module' 12 | }, 13 | plugins: ['vue'], 14 | extends: [ 15 | '@lljj/eslint-config', 16 | '@lljj/eslint-config/vue' 17 | ], 18 | rules: { 19 | // 递归组件导致了循环依赖 20 | 'import/no-cycle': 'off', 21 | }, 22 | globals: { 23 | 'self': true 24 | }, 25 | overrides: [ 26 | { 27 | files: ["*.vue"], 28 | rules: { 29 | "indent": "off", 30 | } 31 | } 32 | ] 33 | }; 34 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-element/src/config/widgets/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/5/17 10:41 下午. 3 | */ 4 | 5 | import CheckboxesWidget from './CheckboxesWidget'; 6 | import RadioWidget from './RadioWidget'; 7 | import SelectWidget from './SelectWidget'; 8 | import DatePickerWidget from './DatePickerWidget'; 9 | import DateTimePickerWidget from './DateTimePickerWidget'; 10 | import TimePickerWidget from './TimePickerWidget'; 11 | import UploadWidget from './UploadWidget'; 12 | 13 | const widgetComponents = { 14 | CheckboxesWidget, 15 | RadioWidget, 16 | SelectWidget, 17 | TimePickerWidget, 18 | DatePickerWidget, 19 | DateTimePickerWidget, 20 | UploadWidget 21 | }; 22 | 23 | export default widgetComponents; 24 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-element/src/config/widgets/TimePickerWidget/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/7/22 13:22. 3 | */ 4 | 5 | export default { 6 | name: 'TimePickerWidget', 7 | functional: true, 8 | render(h, context) { 9 | context.data.attrs = { 10 | 'value-format': 'HH:mm:ss', 11 | ...context.data.attrs || {} 12 | }; 13 | 14 | const oldInputCall = context.data.on.input; 15 | context.data.on = { 16 | ...context.data.on, 17 | input(val) { 18 | oldInputCall.apply(context.data.on, [val === null ? undefined : val]); 19 | } 20 | }; 21 | 22 | return h('el-time-picker', context.data, context.children); 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-ant/types/fieldProps.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace fieldProps { 2 | 3 | /** 当前节点schema */ 4 | export const schema:object 5 | 6 | /** 当前节点 uiSchema */ 7 | 8 | export const uiSchema:object 9 | 10 | /** 当前节点 errorSchema */ 11 | export const errorSchema:object 12 | 13 | /** 自定义校验规则 */ 14 | export const customFormats:object 15 | 16 | /** 根节点 schema */ 17 | export const rootSchema:object 18 | 19 | /** 根节点 formData */ 20 | export const rootFormData:object 21 | 22 | /** 当前节点 路径 */ 23 | export const curNodePath:string 24 | 25 | /** 是否为必填 */ 26 | export const required:boolean 27 | 28 | /** 是否需要校验数据组 */ 29 | export const needValidFieldGroup:boolean 30 | } 31 | 32 | export default fieldProps; 33 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponentsM/CarouselImg/uiSchema.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/4/30 17:13. 3 | */ 4 | 5 | import genImgItem from '../../viewComponents/_commonConfig/ui/genImgItem'; 6 | 7 | export default { 8 | imgList: { 9 | 'ui:options': { 10 | title: '添加图片', 11 | description: '图片宽度750px,高度固定400px。这里使用默认的field和校验提示' 12 | }, 13 | items: { 14 | ...genImgItem({ 15 | width: 1920, 16 | height: 500, 17 | }), 18 | imgLink: { 19 | 'err:format': '请输入正确的的链接地址', 20 | 'err:required': '不能为空' 21 | }, 22 | 'ui:title': '轮播图片配置' 23 | } 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-element/types/fieldProps.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace fieldProps { 2 | 3 | /** 当前节点schema */ 4 | export const schema:object 5 | 6 | /** 当前节点 uiSchema */ 7 | 8 | export const uiSchema:object 9 | 10 | /** 当前节点 errorSchema */ 11 | export const errorSchema:object 12 | 13 | /** 自定义校验规则 */ 14 | export const customFormats:object 15 | 16 | /** 根节点 schema */ 17 | export const rootSchema:object 18 | 19 | /** 根节点 formData */ 20 | export const rootFormData:object 21 | 22 | /** 当前节点 路径 */ 23 | export const curNodePath:string 24 | 25 | /** 是否为必填 */ 26 | export const required:boolean 27 | 28 | /** 是否需要校验数据组 */ 29 | export const needValidFieldGroup:boolean 30 | } 31 | 32 | export default fieldProps; 33 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-iview3/types/fieldProps.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace fieldProps { 2 | 3 | /** 当前节点schema */ 4 | export const schema:object 5 | 6 | /** 当前节点 uiSchema */ 7 | 8 | export const uiSchema:object 9 | 10 | /** 当前节点 errorSchema */ 11 | export const errorSchema:object 12 | 13 | /** 自定义校验规则 */ 14 | export const customFormats:object 15 | 16 | /** 根节点 schema */ 17 | export const rootSchema:object 18 | 19 | /** 根节点 formData */ 20 | export const rootFormData:object 21 | 22 | /** 当前节点 路径 */ 23 | export const curNodePath:string 24 | 25 | /** 是否为必填 */ 26 | export const required:boolean 27 | 28 | /** 是否需要校验数据组 */ 29 | export const needValidFieldGroup:boolean 30 | } 31 | 32 | export default fieldProps; 33 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-element/types/fieldProps.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace fieldProps { 2 | 3 | /** 当前节点schema */ 4 | export const schema:object 5 | 6 | /** 当前节点 uiSchema */ 7 | 8 | export const uiSchema:object 9 | 10 | /** 当前节点 errorSchema */ 11 | export const errorSchema:object 12 | 13 | /** 自定义校验规则 */ 14 | export const customFormats:object 15 | 16 | /** 根节点 schema */ 17 | export const rootSchema:object 18 | 19 | /** 根节点 formData */ 20 | export const rootFormData:object 21 | 22 | /** 当前节点 路径 */ 23 | export const curNodePath:string 24 | 25 | /** 是否为必填 */ 26 | export const required:boolean 27 | 28 | /** 是否需要校验数据组 */ 29 | export const needValidFieldGroup:boolean 30 | } 31 | 32 | export default fieldProps; 33 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-naive/types/fieldProps.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace fieldProps { 2 | 3 | /** 当前节点schema */ 4 | export const schema:object 5 | 6 | /** 当前节点 uiSchema */ 7 | 8 | export const uiSchema:object 9 | 10 | /** 当前节点 errorSchema */ 11 | export const errorSchema:object 12 | 13 | /** 自定义校验规则 */ 14 | export const customFormats:object 15 | 16 | /** 根节点 schema */ 17 | export const rootSchema:object 18 | 19 | /** 根节点 formData */ 20 | export const rootFormData:object 21 | 22 | /** 当前节点 路径 */ 23 | export const curNodePath:string 24 | 25 | /** 是否为必填 */ 26 | export const required:boolean 27 | 28 | /** 是否需要校验数据组 */ 29 | export const needValidFieldGroup:boolean 30 | } 31 | 32 | export default fieldProps; 33 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/MultipleImg1_3/uiSchema.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/4/30 17:13. 3 | */ 4 | 5 | import genImgItem from '../_commonConfig/ui/genImgItem'; 6 | 7 | const line2Item = genImgItem({ 8 | width: 383, 9 | height: 500, 10 | }); 11 | 12 | export default { 13 | imgItem1_1: { 14 | 'ui:title': '图片上', 15 | ...genImgItem({ 16 | width: 1920, 17 | height: 420, 18 | }) 19 | }, 20 | imgItem2_1: { 21 | 'ui:title': '图片下左', 22 | ...line2Item 23 | }, 24 | imgItem2_2: { 25 | 'ui:title': '图片下中', 26 | ...line2Item 27 | }, 28 | imgItem2_3: { 29 | 'ui:title': '图片下右', 30 | ...line2Item 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-iview3/types/vueUtils.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace vueUtils { 2 | 3 | /** nodePath 转css类名 */ 4 | function nodePath2ClassName(path: string): string; 5 | 6 | /** 是否为根节点 */ 7 | function isRootNodePath(path: string): boolean; 8 | 9 | /** 计算当前节点path */ 10 | function computedCurPath(prePath: string, curKey: string): string; 11 | 12 | /** 计算当前节点name */ 13 | function deletePathVal(vueData: object, name: string): void; 14 | 15 | /** 设置当前path值 */ 16 | function setPathVal(vueData: object, path: string, value: any): void; 17 | 18 | /** 设置当前path值 */ 19 | function getPathVal(vueData: object, path: string): object; 20 | 21 | /** 设置当前path值 */ 22 | function path2prop(path: string): string; 23 | } 24 | 25 | export default vueUtils; 26 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-ant/types/vueUtils.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace vueUtils { 2 | 3 | /** nodePath 转css类名 */ 4 | function nodePath2ClassName(path: string): string; 5 | 6 | /** 是否为根节点 */ 7 | function isRootNodePath(path: string): boolean; 8 | 9 | /** 计算当前节点path */ 10 | function computedCurPath(prePath: string, curKey: string): string; 11 | 12 | /** 计算当前节点name */ 13 | function deletePathVal(vueData: object, name: string): void; 14 | 15 | /** 设置当前path值 */ 16 | function setPathVal(vueData: object, path: string, value: any): void; 17 | 18 | /** 设置当前path值 */ 19 | function getPathVal(vueData: object, path: string): object; 20 | 21 | /** 设置当前path值 */ 22 | function path2prop(path: string): string; 23 | } 24 | 25 | export default vueUtils; 26 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-naive/types/vueUtils.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace vueUtils { 2 | 3 | /** nodePath 转css类名 */ 4 | function nodePath2ClassName(path: string): string; 5 | 6 | /** 是否为根节点 */ 7 | function isRootNodePath(path: string): boolean; 8 | 9 | /** 计算当前节点path */ 10 | function computedCurPath(prePath: string, curKey: string): string; 11 | 12 | /** 计算当前节点name */ 13 | function deletePathVal(vueData: object, name: string): void; 14 | 15 | /** 设置当前path值 */ 16 | function setPathVal(vueData: object, path: string, value: any): void; 17 | 18 | /** 设置当前path值 */ 19 | function getPathVal(vueData: object, path: string): object; 20 | 21 | /** 设置当前path值 */ 22 | function path2prop(path: string): string; 23 | } 24 | 25 | export default vueUtils; 26 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-element/types/vueUtils.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace vueUtils { 2 | 3 | /** nodePath 转css类名 */ 4 | function nodePath2ClassName(path: string): string; 5 | 6 | /** 是否为根节点 */ 7 | function isRootNodePath(path: string): boolean; 8 | 9 | /** 计算当前节点path */ 10 | function computedCurPath(prePath: string, curKey: string): string; 11 | 12 | /** 计算当前节点name */ 13 | function deletePathVal(vueData: object, name: string): void; 14 | 15 | /** 设置当前path值 */ 16 | function setPathVal(vueData: object, path: string, value: any): void; 17 | 18 | /** 设置当前path值 */ 19 | function getPathVal(vueData: object, path: string): object; 20 | 21 | /** 设置当前path值 */ 22 | function path2prop(path: string): string; 23 | } 24 | 25 | export default vueUtils; 26 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-element/types/vueUtils.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace vueUtils { 2 | 3 | /** nodePath 转css类名 */ 4 | function nodePath2ClassName(path: string): string; 5 | 6 | /** 是否为根节点 */ 7 | function isRootNodePath(path: string): boolean; 8 | 9 | /** 计算当前节点path */ 10 | function computedCurPath(prePath: string, curKey: string): string; 11 | 12 | /** 计算当前节点name */ 13 | function deletePathVal(vueData: object, name: string): void; 14 | 15 | /** 设置当前path值 */ 16 | function setPathVal(vueData: object, path: string, value: any): void; 17 | 18 | /** 设置当前path值 */ 19 | function getPathVal(vueData: object, path: string): object; 20 | 21 | /** 设置当前path值 */ 22 | function path2prop(path: string): string; 23 | } 24 | 25 | export default vueUtils; 26 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-naive/src/config/widgets/SelectWidget/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2021/2/23 10:21 下午. 3 | */ 4 | 5 | import { h } from 'vue'; 6 | import { modelValueComponent, resolveComponent } from '@lljj/vjsf-utils/vue3Utils'; 7 | 8 | const baseComponent = { 9 | name: 'SelectWidget', 10 | props: { 11 | enumOptions: { 12 | default: () => [], 13 | type: [Array] 14 | } 15 | }, 16 | setup(props, { attrs }) { 17 | return () => h(resolveComponent('n-select'), { 18 | options: props.enumOptions, 19 | ...attrs, 20 | }); 21 | } 22 | }; 23 | 24 | const moduleValeComponent = modelValueComponent(baseComponent, { 25 | model: 'value' 26 | }); 27 | 28 | export default moduleValeComponent; 29 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/CategoryGoods/uiSchema.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/7/25 15:47. 3 | */ 4 | 5 | import genImgItem from '../_commonConfig/ui/genImgItem'; 6 | 7 | export default { 8 | title: { 9 | 'ui:placeholder': '请输入标题' 10 | }, 11 | subTitle: { 12 | 'ui:placeholder': '请输入副标题' 13 | }, 14 | banner: { 15 | link: { 16 | ...genImgItem() 17 | }, 18 | bannerTitle: { 19 | 'ui:placeholder': '请输入banner标题' 20 | }, 21 | bannerSubTitle: { 22 | 'ui:placeholder': '请输入banner副标题' 23 | } 24 | }, 25 | goodsList: { 26 | 'ui:showIndexNumber': true, 27 | items: { 28 | ...genImgItem() 29 | } 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-naive/types/index.d.ts: -------------------------------------------------------------------------------- 1 | import JsonSchemaForm from './vueForm'; 2 | import getDefaultFormState from './getDefaultFormState'; 3 | import modelValueComponent from './modelValueComponent'; 4 | import fieldProps from './fieldProps'; 5 | import vueUtils from './vueUtils'; 6 | import formUtils from './formUtils'; 7 | import schemaValidate from './schemaValidate'; 8 | import i18n from './i18n'; 9 | import globalOptions from './globalOptions'; 10 | 11 | type JsonSchemaFormAntdV4 = JsonSchemaForm 12 | 13 | export default JsonSchemaForm; 14 | 15 | export { 16 | JsonSchemaFormAntdV4, 17 | globalOptions, 18 | getDefaultFormState, 19 | fieldProps, 20 | vueUtils, 21 | formUtils, 22 | schemaValidate, 23 | i18n, 24 | modelValueComponent 25 | }; 26 | 27 | export class SchemaField {} 28 | -------------------------------------------------------------------------------- /packages/demo/demo-common/components/ElementPlus/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/11/20 9:43. 3 | */ 4 | 5 | // import './theme/index.css'; 6 | import ElementPlus, { 7 | ElLoading, 8 | ElMessageBox, 9 | ElMessage 10 | } from 'ElementPlus'; 11 | 12 | console.log(ElementPlus); 13 | export default { 14 | install(app) { 15 | app.use(ElementPlus); 16 | 17 | // 原型方法 18 | app.config.globalProperties.$loading = ElLoading.service; 19 | app.config.globalProperties.$alert = ElMessageBox.alert; 20 | app.config.globalProperties.$confirm = ElMessageBox.confirm; 21 | app.config.globalProperties.$prompt = ElMessageBox.prompt; 22 | app.config.globalProperties.$msgbox = ElMessageBox; 23 | app.config.globalProperties.$message = ElMessage; 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /packages/demo/demo-v3/src/pages/index/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/5/13 15:52. 3 | */ 4 | 5 | import 'demo-common/bootstrap.js'; 6 | import { createApp } from 'vue'; 7 | import { createRouter, createWebHashHistory } from 'VueRouter'; 8 | import ElementPlus from 'demo-common/components/ElementPlus/index.js'; 9 | 10 | import routes from './routes'; 11 | 12 | import App from './App'; 13 | 14 | import './style.css'; 15 | 16 | // create router 17 | const router = createRouter({ 18 | history: createWebHashHistory(), 19 | routes, 20 | }); 21 | 22 | // create app 23 | const app = createApp(App); 24 | 25 | // use router 26 | app.use(router); 27 | 28 | // use ui lib 29 | app.use(ElementPlus); 30 | 31 | // mount 32 | app.mount('#app'); 33 | 34 | app.config.unwrapInjectedRef = true; 35 | 36 | window.app1 = app; 37 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/Text/View.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 24 | 25 | 36 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponentsM/Text/View.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 24 | 25 | 36 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/schema-generator/schema-generator.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | JSON Schema 生成器 | Vue Json schema form 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/vue-editor.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vue Editor 活动编辑器 | Vue Json schema form 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /packages/lib/utils/README.md: -------------------------------------------------------------------------------- 1 | # @lljj/vjsf-utils 2 | 表单基础通用工具类,具体的参数可参见源码 3 | 4 | ## @lljj/vjsf-utils/i18n 5 | 管理当前多语言 6 | 7 | 8 | ## @lljj/vjsf-utils/schema/getDefaultFormState 9 | 根据 jsonSchema 和 formData,计算当前schema value 10 | 11 | ## @lljj/vjsf-utils/schema/validate 12 | 13 | ```js 14 | import { 15 | ajvValidateFormData, 16 | validateFormDataAndTransformMsg, 17 | isValid 18 | } from '@lljj/vjsf-utils/schema/validate'; 19 | 20 | // 直接调用 ajv 验证schema,返回格式化后的结果 21 | ajvValidateFormData(...args); 22 | 23 | // 校验数据并处理多语言(只处理当前节点) 24 | validateFormDataAndTransformMsg(...args); 25 | 26 | // 返回数据是否校验成功 27 | isValid(...args); 28 | 29 | // 返回数据是否校验成功 30 | isValid(...args); 31 | ``` 32 | 33 | ## @lljj/vjsf-utils/arrayUtils 34 | 数组相关的工具类 35 | 36 | ## @lljj/vjsf-utils/formUtils 37 | 表单相关的工具类 38 | 39 | ## @lljj/vjsf-utils/vueUtils 40 | Vue相关的工具类 41 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-iview3/src/config/widgets/SwitchWidget/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2021/1/2 10:53 下午. 3 | */ 4 | 5 | export default { 6 | name: 'SwitchWidget', 7 | functional: true, 8 | render(h, context) { 9 | const { activeText, inactiveText } = context.props; 10 | 11 | // 转换elementUi activeText inactiveText 支持 iview slot 12 | const childNode = Object.entries({ 13 | open: activeText, 14 | close: inactiveText, 15 | }).reduce((preVal, [slot, value]) => { 16 | if (value !== undefined) { 17 | preVal.push(h('span', { 18 | slot 19 | }, [value])); 20 | } 21 | 22 | return preVal; 23 | }, []); 24 | 25 | return h('i-switch', context.data, childNode); 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /packages/lib/utils/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@lljj/vjsf-utils", 3 | "version": "1.19.0", 4 | "description": "vue json schema form 使用的基础utils工具类", 5 | "private": false, 6 | "publishConfig": { 7 | "access": "public" 8 | }, 9 | "keywords": [ 10 | "@lljj/vjsf-utils", 11 | "vue", 12 | "vuejs", 13 | "form", 14 | "jsonSchema" 15 | ], 16 | "dependencies": { 17 | "ajv": "^6.10.2" 18 | }, 19 | "repository": "https://github.com/lljj-x/vue-json-schema-form", 20 | "homepage": "https://github.com/lljj-x/vue-json-schema-form", 21 | "license": "Apache-2.0", 22 | "author": "Liu.Jun", 23 | "browserslist": [ 24 | "> 1%", 25 | "last 2 versions", 26 | "not ie <= 8" 27 | ], 28 | "gitHead": "92795075169c879e1c1fabfe26f1d3c10b861060" 29 | } 30 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-ant/scripts/config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/6/2 16:00. 3 | */ 4 | 5 | const path = require('path'); 6 | 7 | const resolve = p => path.resolve(__dirname, '../', p); 8 | 9 | const packageData = require('../package.json'); 10 | 11 | // eslint-disable-next-line max-len 12 | const banner = `/** @license ${packageData.name} (c) 2020-${new Date().getFullYear()} ${packageData.author} License: ${packageData.license} */`; 13 | 14 | module.exports = { 15 | entry: resolve('src/index.js'), 16 | banner, 17 | external: ['vue'], 18 | globals: { 19 | vue: 'Vue' 20 | }, 21 | extractcss: false, 22 | output: { 23 | path: resolve('dist/'), 24 | file: 'vue3-form-ant', // 导出文件名,自动拼接 format 25 | name: 'vue3FormAnt', // umd 注册的全局变量名称 26 | format: ['esm', 'umd'] 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-naive/scripts/config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/6/2 16:00. 3 | */ 4 | 5 | const path = require('path'); 6 | 7 | const resolve = p => path.resolve(__dirname, '../', p); 8 | 9 | const packageData = require('../package.json'); 10 | 11 | // eslint-disable-next-line max-len 12 | const banner = `/** @license ${packageData.name} (c) 2020-${new Date().getFullYear()} ${packageData.author} License: ${packageData.license} */`; 13 | 14 | module.exports = { 15 | entry: resolve('src/index.js'), 16 | banner, 17 | external: ['vue'], 18 | globals: { 19 | vue: 'Vue' 20 | }, 21 | extractcss: false, 22 | output: { 23 | path: resolve('dist/'), 24 | file: 'vue3-form-naive', // 导出文件名,自动拼接 format 25 | name: 'vue3FormNaive', // umd 注册的全局变量名称 26 | format: ['esm', 'umd'] 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-naive/src/config/widgets/TimePickerWidget/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2021/2/23 10:21 下午. 3 | */ 4 | 5 | import { h } from 'vue'; 6 | import { resolveComponent } from '@lljj/vjsf-utils/vue3Utils'; 7 | 8 | const baseComponent = { 9 | name: 'TimePickerWidget', 10 | inheritAttrs: false, 11 | setup(props, { attrs }) { 12 | return () => { 13 | const { 14 | modelValue, 'onUpdate:modelValue': onUpdateFormattedValue, ...otherAttrs 15 | } = attrs; 16 | 17 | return h(resolveComponent('n-time-picker'), { 18 | ...otherAttrs, 19 | valueFormat: 'HH:mm:ss', 20 | formattedValue: modelValue, 21 | onUpdateFormattedValue, 22 | }); 23 | }; 24 | } 25 | }; 26 | 27 | export default baseComponent; 28 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/MultipleImg2_3/uiSchema.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/4/30 17:13. 3 | */ 4 | 5 | import genImgItem from '../_commonConfig/ui/genImgItem'; 6 | 7 | const line2Item = genImgItem({ 8 | width: 383, 9 | height: 500, 10 | }); 11 | 12 | export default { 13 | imgItem1_1: { 14 | 'ui:title': '图片上左', 15 | ...genImgItem({ 16 | width: 786, 17 | height: 420, 18 | }) 19 | }, 20 | imgItem1_2: { 21 | 'ui:title': '图片上右', 22 | ...line2Item 23 | }, 24 | imgItem2_1: { 25 | 'ui:title': '图片下左', 26 | ...line2Item 27 | }, 28 | imgItem2_2: { 29 | 'ui:title': '图片下中', 30 | ...line2Item 31 | }, 32 | imgItem2_3: { 33 | 'ui:title': '图片下右', 34 | ...line2Item 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /packages/lib/postcss.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable global-require */ 2 | // https://github.com/michael-ciniawsky/postcss-load-config 3 | 4 | // const path = require('path'); 5 | 6 | module.exports = { 7 | plugins: [ 8 | require('postcss-import')({ 9 | path: ['src/common/css/'], 10 | }), 11 | require('postcss-mixins'), 12 | require('postcss-nested'), 13 | require('postcss-color-mod-function'), 14 | require('postcss-cssnext')({ 15 | warnForDuplicates: false, 16 | }), 17 | require('cssnano')({ 18 | sourcemap: false, 19 | autoprefixer: false, 20 | safe: true, 21 | discardComments: { 22 | removeAll: true, 23 | }, 24 | discardUnused: false, 25 | zindex: false, 26 | }), 27 | ] 28 | }; 29 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-iview3/scripts/config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/6/2 16:00. 3 | */ 4 | 5 | const path = require('path'); 6 | 7 | const resolve = p => path.resolve(__dirname, '../', p); 8 | 9 | const packageData = require('../package.json'); 10 | 11 | // eslint-disable-next-line max-len 12 | const banner = `/** @license ${packageData.name} (c) 2020-${new Date().getFullYear()} ${packageData.author} License: ${packageData.license} */`; 13 | 14 | module.exports = { 15 | entry: resolve('src/index.js'), 16 | banner, 17 | external: ['vue'], 18 | globals: { 19 | vue: 'Vue' 20 | }, 21 | extractcss: false, 22 | output: { 23 | path: resolve('dist/'), 24 | file: 'vue2-form-iview3', // 导出文件名,自动拼接 format 25 | name: 'vue2FormIview3', // umd 注册的全局变量名称 26 | format: ['esm', 'umd'] 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-element/scripts/config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/6/2 16:00. 3 | */ 4 | 5 | const path = require('path'); 6 | 7 | const resolve = p => path.resolve(__dirname, '../', p); 8 | 9 | const packageData = require('../package.json'); 10 | 11 | // eslint-disable-next-line max-len 12 | const banner = `/** @license ${packageData.name} (c) 2020-${new Date().getFullYear()} ${packageData.author} License: ${packageData.license} */`; 13 | 14 | module.exports = { 15 | entry: resolve('src/index.js'), 16 | banner, 17 | external: ['vue'], 18 | globals: { 19 | vue: 'Vue' 20 | }, 21 | extractcss: false, 22 | output: { 23 | path: resolve('dist/'), 24 | file: 'vueJsonSchemaForm', // 导出文件名,自动拼接 format 25 | name: 'vueJsonSchemaForm', // umd 注册的全局变量名称 26 | format: ['esm', 'umd'] 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-element/scripts/config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/6/2 16:00. 3 | */ 4 | 5 | const path = require('path'); 6 | 7 | const resolve = p => path.resolve(__dirname, '../', p); 8 | 9 | const packageData = require('../package.json'); 10 | 11 | // eslint-disable-next-line max-len 12 | const banner = `/** @license ${packageData.name} (c) 2020-${new Date().getFullYear()} ${packageData.author} License: ${packageData.license} */`; 13 | 14 | module.exports = { 15 | entry: resolve('src/index.js'), 16 | banner, 17 | external: ['vue'], 18 | globals: { 19 | vue: 'Vue' 20 | }, 21 | extractcss: false, 22 | output: { 23 | path: resolve('dist/'), 24 | file: 'vue3-form-element', // 导出文件名,自动拼接 format 25 | name: 'vue3FormElement', // umd 注册的全局变量名称 26 | format: ['esm', 'umd'] 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /packages/lib/utils/icons/IconQuestion.vue: -------------------------------------------------------------------------------- 1 | 17 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-ant/scripts/build.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/6/2 15:58. 3 | */ 4 | 5 | const rollup = require('rollup'); 6 | 7 | const baseConfig = require('./base.config'); 8 | 9 | const buildConfig = baseConfig({ 10 | sourcemap: false, 11 | uglify: true 12 | }); 13 | 14 | // see below for details on the options 15 | const { output: outputList, ...inputOptions } = buildConfig; 16 | 17 | async function build() { 18 | // create a bundle 19 | const bundle = await rollup.rollup(inputOptions); 20 | 21 | // 循环输出每种格式 22 | for (const outputOptions of outputList) { 23 | // or write the bundle to disk 24 | // eslint-disable-next-line no-await-in-loop 25 | // 并发 26 | bundle.write(outputOptions).then(() => { 27 | console.log(`Success: ${outputOptions.file}`); 28 | }); 29 | } 30 | } 31 | 32 | build(); 33 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-element/scripts/build.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/6/2 15:58. 3 | */ 4 | 5 | const rollup = require('rollup'); 6 | 7 | const baseConfig = require('./base.config'); 8 | 9 | const buildConfig = baseConfig({ 10 | sourcemap: false, 11 | uglify: true 12 | }); 13 | 14 | // see below for details on the options 15 | const { output: outputList, ...inputOptions } = buildConfig; 16 | 17 | async function build() { 18 | // create a bundle 19 | const bundle = await rollup.rollup(inputOptions); 20 | 21 | // 循环输出每种格式 22 | for (const outputOptions of outputList) { 23 | // or write the bundle to disk 24 | // eslint-disable-next-line no-await-in-loop 25 | // 并发 26 | bundle.write(outputOptions).then(() => { 27 | console.log(`Success: ${outputOptions.file}`); 28 | }); 29 | } 30 | } 31 | 32 | build(); 33 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-element/scripts/build.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/6/2 15:58. 3 | */ 4 | 5 | const rollup = require('rollup'); 6 | 7 | const baseConfig = require('./base.config'); 8 | 9 | const buildConfig = baseConfig({ 10 | sourcemap: false, 11 | uglify: true 12 | }); 13 | 14 | // see below for details on the options 15 | const { output: outputList, ...inputOptions } = buildConfig; 16 | 17 | async function build() { 18 | // create a bundle 19 | const bundle = await rollup.rollup(inputOptions); 20 | 21 | // 循环输出每种格式 22 | for (const outputOptions of outputList) { 23 | // or write the bundle to disk 24 | // eslint-disable-next-line no-await-in-loop 25 | // 并发 26 | bundle.write(outputOptions).then(() => { 27 | console.log(`Success: ${outputOptions.file}`); 28 | }); 29 | } 30 | } 31 | 32 | build(); 33 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-naive/scripts/build.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/6/2 15:58. 3 | */ 4 | 5 | const rollup = require('rollup'); 6 | 7 | const baseConfig = require('./base.config'); 8 | 9 | const buildConfig = baseConfig({ 10 | sourcemap: false, 11 | uglify: true 12 | }); 13 | 14 | // see below for details on the options 15 | const { output: outputList, ...inputOptions } = buildConfig; 16 | 17 | async function build() { 18 | // create a bundle 19 | const bundle = await rollup.rollup(inputOptions); 20 | 21 | // 循环输出每种格式 22 | for (const outputOptions of outputList) { 23 | // or write the bundle to disk 24 | // eslint-disable-next-line no-await-in-loop 25 | // 并发 26 | bundle.write(outputOptions).then(() => { 27 | console.log(`Success: ${outputOptions.file}`); 28 | }); 29 | } 30 | } 31 | 32 | build(); 33 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-core/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@lljj/vue2-form-core", 3 | "version": "1.19.0", 4 | "description": "基于 Vue 、JsonSchema快速构建一个带完整校验的form表单,vue2版本基础框架", 5 | "main": "src/index.js", 6 | "module": "src/index.js", 7 | "keywords": [ 8 | "vue", 9 | "vuejs", 10 | "form", 11 | "jsonSchema" 12 | ], 13 | "publishConfig": { 14 | "access": "public" 15 | }, 16 | "dependencies": { 17 | "@lljj/vjsf-utils": "1.19.0" 18 | }, 19 | "repository": "https://github.com/lljj-x/vue-json-schema-form", 20 | "homepage": "https://github.com/lljj-x/vue-json-schema-form", 21 | "license": "Apache-2.0", 22 | "author": "Liu.Jun", 23 | "browserslist": [ 24 | "> 1%", 25 | "last 2 versions", 26 | "not ie <= 8" 27 | ], 28 | "gitHead": "92795075169c879e1c1fabfe26f1d3c10b861060" 29 | } 30 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-iview3/src/config/widgets/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/5/17 10:41 下午. 3 | */ 4 | 5 | import CheckboxesWidget from './CheckboxesWidget'; 6 | import RadioWidget from './RadioWidget'; 7 | import SelectWidget from './SelectWidget'; 8 | import DatePickerWidget from './DatePickerWidget'; 9 | import DateTimePickerWidget from './DateTimePickerWidget'; 10 | import TimePickerWidget from './TimePickerWidget'; 11 | import UploadWidget from './UploadWidget'; 12 | import SwitchWidget from './SwitchWidget'; 13 | import InputNumberWidget from './InputNumberWidget'; 14 | 15 | const widgetComponents = { 16 | CheckboxesWidget, 17 | RadioWidget, 18 | SelectWidget, 19 | TimePickerWidget, 20 | DatePickerWidget, 21 | DateTimePickerWidget, 22 | UploadWidget, 23 | SwitchWidget, 24 | InputNumberWidget 25 | }; 26 | 27 | export default widgetComponents; 28 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-core/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@lljj/vue3-form-core", 3 | "version": "1.19.0", 4 | "description": "基于 Vue3 、JsonSchema快速构建一个带完整校验的form表单,vue3版本基础框架", 5 | "main": "src/index.js", 6 | "module": "src/index.js", 7 | "keywords": [ 8 | "vue", 9 | "vuejs", 10 | "form", 11 | "jsonSchema" 12 | ], 13 | "publishConfig": { 14 | "access": "public" 15 | }, 16 | "dependencies": { 17 | "@lljj/vjsf-utils": "1.19.0" 18 | }, 19 | "repository": "https://github.com/lljj-x/vue-json-schema-form", 20 | "homepage": "https://github.com/lljj-x/vue-json-schema-form", 21 | "license": "Apache-2.0", 22 | "author": "Liu.Jun", 23 | "browserslist": [ 24 | "> 1%", 25 | "last 2 versions", 26 | "not ie <= 8" 27 | ], 28 | "gitHead": "92795075169c879e1c1fabfe26f1d3c10b861060" 29 | } 30 | -------------------------------------------------------------------------------- /packages/demo/demo-common/schemaTypes/25.hidden(隐藏表单项)/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/7/22 11:07 下午. 3 | */ 4 | 5 | export default { 6 | schema: { 7 | title: '隐藏表单项', 8 | type: 'object', 9 | description: ` 10 | 隐藏表单项可以使用多种配置方案,可以结合实际需要 11 |
1. ui:widget: "hidden" 12 |
2. ui:widget: "HiddenWidget" 13 |
3. ui:hidden: true 14 | `, 15 | properties: { 16 | hidden2: { 17 | title: 'hidden2', 18 | type: 'string', 19 | 'ui:widget': 'HiddenWidget', 20 | default: 'hidden2' 21 | }, 22 | hidden3: { 23 | title: 'hidden1', 24 | type: 'string', 25 | 'ui:hidden': true, 26 | default: 'hidden3' 27 | } 28 | } 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /packages/demo/demo-common/utils/url.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/11/11 22:24. 3 | */ 4 | 5 | export function openNewPage(url, target = '_blank') { 6 | const a = document.createElement('a'); 7 | a.style.display = 'none'; 8 | a.target = target; 9 | a.href = url; 10 | document.body.appendChild(a); 11 | a.click(); 12 | document.body.removeChild(a); 13 | } 14 | 15 | // 解析当前url的query 参数 16 | export function getUrlQuery(href) { 17 | const url = String(href === undefined ? window.location.href : href).replace(/#.*$/, ''); 18 | const search = url.substring(url.lastIndexOf('?') + 1); 19 | const obj = {}; 20 | const reg = /([^?&=]+)=([^?&=]*)/g; 21 | search.replace(reg, (rs, $1, $2) => { 22 | const name = decodeURIComponent($1); 23 | const query = String(decodeURIComponent($2)); 24 | obj[name] = query; 25 | return rs; 26 | }); 27 | return obj; 28 | } 29 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-iview3/scripts/build.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/6/2 15:58. 3 | */ 4 | 5 | const rollup = require('rollup'); 6 | 7 | const baseConfig = require('./base.config'); 8 | 9 | const buildConfig = baseConfig({ 10 | sourcemap: false, 11 | uglify: true 12 | }); 13 | 14 | // see below for details on the options 15 | const { output: outputList, ...inputOptions } = buildConfig; 16 | 17 | async function build() { 18 | // create a bundle 19 | const bundle = await rollup.rollup(inputOptions); 20 | 21 | // 循环输出每种格式 22 | for (const outputOptions of outputList) { 23 | // or write the bundle to disk 24 | // eslint-disable-next-line no-await-in-loop 25 | // 并发 26 | bundle.write(outputOptions).then(() => { 27 | console.log(`Success: ${outputOptions.file}`); 28 | }); 29 | } 30 | } 31 | 32 | build().catch((error) => { 33 | debugger; 34 | }); 35 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/schema-generator/views/editor/viewComponents/SelectBoolean/elCheckbox.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/12/10 15:16. 3 | */ 4 | 5 | 6 | import genSchema from '../genSchema.js'; 7 | 8 | const viewSchema = { 9 | title: '是否选择(Checkbox)', 10 | type: 'boolean', 11 | 'ui:widget': 'el-checkbox' 12 | }; 13 | 14 | export default { 15 | viewSchema, 16 | propsSchema: genSchema({ 17 | options: { 18 | type: 'object', 19 | title: '选项', 20 | properties: { 21 | uiOptions: { 22 | type: 'object', 23 | properties: { 24 | label: { 25 | title: '标签文案', 26 | type: 'string', 27 | default: '是否' 28 | } 29 | } 30 | } 31 | } 32 | } 33 | }) 34 | }; 35 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/schema-generator/views/editor/viewComponents/Date/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/10/30 17:11. 3 | */ 4 | 5 | import genSchema from '../genSchema.js'; 6 | 7 | const viewSchema = { 8 | title: 'Date(时间戳)', 9 | type: 'number', 10 | format: 'date' 11 | }; 12 | 13 | export default { 14 | viewSchema, 15 | propsSchema: genSchema({ 16 | options: { 17 | type: 'object', 18 | title: '选项', 19 | required: [], 20 | properties: { 21 | uiOptions: { 22 | type: 'object', 23 | properties: { 24 | placeholder: { 25 | type: 'string', 26 | title: '输入占位文本', 27 | default: '请选择日期' 28 | } 29 | } 30 | } 31 | } 32 | } 33 | }) 34 | }; 35 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/schema-generator/views/editor/viewComponents/Time/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/10/30 16:25. 3 | */ 4 | 5 | import genSchema from '../genSchema.js'; 6 | 7 | const viewSchema = { 8 | title: 'Time(字符串)', 9 | type: 'string', 10 | format: 'time' 11 | }; 12 | 13 | export default { 14 | viewSchema, 15 | propsSchema: genSchema({ 16 | options: { 17 | type: 'object', 18 | title: '选项', 19 | required: [], 20 | properties: { 21 | uiOptions: { 22 | type: 'object', 23 | properties: { 24 | placeholder: { 25 | type: 'string', 26 | title: '输入占位文本', 27 | default: '请选择时间' 28 | } 29 | } 30 | } 31 | } 32 | } 33 | }) 34 | }; 35 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/schema-generator/views/editor/viewComponents/DateTime/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/10/30 17:10. 3 | */ 4 | 5 | import genSchema from '../genSchema.js'; 6 | 7 | const viewSchema = { 8 | title: 'DateTime(时间戳)', 9 | type: 'number', 10 | format: 'date-time' 11 | }; 12 | 13 | export default { 14 | viewSchema, 15 | propsSchema: genSchema({ 16 | options: { 17 | type: 'object', 18 | title: '选项', 19 | required: [], 20 | properties: { 21 | uiOptions: { 22 | type: 'object', 23 | properties: { 24 | placeholder: { 25 | type: 'string', 26 | title: '输入占位文本', 27 | default: '请选择日期时间' 28 | } 29 | } 30 | } 31 | } 32 | } 33 | }) 34 | }; 35 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/schema-generator/views/editor/common/utils.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2019/11/28 18:37. 3 | */ 4 | 5 | // import { genId } from 'demo-common/utils/id'; 6 | 7 | export function isObject(obj) { 8 | return (Object.prototype.toString.call(obj) === '[object Object]'); 9 | } 10 | 11 | export function isEmptyObject(obj) { 12 | for (const key in obj) { 13 | if (Object.prototype.hasOwnProperty.call(obj, key)) { 14 | return false; 15 | } 16 | } 17 | return true; 18 | } 19 | 20 | export function deepFreeze(obj) { 21 | // 取回定义在obj上的属性名 22 | const propNames = Object.getOwnPropertyNames(obj); 23 | 24 | // 在冻结自身之前冻结属性 25 | propNames.forEach((name) => { 26 | const prop = obj[name]; 27 | 28 | // 如果prop是个对象,冻结它 29 | if (typeof prop === 'object' && prop !== null) deepFreeze(prop); 30 | }); 31 | 32 | // 冻结自身(no-op if already frozen) 33 | return Object.freeze(obj); 34 | } 35 | -------------------------------------------------------------------------------- /packages/lib/utils/vueUtils.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/4/25 14:45. 3 | */ 4 | 5 | import Vue from 'vue'; 6 | 7 | import { 8 | nodePath2ClassName, isRootNodePath, computedCurPath, getPathVal, path2prop, pathSeparator 9 | } from './vueCommonUtils'; 10 | 11 | // 删除当前path值 12 | export function deletePathVal(vueData, name) { 13 | Vue.delete(vueData, name); 14 | } 15 | 16 | // 设置当前path值 17 | export function setPathVal(obj, path, value) { 18 | // Vue.set ? 19 | const pathArr = path.split(pathSeparator); 20 | for (let i = 0; i < pathArr.length; i += 1) { 21 | if (pathArr.length - i < 2) { 22 | // 倒数第一个数据 23 | // obj[pathArr[pathArr.length - 1]] = value; 24 | Vue.set(obj, pathArr[pathArr.length - 1], value); 25 | break; 26 | } 27 | obj = obj[pathArr[i]]; 28 | } 29 | } 30 | 31 | export { 32 | nodePath2ClassName, isRootNodePath, computedCurPath, getPathVal, path2prop, pathSeparator 33 | }; 34 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-element/src/config/widgets/DatePickerWidget/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/7/22 13:21. 3 | */ 4 | 5 | export default { 6 | name: 'DatePickerWidget', 7 | functional: true, 8 | render(h, context) { 9 | const { isNumberValue, isRange, ...otherProps } = context.data.attrs || {}; 10 | 11 | context.data.attrs = { 12 | type: isRange ? 'daterange' : 'date', 13 | 'value-format': isNumberValue ? 'timestamp' : 'yyyy-MM-dd', 14 | ...otherProps 15 | }; 16 | 17 | const oldInputCall = context.data.on.input; 18 | context.data.on = { 19 | ...context.data.on, 20 | input(val) { 21 | const trueVal = val === null ? (isRange ? [] : undefined) : val; 22 | oldInputCall.apply(context.data.on, [trueVal]); 23 | } 24 | }; 25 | 26 | return h('el-date-picker', context.data, context.children); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/Coupon/component/View.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 23 | 24 | 39 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/Text/uiSchema.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/7/25 11:25. 3 | */ 4 | 5 | export default { 6 | txt: { 7 | 'ui:options': { 8 | renderScopedSlots(h) { 9 | return { 10 | append: () => h('span', '.com') 11 | }; 12 | }, 13 | widgetListeners: { 14 | input(event) { 15 | console.log('ui input', event); 16 | } 17 | }, 18 | renderChildren(h) { 19 | return [ 20 | h('span', { 21 | slot: 'suffix', 22 | }, '后缀') 23 | ]; 24 | }, 25 | getWidget(widgetVm) { 26 | console.log(widgetVm); 27 | }, 28 | onChange(data) { 29 | console.log('change:', data); 30 | } 31 | } 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/scripts/envConfig.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2018/5/31. 3 | */ 4 | 5 | // envConfig 分为两部分参数 1、根据入口文件携带的固定参数 2、根具 npm_config 获取参数可以覆盖1的参数 6 | // 不同入口文件需要自己调用 initConfig 7 | 8 | const argv = require('yargs').argv; 9 | 10 | const manifestAlias = { 11 | lgb: 'log', 12 | dgb: 'dir', 13 | rgb: 'report', 14 | }; 15 | 16 | exports.getConfig = () => { 17 | try { 18 | return JSON.parse(process.env.npm_config_argv).original.slice(2).reduce((preVal, item) => { 19 | const param = item.replace(/^--/, ''); 20 | const [key, value] = param.split('='); 21 | preVal[key] = value || !0; 22 | 23 | // 别名 24 | if (manifestAlias[key]) { 25 | preVal[manifestAlias[key]] = preVal[key]; 26 | } 27 | return preVal; 28 | }, argv); 29 | } catch (e) { 30 | // 31 | console.warn('JSON parse "process.env.npm_config_argv" fail !'); 32 | } 33 | return {}; 34 | }; 35 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-ant/src/config/widgets/DatePickerWidget/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2021/2/23 10:21 下午. 3 | */ 4 | 5 | import { h } from 'vue'; 6 | import { resolveComponent } from '@lljj/vjsf-utils/vue3Utils'; 7 | import { modelValueComponent, numberTimeComponent } from '../../utils'; 8 | 9 | const baseComponent = { 10 | name: 'DatePickerWidget', 11 | inheritAttrs: false, 12 | setup(props, { attrs }) { 13 | return () => { 14 | const { isNumberValue, isRange, ...otherAttrs } = attrs; 15 | return h(resolveComponent(isRange ? 'a-range-picker' : 'a-date-picker'), { 16 | valueFormat: isNumberValue ? 'x' : 'YYYY-MM-DD', 17 | ...otherAttrs 18 | }); 19 | }; 20 | } 21 | }; 22 | 23 | const timeNumberComponent = numberTimeComponent(baseComponent); 24 | 25 | const moduleValeComponent = modelValueComponent(timeNumberComponent, { 26 | model: 'value' 27 | }); 28 | 29 | export default moduleValeComponent; 30 | -------------------------------------------------------------------------------- /packages/docs/docs/zh/guide/todo.md: -------------------------------------------------------------------------------- 1 | # TODO 2 | 3 | ## 不支持 (持续更新) 4 | 目前对标准JSON Schema不支持的部分包含可能不限于如下: 5 | 1. object additionalProperties 属性只支持配置false(暂不计划) 6 | 1. object Dependencies schema依赖不支持(暂不计划) 7 | 1. if else 新特性不支持(暂不计划) 8 | 1. $ref 不支持跨文件调用(暂不计划) 9 | 10 | ## Todo 11 | - [x] anyOf 嵌套数组调整顺序的时候数据渲染异常问题修复 12 | - [x] lib如果直接umd包导入,默认注册vue组件 类elementUi 13 | - [x] 配置化所有调用外部组件的地方,方便后续扩展支持不同的ui库 14 | - [x] enumNames 支持 ui-schema 配置 15 | - [x] 对表单所有渲染节点打上唯一class类名,方便重置样式 16 | - [x] 整理文档,逐步梳理 基本使用方法和个性化配置field、组件、错误信息处理、options配置等 17 | - [x] 添加 ui:fieldProps 传递给自定义field的参数 18 | - [x] 添加 d.ts 文件 19 | - [x] ui:widget 支持在array级别传入 20 | - [x] custom-rule 参数 支持 21 | - [x] 逐步开源发布 22 | - [x] 优化源码 不需要this的组件调整为 functional 23 | - [x] 数组支持配置是否显示序号 24 | - [x] 数组渲染样式微调优化(控制条下间距等) 25 | - [x] 支持属性依赖 [属性依赖](https://json-schema.org/understanding-json-schema/reference/object.html#property-dependencies) 26 | - [x] 支持 ui:hidden 使用 mustache 表达式 27 | - [x] 支持 所有ui配置使用 mustache 表达式 28 | - [x] 支持Vue3 29 | - [x] 适配elementUi、iView、Ant vue 等常用ui组件 30 | - [ ] 添加代码测试 31 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-element/src/config/widgets/WIDGET_MAP.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/4/21 18:23. 3 | */ 4 | 5 | // widget 组件对应elementUi 配置表 6 | 7 | import widgetComponents from './index'; 8 | 9 | const { 10 | CheckboxesWidget, 11 | RadioWidget, 12 | SelectWidget, 13 | TimePickerWidget, 14 | DatePickerWidget, 15 | DateTimePickerWidget 16 | } = widgetComponents; 17 | 18 | export default { 19 | types: { 20 | boolean: 'el-switch', 21 | string: 'el-input', 22 | number: 'el-input-number', 23 | integer: 'el-input-number', 24 | }, 25 | formats: { 26 | color: 'el-color-picker', 27 | time: TimePickerWidget, // 20:20:39+00:00 28 | date: DatePickerWidget, // 2018-11-13 29 | 'date-time': DateTimePickerWidget, // 2018-11-13T20:20:39+00:00 30 | }, 31 | common: { 32 | select: SelectWidget, 33 | radioGroup: RadioWidget, 34 | checkboxGroup: CheckboxesWidget, 35 | }, 36 | widgetComponents 37 | }; 38 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-element/src/config/widgets/WIDGET_MAP.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/4/21 18:23. 3 | */ 4 | 5 | // widget 组件对应elementUi 配置表 6 | 7 | import widgetComponents from './index'; 8 | 9 | const { 10 | CheckboxesWidget, 11 | RadioWidget, 12 | SelectWidget, 13 | TimePickerWidget, 14 | DatePickerWidget, 15 | DateTimePickerWidget 16 | } = widgetComponents; 17 | 18 | export default { 19 | types: { 20 | boolean: 'el-switch', 21 | string: 'el-input', 22 | number: 'el-input-number', 23 | integer: 'el-input-number', 24 | }, 25 | formats: { 26 | color: 'el-color-picker', 27 | time: TimePickerWidget, // 20:20:39+00:00 28 | date: DatePickerWidget, // 2018-11-13 29 | 'date-time': DateTimePickerWidget, // 2018-11-13T20:20:39+00:00 30 | }, 31 | common: { 32 | select: SelectWidget, 33 | radioGroup: RadioWidget, 34 | checkboxGroup: CheckboxesWidget, 35 | }, 36 | widgetComponents 37 | }; 38 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-naive/src/style.css: -------------------------------------------------------------------------------- 1 | /* element plus 重置样式*/ 2 | .genFromComponent { 3 | .n-form-item-blank { 4 | flex-wrap: wrap; 5 | } 6 | 7 | /*如果引起问题可以覆盖*/ 8 | .n-form-item.n-form-item--top-labelled { 9 | grid-template-rows: none; 10 | } 11 | 12 | .formFooter_item { 13 | .n-form-item-blank { 14 | justify-content: flex-end; 15 | } 16 | } 17 | 18 | .n-form-item-feedback--error { 19 | .n-form-item-feedback__line { 20 | display: -webkit-box!important; 21 | text-overflow: ellipsis; 22 | overflow: hidden; 23 | -webkit-box-orient: vertical; 24 | -webkit-line-clamp: 2; 25 | white-space: normal; 26 | text-align: left; 27 | line-height: 1.2; 28 | font-size: 12px; 29 | } 30 | } 31 | .validateWidget { 32 | .n-form-item-blank, .n-form-item-feedback-wrapper{ 33 | min-height: auto; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/schema-generator/views/editor/components/ImportSchemaView.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 35 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/schema-generator/views/editor/viewComponents/SelectBoolean/elSwitch.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/12/10 15:15. 3 | */ 4 | 5 | import genSchema from '../genSchema.js'; 6 | 7 | const viewSchema = { 8 | title: '是否选择(Switch)', 9 | type: 'boolean' 10 | }; 11 | 12 | export default { 13 | viewSchema, 14 | propsSchema: genSchema({ 15 | options: { 16 | type: 'object', 17 | title: '选项', 18 | properties: { 19 | uiOptions: { 20 | type: 'object', 21 | properties: { 22 | activeText: { 23 | title: '选择文案', 24 | type: 'string' 25 | }, 26 | inactiveText: { 27 | title: '非选择文案', 28 | type: 'string' 29 | } 30 | } 31 | } 32 | } 33 | } 34 | }) 35 | }; 36 | -------------------------------------------------------------------------------- /packages/demo/demo-v3/scripts/envConfig.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2018/5/31. 3 | */ 4 | 5 | // envConfig 分为两部分参数 1、根据入口文件携带的固定参数 2、根具 npm_config 获取参数可以覆盖1的参数 6 | // 不同入口文件需要自己调用 initConfig 7 | 8 | const argv = require('yargs').argv; 9 | 10 | const manifestAlias = { 11 | lgb: 'log', 12 | dgb: 'dir', 13 | rgb: 'report', 14 | }; 15 | 16 | exports.getConfig = () => { 17 | try { 18 | return JSON.parse(process.env.npm_config_argv).original.slice(2).reduce((preVal, item) => { 19 | const param = item.replace(/^--/, ''); 20 | const [key, value] = param.split('='); 21 | preVal[key] = value || !0; 22 | 23 | // 别名 24 | if (manifestAlias[key]) { 25 | preVal[manifestAlias[key]] = preVal[key]; 26 | } 27 | return preVal; 28 | }, argv); 29 | } catch (e) { 30 | // 31 | console.warn('JSON parse "process.env.npm_config_argv" fail !'); 32 | } 33 | return {}; 34 | }; 35 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/FlashSaleGoodsList/uiSchema.js: -------------------------------------------------------------------------------- 1 | import genImgItem from '../_commonConfig/ui/genImgItem'; 2 | 3 | export default { 4 | startTime: { 5 | 'ui:options': { 6 | placeholder: '选择开始时间', 7 | style: { 8 | width: '100%' 9 | }, 10 | pickerOptions: { 11 | disabledDate(time) { 12 | return time.getTime() < Date.now(); 13 | } 14 | } 15 | } 16 | }, 17 | seckillBrand: { 18 | ...genImgItem(), 19 | 'ui:title': '右侧固定广告位配置' 20 | }, 21 | goodsList: { 22 | 'ui:options': { 23 | title: '添加商品', 24 | description: '添加秒杀商品,这里应该是结合具体业务调用添加商品逻辑', 25 | showIndexNumber: true 26 | }, 27 | items: { 28 | ...genImgItem({ 29 | width: 1920, 30 | height: 500, 31 | }), 32 | 'ui:title': '商品配置' 33 | } 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /packages/lib/utils/vueCommonUtils.js: -------------------------------------------------------------------------------- 1 | // 内部使用 . ,配置数据key不能出现. 2 | export const pathSeparator = '.'; 3 | 4 | // nodePath 转css类名 5 | export function nodePath2ClassName(path) { 6 | const rootPathName = '__pathRoot'; 7 | return path ? `${rootPathName}.${path}`.replace(/\./g, '_') : rootPathName; 8 | } 9 | 10 | // 是否为根节点 11 | export function isRootNodePath(path) { 12 | return path === ''; 13 | } 14 | 15 | // 计算当前节点path 16 | export function computedCurPath(prePath, curKey) { 17 | return prePath === '' ? curKey : [prePath, curKey].join(pathSeparator); 18 | } 19 | 20 | // 获取当前path值 21 | export function getPathVal(obj, path, leftDeviation = 0) { 22 | const pathArr = path.split(pathSeparator); 23 | 24 | for (let i = 0; i < pathArr.length - leftDeviation; i += 1) { 25 | // 错误路径或者undefined中断查找 26 | if (obj === undefined) return undefined; 27 | obj = pathArr[i] === '' ? obj : obj[pathArr[i]]; 28 | } 29 | return obj; 30 | } 31 | 32 | // path 等于props 33 | export function path2prop(path) { 34 | return path; 35 | } 36 | -------------------------------------------------------------------------------- /packages/lib/utils/schema/findSchemaDefinition.js: -------------------------------------------------------------------------------- 1 | // $ref 引用 2 | function getPathVal(obj, pathStr) { 3 | const pathArr = pathStr.split('/'); 4 | for (let i = 0; i < pathArr.length; i += 1) { 5 | if (obj === undefined) return undefined; 6 | obj = pathArr[i] === '' ? obj : obj[pathArr[i]]; 7 | } 8 | return obj; 9 | } 10 | 11 | // 找到ref引用的schema 12 | export default function findSchemaDefinition($ref, rootSchema = {}) { 13 | const origRef = $ref; 14 | if ($ref.startsWith('#')) { 15 | // Decode URI fragment representation. 16 | $ref = decodeURIComponent($ref.substring(1)); 17 | } else { 18 | throw new Error(`Could not find a definition for ${origRef}.`); 19 | } 20 | const current = getPathVal(rootSchema, $ref); 21 | 22 | if (current === undefined) { 23 | throw new Error(`Could not find a definition for ${origRef}.`); 24 | } 25 | if (current.hasOwnProperty('$ref')) { 26 | return findSchemaDefinition(current.$ref, rootSchema); 27 | } 28 | return current; 29 | } 30 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-naive/src/config/widgets/RadioWidget/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2021/2/23 10:21 下午. 3 | */ 4 | 5 | import { h } from 'vue'; 6 | import { modelValueComponent, resolveComponent } from '@lljj/vjsf-utils/vue3Utils'; 7 | 8 | const baseComponent = { 9 | name: 'RadioWidget', 10 | props: { 11 | enumOptions: { 12 | default: () => [], 13 | type: [Array] 14 | } 15 | }, 16 | setup(props, { attrs }) { 17 | return () => h(resolveComponent('n-radio-group'), attrs, { 18 | default() { 19 | return props.enumOptions.map((item, index) => h(resolveComponent('n-radio'), { 20 | key: index, 21 | value: item.value 22 | }, { 23 | default: () => item.label 24 | })); 25 | } 26 | }); 27 | } 28 | }; 29 | 30 | const moduleValeComponent = modelValueComponent(baseComponent, { 31 | model: 'value' 32 | }); 33 | 34 | export default moduleValeComponent; 35 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-ant/src/config/widgets/DateTimePickerWidget/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2021/2/23 10:21 下午. 3 | */ 4 | 5 | import { h } from 'vue'; 6 | import { resolveComponent } from '@lljj/vjsf-utils/vue3Utils'; 7 | import { modelValueComponent, numberTimeComponent } from '../../utils'; 8 | 9 | const baseComponent = { 10 | name: 'DatePickerWidget', 11 | inheritAttrs: false, 12 | setup(props, { attrs }) { 13 | return () => { 14 | const { isNumberValue, isRange, ...otherAttrs } = attrs; 15 | return h(resolveComponent(isRange ? 'a-range-picker' : 'a-date-picker'), { 16 | valueFormat: isNumberValue ? 'x' : 'YYYY-MM-DDTHH:mm:ssZ', 17 | showTime: true, 18 | ...otherAttrs 19 | }); 20 | }; 21 | } 22 | }; 23 | 24 | const timeNumberComponent = numberTimeComponent(baseComponent); 25 | 26 | const moduleValeComponent = modelValueComponent(timeNumberComponent, { 27 | model: 'value' 28 | }); 29 | 30 | export default moduleValeComponent; 31 | -------------------------------------------------------------------------------- /packages/docs/docs/zh/guide/datetime-config.md: -------------------------------------------------------------------------------- 1 | # 日期时间配置 2 | * 详细配置demo参见这里:[在线演示 dateTime](https://form.lljj.me/#/demo?type=Date-DateTime) 3 | 4 | :::warning 5 | 对type为 `number` `array` 类型配置 `format` 这里打破了 `JSON Schema` 规范 6 | ::: 7 | 8 | 支持配置如下三种 `format` 配置时间和日期 9 | 10 | ## format `date-time` 11 | 使用日期时间格式选择器渲染,`支持区间选择` 12 | 13 | * 支持配置 type `number` `string` `array` 14 | * `string`:`2018-11-13T20:20:39+00:00` ISO字符串格式 15 | * `number`: `1595492397822` 数字时间戳格式 16 | * `array`:使用区间选择 17 | 18 | >* 如果配置了 type `array` ,那么必须要在 items type 里面配置里面申明类型(`number` | `string`) 19 | >* 如下:日期时间区间选择,使用 `string` 类型 20 | 21 | > ```json 22 | > { 23 | > "dateTimeRange": { 24 | > "title": "日期时间区间选择", 25 | > "type": "array", 26 | > "format": "date-time", 27 | > "items": { 28 | > "type": "string" 29 | > } 30 | > } 31 | > } 32 | > ``` 33 | 34 | ## format `date` 35 | 使用日期格式选择器渲染,`支持区间选择` 36 | 37 | * 支持配置 type `number` `string` `array` 38 | * 和 [format-date-time](#format-date-time) 配置一致 39 | 40 | ## format `time` 41 | * 只支持支持配置 type `string` 格式 `16:04:41` 42 | * 不支持配置区间 43 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-iview3/src/config/widgets/WIDGET_MAP.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/4/21 18:23. 3 | */ 4 | 5 | // widget 组件对应elementUi 配置表 6 | 7 | import widgetComponents from './index'; 8 | 9 | const { 10 | CheckboxesWidget, 11 | RadioWidget, 12 | SelectWidget, 13 | TimePickerWidget, 14 | DatePickerWidget, 15 | DateTimePickerWidget, 16 | SwitchWidget, 17 | InputNumberWidget 18 | } = widgetComponents; 19 | 20 | export default { 21 | types: { 22 | boolean: SwitchWidget, 23 | string: 'i-input', 24 | number: InputNumberWidget, 25 | integer: InputNumberWidget, 26 | }, 27 | formats: { 28 | color: 'color-picker', 29 | time: TimePickerWidget, // 20:20:39+00:00 30 | date: DatePickerWidget, // 2018-11-13 31 | 'date-time': DateTimePickerWidget, // 2018-11-13T20:20:39+00:00 32 | }, 33 | common: { 34 | select: SelectWidget, 35 | radioGroup: RadioWidget, 36 | checkboxGroup: CheckboxesWidget, 37 | }, 38 | widgetComponents 39 | }; 40 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-core/src/fields/ArrayField/arrayTypes/ArrayFieldSpecialFormat.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/9/16 10:25. 3 | */ 4 | 5 | import { h, computed } from 'vue'; 6 | import { getWidgetConfig } from '@lljj/vjsf-utils/formUtils'; 7 | import vueProps from '../../props'; 8 | import Widget from '../../../components/Widget'; 9 | 10 | export default { 11 | name: 'ArrayFieldSpecialFormat', 12 | props: vueProps, 13 | setup(props, { attrs }) { 14 | const widgetConfig = computed(() => getWidgetConfig({ 15 | schema: { 16 | 'ui:widget': props.globalOptions.WIDGET_MAP.formats[props.schema.format], 17 | ...props.schema 18 | }, 19 | uiSchema: props.uiSchema, 20 | curNodePath: props.curNodePath, 21 | rootFormData: props.rootFormData 22 | })); 23 | 24 | return () => h( 25 | Widget, 26 | { 27 | ...attrs, 28 | ...props, 29 | ...widgetConfig.value 30 | } 31 | ); 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-ant/src/config/widgets/RadioWidget/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2021/2/23 10:21 下午. 3 | */ 4 | 5 | import { h } from 'vue'; 6 | import { resolveComponent } from '@lljj/vjsf-utils/vue3Utils'; 7 | import { modelValueComponent } from '../../utils'; 8 | 9 | const baseComponent = { 10 | name: 'RadioWidget', 11 | props: { 12 | enumOptions: { 13 | default: () => [], 14 | type: [Array] 15 | } 16 | }, 17 | setup(props, { attrs }) { 18 | return () => h(resolveComponent('a-radio-group'), attrs, { 19 | default() { 20 | return props.enumOptions.map((item, index) => h(resolveComponent('a-radio'), { 21 | key: index, 22 | value: item.value 23 | }, { 24 | default: () => item.label 25 | })); 26 | } 27 | }); 28 | } 29 | }; 30 | 31 | const moduleValeComponent = modelValueComponent(baseComponent, { 32 | model: 'value' 33 | }); 34 | 35 | export default moduleValeComponent; 36 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-ant/src/config/widgets/CheckboxesWidget/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2021/2/23 10:21 下午. 3 | */ 4 | 5 | import { h } from 'vue'; 6 | import { resolveComponent } from '@lljj/vjsf-utils/vue3Utils'; 7 | import { modelValueComponent } from '../../utils'; 8 | 9 | const baseComponent = { 10 | name: 'CheckboxesWidget', 11 | props: { 12 | enumOptions: { 13 | default: () => [], 14 | type: [Array] 15 | } 16 | }, 17 | setup(props, { attrs }) { 18 | return () => h(resolveComponent('a-checkbox-group'), attrs, { 19 | default() { 20 | return props.enumOptions.map((item, index) => h(resolveComponent('a-checkbox'), { 21 | key: index, 22 | value: item.value 23 | }, { 24 | default: () => item.label 25 | })); 26 | } 27 | }); 28 | } 29 | }; 30 | 31 | const moduleValeComponent = modelValueComponent(baseComponent, { 32 | model: 'value' 33 | }); 34 | 35 | export default moduleValeComponent; 36 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-element/src/config/widgets/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/5/17 10:41 下午. 3 | */ 4 | 5 | import CheckboxesWidget from './CheckboxesWidget'; 6 | import RadioWidget from './RadioWidget'; 7 | import SelectWidget from './SelectWidget'; 8 | import DatePickerWidget from './DatePickerWidget'; 9 | import DateTimePickerWidget from './DateTimePickerWidget'; 10 | import TimePickerWidget from './TimePickerWidget'; 11 | import UploadWidget from './UploadWidget'; 12 | 13 | // webpack -> rollup 14 | // const files = require.context('.', true, /\.js|vue$/); 15 | // const widgetComponents = files.keys().reduce((preVal, curKey) => { 16 | // if (curKey !== './index.js') { 17 | // preVal[curKey.replace(/(\.\/|\/index\.(js|vue))/g, '')] = files(curKey).default; 18 | // } 19 | // return preVal; 20 | // }, {}); 21 | 22 | 23 | const widgetComponents = { 24 | CheckboxesWidget, 25 | RadioWidget, 26 | SelectWidget, 27 | TimePickerWidget, 28 | DatePickerWidget, 29 | DateTimePickerWidget, 30 | UploadWidget 31 | }; 32 | 33 | export default widgetComponents; 34 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-ant/scripts/watch.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/6/2 15:58. 3 | */ 4 | 5 | const path = require('path'); 6 | const rollup = require('rollup'); 7 | const baseConfig = require('./base.config'); 8 | 9 | const resolve = p => path.resolve(__dirname, '../', p); 10 | 11 | const watchConfig = baseConfig({ 12 | sourcemap: true 13 | }); 14 | 15 | // watch 16 | const watcher = rollup.watch({ 17 | ...watchConfig, 18 | watch: { 19 | buildDelay: 300, 20 | include: resolve('src/**'), 21 | exclude: resolve('node_modules/**'), 22 | clearScreen: true 23 | } 24 | }); 25 | 26 | watcher.on('event', (event) => { 27 | // event.code can be one of: 28 | // START — the watcher is (re)starting 29 | // BUNDLE_START — building an individual bundle 30 | // BUNDLE_END — finished building a bundle 31 | // END — finished building all bundles 32 | // ERROR — encountered an error while bundling 33 | console.log(`Watch Event Code: ${event.code}`); 34 | }); 35 | 36 | // stop watching 37 | // watcher.close(); 38 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-ant/src/config/widgets/WIDGET_MAP.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/4/21 18:23. 3 | */ 4 | 5 | // widget 组件对应elementUi 配置表 6 | 7 | import widgetComponents from './index'; 8 | 9 | const { 10 | InputWidget, 11 | InputNumberWidget, 12 | SwitchWidget, 13 | CheckboxesWidget, 14 | RadioWidget, 15 | SelectWidget, 16 | TimePickerWidget, 17 | DatePickerWidget, 18 | DateTimePickerWidget, 19 | ColorWidget 20 | } = widgetComponents; 21 | 22 | export default { 23 | types: { 24 | boolean: SwitchWidget, 25 | string: InputWidget, 26 | number: InputNumberWidget, 27 | integer: InputNumberWidget, 28 | }, 29 | formats: { 30 | color: ColorWidget, 31 | time: TimePickerWidget, // 20:20:39+00:00 32 | date: DatePickerWidget, // 2018-11-13 33 | 'date-time': DateTimePickerWidget, // 2018-11-13T20:20:39+00:00 34 | }, 35 | common: { 36 | select: SelectWidget, 37 | radioGroup: RadioWidget, 38 | checkboxGroup: CheckboxesWidget, 39 | }, 40 | widgetComponents 41 | }; 42 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-naive/scripts/watch.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/6/2 15:58. 3 | */ 4 | 5 | const path = require('path'); 6 | const rollup = require('rollup'); 7 | const baseConfig = require('./base.config'); 8 | 9 | const resolve = p => path.resolve(__dirname, '../', p); 10 | 11 | const watchConfig = baseConfig({ 12 | sourcemap: true 13 | }); 14 | 15 | // watch 16 | const watcher = rollup.watch({ 17 | ...watchConfig, 18 | watch: { 19 | buildDelay: 300, 20 | include: resolve('src/**'), 21 | exclude: resolve('node_modules/**'), 22 | clearScreen: true 23 | } 24 | }); 25 | 26 | watcher.on('event', (event) => { 27 | // event.code can be one of: 28 | // START — the watcher is (re)starting 29 | // BUNDLE_START — building an individual bundle 30 | // BUNDLE_END — finished building a bundle 31 | // END — finished building all bundles 32 | // ERROR — encountered an error while bundling 33 | console.log(`Watch Event Code: ${event.code}`); 34 | }); 35 | 36 | // stop watching 37 | // watcher.close(); 38 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-naive/src/config/widgets/WIDGET_MAP.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/4/21 18:23. 3 | */ 4 | 5 | // widget 组件对应elementUi 配置表 6 | import widgetComponents from './index'; 7 | 8 | const { 9 | CheckboxesWidget, 10 | RadioWidget, 11 | SelectWidget, 12 | TimePickerWidget, 13 | DatePickerWidget, 14 | DateTimePickerWidget, 15 | InputWidget, 16 | SwitchWidget, 17 | InputNumberWidget, 18 | ColorWidget 19 | } = widgetComponents; 20 | 21 | export default { 22 | types: { 23 | boolean: SwitchWidget, 24 | string: InputWidget, 25 | number: InputNumberWidget, 26 | integer: InputNumberWidget, 27 | }, 28 | formats: { 29 | color: ColorWidget, 30 | time: TimePickerWidget, // 20:20:39+00:00 31 | date: DatePickerWidget, // 2018-11-13 32 | 'date-time': DateTimePickerWidget, // 2018-11-13T20:20:39+00:00 33 | }, 34 | common: { 35 | select: SelectWidget, 36 | radioGroup: RadioWidget, 37 | checkboxGroup: CheckboxesWidget, 38 | }, 39 | widgetComponents 40 | }; 41 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-element/scripts/watch.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/6/2 15:58. 3 | */ 4 | 5 | const path = require('path'); 6 | const rollup = require('rollup'); 7 | const baseConfig = require('./base.config'); 8 | 9 | const resolve = p => path.resolve(__dirname, '../', p); 10 | 11 | const watchConfig = baseConfig({ 12 | sourcemap: true 13 | }); 14 | 15 | // watch 16 | const watcher = rollup.watch({ 17 | ...watchConfig, 18 | watch: { 19 | buildDelay: 300, 20 | include: resolve('src/**'), 21 | exclude: resolve('node_modules/**'), 22 | clearScreen: true 23 | } 24 | }); 25 | 26 | watcher.on('event', (event) => { 27 | // event.code can be one of: 28 | // START — the watcher is (re)starting 29 | // BUNDLE_START — building an individual bundle 30 | // BUNDLE_END — finished building a bundle 31 | // END — finished building all bundles 32 | // ERROR — encountered an error while bundling 33 | console.log(`Watch Event Code: ${event.code}`); 34 | }); 35 | 36 | // stop watching 37 | // watcher.close(); 38 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-iview3/scripts/watch.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/6/2 15:58. 3 | */ 4 | 5 | const path = require('path'); 6 | const rollup = require('rollup'); 7 | const baseConfig = require('./base.config'); 8 | 9 | const resolve = p => path.resolve(__dirname, '../', p); 10 | 11 | const watchConfig = baseConfig({ 12 | sourcemap: true 13 | }); 14 | 15 | // watch 16 | const watcher = rollup.watch({ 17 | ...watchConfig, 18 | watch: { 19 | buildDelay: 300, 20 | include: resolve('src/**'), 21 | exclude: resolve('node_modules/**'), 22 | clearScreen: true 23 | } 24 | }); 25 | 26 | watcher.on('event', (event) => { 27 | // event.code can be one of: 28 | // START — the watcher is (re)starting 29 | // BUNDLE_START — building an individual bundle 30 | // BUNDLE_END — finished building a bundle 31 | // END — finished building all bundles 32 | // ERROR — encountered an error while bundling 33 | console.log(`Watch Event Code: ${event.code}`); 34 | }); 35 | 36 | // stop watching 37 | // watcher.close(); 38 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-element/scripts/watch.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/6/2 15:58. 3 | */ 4 | 5 | const path = require('path'); 6 | const rollup = require('rollup'); 7 | const baseConfig = require('./base.config'); 8 | 9 | const resolve = p => path.resolve(__dirname, '../', p); 10 | 11 | const watchConfig = baseConfig({ 12 | sourcemap: true 13 | }); 14 | 15 | // watch 16 | const watcher = rollup.watch({ 17 | ...watchConfig, 18 | watch: { 19 | buildDelay: 300, 20 | include: resolve('src/**'), 21 | exclude: resolve('node_modules/**'), 22 | clearScreen: true 23 | } 24 | }); 25 | 26 | watcher.on('event', (event) => { 27 | // event.code can be one of: 28 | // START — the watcher is (re)starting 29 | // BUNDLE_START — building an individual bundle 30 | // BUNDLE_END — finished building a bundle 31 | // END — finished building all bundles 32 | // ERROR — encountered an error while bundling 33 | console.log(`Watch Event Code: ${event.code}`); 34 | }); 35 | 36 | // stop watching 37 | // watcher.close(); 38 | -------------------------------------------------------------------------------- /packages/docs/docs/.vuepress/enhanceApp.js: -------------------------------------------------------------------------------- 1 | import ElementUI from 'element-ui'; 2 | import 'element-ui/lib/theme-chalk/index.css'; 3 | import VueForm from '@lljj/vue-json-schema-form'; 4 | 5 | import componentWithDialog from './injectVue/component-with-dialog'; 6 | import JsonPerttyPrint from './injectVue/JsonPerttyPrint.vue'; 7 | 8 | const LinkImgField = () => import('./injectVue/field/LinkImgField.vue'); 9 | const DistpickerField = () => import('./injectVue/field/DistpickerField.vue'); 10 | 11 | 12 | function showJson({ componentProps }) { 13 | const instance = componentWithDialog({ 14 | VueComponent: JsonPerttyPrint, 15 | dialogProps: { 16 | title: 'formData', 17 | width: '800px' 18 | }, 19 | componentProps 20 | }); 21 | } 22 | 23 | export default ({ 24 | Vue 25 | }) => { 26 | Vue.use(ElementUI); 27 | Vue.component('VueForm', VueForm); 28 | Vue.component('LinkImgField', LinkImgField); 29 | Vue.component('DistpickerField', DistpickerField); 30 | 31 | Vue.prototype.$componentWithDialog = componentWithDialog; 32 | Vue.prototype.$showJson = showJson; 33 | } 34 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/data.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/4/28 15:36. 3 | */ 4 | 5 | export function vm2Api(vmData) { 6 | return vmData.map(item => ({ 7 | name: item.name, 8 | value: item.componentValue, 9 | })); 10 | } 11 | 12 | function getComponentMap(configTools) { 13 | const componentList = configTools.reduce((preVal, curVal) => [ 14 | ...preVal, 15 | ...curVal.componentList 16 | ], []); 17 | 18 | // 注册组件结构 19 | return componentList.reduce((preVal, componentItem) => { 20 | preVal[componentItem.name] = componentItem; 21 | return preVal; 22 | }, {}); 23 | } 24 | 25 | export function api2VmToolItem(configTools, apiData) { 26 | const componentMap = getComponentMap(configTools); 27 | try { 28 | const apiJson = apiData === String(apiData) ? JSON.parse(apiData) : apiData; 29 | return apiJson.map(({ name, value }) => ({ 30 | ...componentMap[name], 31 | componentValue: value 32 | })); 33 | } catch (e) { 34 | // 数据解析失败不处理 35 | return []; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/docs/docs/.vuepress/plugins/demo-container/src/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 提供 ::: demo xxx ::: 语法,用于构建 markdown 中的示例 3 | */ 4 | const path = require('path') 5 | const renderDemoBlock = require('./common/render') 6 | const demoBlockContainers = require('./common/containers') 7 | module.exports = (options = {}, ctx) => { 8 | return { 9 | enhanceAppFiles: path.resolve(__dirname, './enhanceAppFile.js'), 10 | chainMarkdown(config) { 11 | config.plugin('containers') 12 | .use(demoBlockContainers(options)) 13 | .end(); 14 | }, 15 | extendMarkdown: md => { 16 | const id = setInterval(() => { 17 | const render = md.render; 18 | if (typeof render.call(md, '') === 'object') { 19 | md.render = (...args) => { 20 | let result = render.call(md, ...args); 21 | const { template, script, style } = renderDemoBlock(result.html); 22 | result.html = template; 23 | result.dataBlockString = `${script}\n${style}\n${result.dataBlockString}`; 24 | return result; 25 | } 26 | clearInterval(id); 27 | } 28 | }, 10); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /packages/docs/docs/zh/rules/null.md: -------------------------------------------------------------------------------- 1 | # null 2 | 3 | ## 描述 4 | >* type `null` 相关配置演示 5 | >* 官方文档 - [JSON Schema null](https://json-schema.org/understanding-json-schema/reference/null.html) 6 | 7 | ## 数据校验 8 | * `null` 类型 固定值为 null,null field 不渲染,`formData` 值为 `null` 9 | 10 | 如下演示:`schema` `ui-schema` `error-schema` 相关配置 11 | 12 | :::demo 13 | ```html 14 | 24 | 42 | ``` 43 | 44 | 45 | -------------------------------------------------------------------------------- /.github/workflows/dev-docs-demo.yml: -------------------------------------------------------------------------------- 1 | name: Deploy docs 2 | 3 | on: 4 | push: 5 | branches: [ master-dev ] 6 | 7 | jobs: 8 | build-and-deploy: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - name: Checkout # checkout 13 | uses: actions/checkout@v2 14 | 15 | - name: Setup node 16 | uses: actions/setup-node@v1 17 | with: 18 | node-version: "12.x" 19 | 20 | - name: Install yarn 21 | run: npm install -g yarn 22 | 23 | - name: Build 24 | run: | 25 | yarn install 26 | yarn run demo:build 27 | yarn run demo3:build 28 | 29 | - name: Setup aliyun oss 30 | # 设置阿里云OSS配置 31 | uses: manyuanrong/setup-ossutil@v2.0 32 | with: 33 | endpoint: "oss-cn-hongkong.aliyuncs.com" 34 | access-key-id: ${{ secrets.OSS_ACCESSKEYID }} 35 | access-key-secret: ${{ secrets.OSS_ACCESSKEYSECRET }} 36 | 37 | - name: Deploy demo-v2 38 | # 发布demo-v2 39 | run: ossutil cp -rf ./packages/demo/demo-v2/dist/ oss://dev-form/ 40 | 41 | - name: Deploy demo-v3 42 | # 发布demo-v3 43 | run: ossutil cp -rf ./packages/demo/demo-v3/dist/v3 oss://dev-form/v3 44 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponentsM/CarouselImg/CarouselImg.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "type": "object", 4 | "properties": { 5 | "imgList": { 6 | "type": "array", 7 | "minItems": 1, 8 | "maxItems": 4, 9 | "items": { 10 | "type": "object", 11 | "properties": { 12 | "imgUrl": { 13 | "type": "string", 14 | "format": "uri", 15 | "default": "https://m.360buyimg.com/babel/jfs/t1/116779/33/13215/494116/5f19a54fE4e3bf7cc/8a2a7b0732385d19.jpg.webp" 16 | }, 17 | "imgLink": { 18 | "type": "string", 19 | "format": "uri", 20 | "default": "https://www.google.com" 21 | } 22 | }, 23 | "required": [ 24 | "imgUrl", 25 | "imgLink" 26 | ] 27 | } 28 | } 29 | }, 30 | "additionalProperties": false 31 | } 32 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-core/src/fields/ArrayField/arrayTypes/ArrayFieldSpecialFormat.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/9/16 10:25. 3 | */ 4 | 5 | import { getWidgetConfig } from '@lljj/vjsf-utils/formUtils'; 6 | import vueProps from '../../props'; 7 | import Widget from '../../../components/Widget'; 8 | 9 | export default { 10 | name: 'ArrayFieldSpecialFormat', 11 | props: vueProps, 12 | functional: true, 13 | render(h, context) { 14 | const { 15 | schema, uiSchema, curNodePath, rootFormData, globalOptions 16 | } = context.props; 17 | const widgetConfig = getWidgetConfig({ 18 | schema: { 19 | 'ui:widget': globalOptions.WIDGET_MAP.formats[schema.format], 20 | ...schema 21 | }, 22 | uiSchema, 23 | curNodePath, 24 | rootFormData 25 | }); 26 | 27 | return h( 28 | Widget, 29 | { 30 | ...context.data, 31 | props: { 32 | ...context.props, 33 | ...widgetConfig 34 | } 35 | } 36 | ); 37 | } 38 | }; 39 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/schema-generator/views/editor/data.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/4/28 15:36. 3 | */ 4 | 5 | export function vm2Api(vmData) { 6 | return vmData.map(item => ({ 7 | name: item.componentPack.propsSchema.id, 8 | value: item.componentValue, 9 | })); 10 | } 11 | 12 | function getComponentMap(configTools) { 13 | const componentList = configTools.reduce((preVal, curVal) => [ 14 | ...preVal, 15 | ...curVal.componentList 16 | ], []); 17 | 18 | // 注册组件结构 19 | return componentList.reduce((preVal, componentItem) => { 20 | preVal[componentItem.componentPack.propsSchema.id] = componentItem; 21 | return preVal; 22 | }, {}); 23 | } 24 | 25 | export function api2VmToolItem(configTools, apiData) { 26 | const componentMap = getComponentMap(configTools); 27 | try { 28 | const apiJson = apiData === String(apiData) ? JSON.parse(apiData) : apiData; 29 | return apiJson.map(({ name, value }) => ({ 30 | ...componentMap[name], 31 | componentValue: value 32 | })); 33 | } catch (e) { 34 | // 数据解析失败不处理 35 | return []; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/MultipleImg1_3/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "type": "object", 4 | "definitions": { 5 | "ImgItem": { 6 | "type": "object", 7 | "properties": { 8 | "imgUrl": { 9 | "type": "string", 10 | "format": "uri" 11 | }, 12 | "imgLink": { 13 | "type": "string", 14 | "format": "uri", 15 | "default": "https://www.tmall.com/" 16 | } 17 | }, 18 | "required": [ 19 | "imgUrl", 20 | "imgLink" 21 | ] 22 | } 23 | }, 24 | "properties": { 25 | "imgItem1_1": { 26 | "$ref": "#/definitions/ImgItem" 27 | }, 28 | "imgItem2_1": { 29 | "$ref": "#/definitions/ImgItem" 30 | }, 31 | "imgItem2_2": { 32 | "$ref": "#/definitions/ImgItem" 33 | }, 34 | "imgItem2_3": { 35 | "$ref": "#/definitions/ImgItem" 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-core/src/components/FieldGroupWrap.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 46 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/CarouselImg/CarouselImg.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "type": "object", 4 | "properties": { 5 | "imgList": { 6 | "type": "array", 7 | "minItems": 1, 8 | "maxItems": 4, 9 | "uniqueItems": true, 10 | "items": { 11 | "type": "object", 12 | "properties": { 13 | "imgUrl": { 14 | "type": "string", 15 | "format": "uri", 16 | "default": "https://m.360buyimg.com/babel/jfs/t1/116779/33/13215/494116/5f19a54fE4e3bf7cc/8a2a7b0732385d19.jpg.webp" 17 | }, 18 | "imgLink": { 19 | "type": "string", 20 | "format": "uri", 21 | "default": "https://www.google.com" 22 | } 23 | }, 24 | "required": [ 25 | "imgUrl", 26 | "imgLink" 27 | ] 28 | } 29 | } 30 | }, 31 | "additionalProperties": false 32 | } 33 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-form-ant/src/config/widgets/SelectWidget/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2021/2/23 10:21 下午. 3 | */ 4 | 5 | import { h } from 'vue'; 6 | import { resolveComponent } from '@lljj/vjsf-utils/vue3Utils'; 7 | import { modelValueComponent } from '../../utils'; 8 | 9 | const baseComponent = { 10 | name: 'SelectWidget', 11 | props: { 12 | enumOptions: { 13 | default: () => [], 14 | type: [Array] 15 | } 16 | }, 17 | setup(props, { attrs }) { 18 | return () => h(resolveComponent('a-select'), { 19 | ...(attrs.multiple ? { 20 | mode: 'multiple' 21 | } : {}), 22 | ...attrs, 23 | }, { 24 | default() { 25 | return props.enumOptions.map((item, index) => h(resolveComponent('a-select-option'), { 26 | key: index, 27 | value: item.value 28 | }, { 29 | default: () => item.label 30 | })); 31 | } 32 | }); 33 | } 34 | }; 35 | 36 | const moduleValeComponent = modelValueComponent(baseComponent, { 37 | model: 'value' 38 | }); 39 | 40 | export default moduleValeComponent; 41 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/schema-generator/views/editor/viewComponents/DateRange/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/10/30 17:11. 3 | */ 4 | 5 | import genSchema from '../genSchema.js'; 6 | 7 | const viewSchema = { 8 | title: 'Date范围(时间戳)', 9 | type: 'array', 10 | format: 'date', 11 | items: { 12 | type: 'number' 13 | } 14 | }; 15 | 16 | export default { 17 | viewSchema, 18 | propsSchema: genSchema({ 19 | options: { 20 | type: 'object', 21 | title: '选项', 22 | required: [], 23 | properties: { 24 | uiOptions: { 25 | type: 'object', 26 | properties: { 27 | startPlaceholder: { 28 | type: 'string', 29 | title: '开始占位符', 30 | default: '开始日期' 31 | }, 32 | endPlaceholder: { 33 | type: 'string', 34 | title: '结束占位符', 35 | default: '结束日期' 36 | } 37 | } 38 | } 39 | } 40 | } 41 | }) 42 | }; 43 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/schema-generator/views/editor/viewComponents/DateTimeRange/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/10/30 17:10. 3 | */ 4 | 5 | import genSchema from '../genSchema.js'; 6 | 7 | const viewSchema = { 8 | title: 'DateTime范围(时间戳)', 9 | type: 'array', 10 | format: 'date-time', 11 | items: { 12 | type: 'number' 13 | } 14 | }; 15 | 16 | export default { 17 | viewSchema, 18 | propsSchema: genSchema({ 19 | options: { 20 | type: 'object', 21 | title: '选项', 22 | required: [], 23 | properties: { 24 | uiOptions: { 25 | type: 'object', 26 | properties: { 27 | startPlaceholder: { 28 | type: 'string', 29 | title: '开始占位符', 30 | default: '开始日期' 31 | }, 32 | endPlaceholder: { 33 | type: 'string', 34 | title: '结束占位符', 35 | default: '结束日期' 36 | } 37 | } 38 | } 39 | } 40 | } 41 | }) 42 | }; 43 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/Text/propsSchema.js: -------------------------------------------------------------------------------- 1 | export default { 2 | $schema: 'http://json-schema.org/draft-07/schema#', 3 | title: '单文本输入组件', 4 | description: '单文本输入组件,用于在页面配置一条文字信息', 5 | type: 'object', 6 | required: ['txt'], 7 | properties: { 8 | imgUrl: { 9 | title: '测试图片上传', 10 | type: 'string', 11 | default: 'http://img.alicdn.com/tfs/TB1vYlkdnZmx1VjSZFGXXax2XXa-468-644.jpg_320x5000q100.jpg_.webp', 12 | 'ui:action': 'https://run.mocky.io/v3/518d7af7-204f-45ab-9628-a6e121dab8ca', 13 | 'ui:widget': 'UploadWidget', 14 | 'ui:btnText': '上传按钮文案配置', 15 | 'ui:responseFileUrl': (res) => {} 16 | }, 17 | txt: { 18 | title: '文字', 19 | type: 'string', 20 | 'err:required': '必须输入标题文字内容', 21 | 'fui:placeholder': (parent, root, prop) => { 22 | console.log(parent, root, prop); 23 | return parent.txtColor; 24 | }, 25 | }, 26 | txtColor: { 27 | title: '选择文字颜色', 28 | type: 'string', 29 | format: 'color', 30 | default: '#ff0132' 31 | } 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-form-element/src/config/widgets/DateTimePickerWidget/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/7/22 13:21. 3 | */ 4 | 5 | export default { 6 | name: 'DateTimePickerWidget', 7 | functional: true, 8 | render(h, context) { 9 | const { isNumberValue, isRange, ...otherProps } = context.data.attrs || {}; 10 | 11 | context.data.attrs = { 12 | type: isRange ? 'datetimerange' : 'datetime', 13 | ...otherProps 14 | }; 15 | 16 | // 字符串为 0 时区ISO标准时间 17 | const oldInputCall = context.data.on.input; 18 | context.data.on = { 19 | ...context.data.on, 20 | input(val) { 21 | let trueVal; 22 | if (isRange) { 23 | trueVal = (val === null) ? [] : val.map(item => (new Date(item))[isNumberValue ? 'valueOf' : 'toISOString']()); 24 | } else { 25 | trueVal = (val === null) ? undefined : (new Date(val))[isNumberValue ? 'valueOf' : 'toISOString'](); 26 | } 27 | 28 | oldInputCall.apply(context.data.on, [trueVal]); 29 | } 30 | }; 31 | 32 | return h('el-date-picker', context.data, context.children); 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/MultipleImg5/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "type": "object", 4 | "definitions": { 5 | "ImgItem": { 6 | "title": "图片配置", 7 | "type": "object", 8 | "properties": { 9 | "imgUrl": { 10 | "type": "string", 11 | "format": "uri" 12 | }, 13 | "imgLink": { 14 | "type": "string", 15 | "format": "uri", 16 | "default": "https://www.jd.com/" 17 | } 18 | }, 19 | "required": [ 20 | "imgUrl", 21 | "imgLink" 22 | ] 23 | } 24 | }, 25 | "properties": { 26 | "imgList": { 27 | "title": "配置多图模块", 28 | "description": "图片一行展示,最多配置5张图片", 29 | "type": "array", 30 | "minItems": 1, 31 | "maxItems": 5, 32 | "ui:options": { 33 | "showIndexNumber": true 34 | }, 35 | "items": { 36 | "$ref": "#/definitions/ImgItem" 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/schema-generator/views/editor/viewComponents/Upload/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/11/27 11:03 下午. 3 | */ 4 | 5 | import genSchema from '../genSchema.js'; 6 | 7 | const viewSchema = { 8 | title: '单文件', 9 | type: 'string', 10 | 'ui:widget': 'UploadWidget', 11 | }; 12 | export default { 13 | viewSchema, 14 | propsSchema: genSchema({ 15 | options: { 16 | type: 'object', 17 | title: '选项', 18 | required: [], 19 | properties: { 20 | uiOptions: { 21 | type: 'object', 22 | required: ['action'], 23 | properties: { 24 | action: { 25 | title: '上传接口', 26 | type: 'string', 27 | format: 'uri', 28 | default: 'https://run.mocky.io/v3/518d7af7-204f-45ab-9628-a6e121dab8ca' 29 | }, 30 | btnText: { 31 | title: '上传按钮文案', 32 | type: 'string' 33 | } 34 | } 35 | } 36 | } 37 | } 38 | }) 39 | }; 40 | -------------------------------------------------------------------------------- /packages/lib/vue2/vue2-core/src/props.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/4/16 10:47 下午. 3 | */ 4 | 5 | export default { 6 | formFooter: { 7 | type: Object, 8 | default: () => ({ 9 | show: true, 10 | okBtn: '保存', 11 | cancelBtn: '取消', 12 | }), 13 | }, 14 | value: { 15 | type: null, 16 | default: () => ({}), 17 | required: true 18 | }, 19 | formProps: { 20 | type: Object, 21 | default: () => ({}), 22 | }, 23 | fallbackLabel: { 24 | type: Boolean, 25 | default: false, 26 | }, 27 | strictMode: { 28 | type: Boolean, 29 | default: false, 30 | }, 31 | schema: { 32 | type: Object, 33 | default: () => ({}), 34 | required: true 35 | }, 36 | // 重置ui样式 37 | uiSchema: { 38 | type: Object, 39 | default: () => ({}) 40 | }, 41 | // 自定义校验规则 42 | customFormats: { 43 | type: Object, 44 | default: () => ({}) 45 | }, 46 | // 自定义校验 47 | customRule: { 48 | type: Function, 49 | default: null 50 | }, 51 | // 重置自定义错误 52 | errorSchema: { 53 | type: Object, 54 | default: () => ({}) 55 | } 56 | }; 57 | -------------------------------------------------------------------------------- /.github/workflows/docs-demo.yml: -------------------------------------------------------------------------------- 1 | name: Deploy docs 2 | 3 | on: 4 | push: 5 | branches: [ master-disabled ] 6 | 7 | jobs: 8 | build-and-deploy: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - name: Checkout # checkout 13 | uses: actions/checkout@v2 14 | 15 | - name: Setup node 16 | uses: actions/setup-node@v1 17 | with: 18 | node-version: "12.x" 19 | 20 | - name: Build 21 | run: | 22 | yarn install 23 | yarn run docs:build 24 | yarn run demo:build 25 | yarn run demo3:build 26 | 27 | - name: Setup aliyun oss 28 | # 设置阿里云OSS配置 29 | uses: manyuanrong/setup-ossutil@v2.0 30 | with: 31 | endpoint: "oss-cn-hongkong.aliyuncs.com" 32 | access-key-id: ${{ secrets.OSS_ACCESSKEYID }} 33 | access-key-secret: ${{ secrets.OSS_ACCESSKEYSECRET }} 34 | 35 | - name: Deploy docs 36 | # 发布文档 37 | run: ossutil cp -rf ./packages/docs/docs/.vuepress/dist/ oss://vjsf-docs-buhuida/ 38 | 39 | - name: Deploy demo 40 | # 发布demo 41 | run: ossutil cp -rf ./packages/demo/demo-v2/dist/ oss://form-buhuida/ 42 | 43 | - name: Deploy demo-v3 44 | # 发布demo-v3 45 | run: ossutil cp -rf ./packages/demo/demo-v3/dist/v3 oss://form-buhuida/v3 46 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/schema-generator/views/editor/viewComponents/SelectBoolean/elRadio.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/12/10 15:16. 3 | */ 4 | 5 | import genSchema from '../genSchema.js'; 6 | 7 | const viewSchema = { 8 | title: '是否选择(Radio)', 9 | type: 'boolean', 10 | 'ui:widget': 'RadioWidget' 11 | }; 12 | 13 | export default { 14 | viewSchema, 15 | propsSchema: genSchema({ 16 | options: { 17 | type: 'object', 18 | title: '选项', 19 | properties: { 20 | schemaOptions: { 21 | type: 'object', 22 | properties: { 23 | enumNames: { 24 | type: 'array', 25 | items: [{ 26 | title: '选择文案', 27 | type: 'string', 28 | default: '是' 29 | }, { 30 | title: '非选择文案', 31 | type: 'string', 32 | default: '否' 33 | }] 34 | } 35 | } 36 | } 37 | } 38 | } 39 | }) 40 | }; 41 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/schema-generator/views/editor/viewComponents/SelectBoolean/elSelect.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/12/10 15:16. 3 | */ 4 | 5 | import genSchema from '../genSchema.js'; 6 | 7 | const viewSchema = { 8 | title: '是否选择(Select)', 9 | type: 'boolean', 10 | 'ui:widget': 'SelectWidget' 11 | }; 12 | 13 | export default { 14 | viewSchema, 15 | propsSchema: genSchema({ 16 | options: { 17 | type: 'object', 18 | title: '选项', 19 | properties: { 20 | schemaOptions: { 21 | type: 'object', 22 | properties: { 23 | enumNames: { 24 | type: 'array', 25 | items: [{ 26 | title: '选择文案', 27 | type: 'string', 28 | default: '是' 29 | }, { 30 | title: '非选择文案', 31 | type: 'string', 32 | default: '否' 33 | }] 34 | } 35 | } 36 | } 37 | } 38 | } 39 | }) 40 | }; 41 | -------------------------------------------------------------------------------- /packages/demo/demo-v2/src/pages/vue-editor/views/editor/viewComponents/MultipleImg2_3/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "type": "object", 4 | "definitions": { 5 | "ImgItem": { 6 | "type": "object", 7 | "properties": { 8 | "imgUrl": { 9 | "type": "string", 10 | "format": "uri" 11 | }, 12 | "imgLink": { 13 | "type": "string", 14 | "format": "uri", 15 | "default": "https://www.jd.com/" 16 | } 17 | }, 18 | "required": [ 19 | "imgUrl", 20 | "imgLink" 21 | ] 22 | } 23 | }, 24 | "properties": { 25 | "imgItem1_1": { 26 | "$ref": "#/definitions/ImgItem" 27 | }, 28 | "imgItem1_2": { 29 | "$ref": "#/definitions/ImgItem" 30 | }, 31 | "imgItem2_1": { 32 | "$ref": "#/definitions/ImgItem" 33 | }, 34 | "imgItem2_2": { 35 | "$ref": "#/definitions/ImgItem" 36 | }, 37 | "imgItem2_3": { 38 | "$ref": "#/definitions/ImgItem" 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /packages/lib/vue3/vue3-core/src/props.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Liu.Jun on 2020/4/16 10:47 下午. 3 | */ 4 | 5 | export default { 6 | formFooter: { 7 | type: Object, 8 | default: () => ({ 9 | show: true, 10 | okBtn: '保存', 11 | cancelBtn: '取消', 12 | }), 13 | }, 14 | modelValue: { 15 | type: null, 16 | default: () => ({}), 17 | required: true 18 | }, 19 | fallbackLabel: { 20 | type: Boolean, 21 | default: false, 22 | }, 23 | strictMode: { 24 | type: Boolean, 25 | default: false, 26 | }, 27 | formProps: { 28 | type: Object, 29 | default: () => ({}), 30 | }, 31 | schema: { 32 | type: Object, 33 | default: () => ({}), 34 | required: true 35 | }, 36 | // 重置ui样式 37 | uiSchema: { 38 | type: Object, 39 | default: () => ({}) 40 | }, 41 | // 自定义校验规则 42 | customFormats: { 43 | type: Object, 44 | default: () => ({}) 45 | }, 46 | // 自定义校验 47 | customRule: { 48 | type: Function, 49 | default: null 50 | }, 51 | // 重置自定义错误 52 | errorSchema: { 53 | type: Object, 54 | default: () => ({}) 55 | } 56 | }; 57 | --------------------------------------------------------------------------------