@cicctencent/formily 0.0.0-stage → 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (308) hide show
  1. package/.eslintrc.js +40 -0
  2. package/.prettierrc.js +28 -0
  3. package/.vscode/launch.json +23 -0
  4. package/CHANGELOG.md +8 -0
  5. package/README.md +22 -2
  6. package/babel.config.js +3 -0
  7. package/build/build.js +96 -0
  8. package/build/rollup.config.bundle.js +63 -0
  9. package/build/update.version.js +35 -0
  10. package/dist/index.css +2516 -0
  11. package/dist/index.js +8377 -0
  12. package/dist/schema-field/index.css +2466 -0
  13. package/dist/schema-field/index.js +8213 -0
  14. package/dist/transform/index.js +551 -0
  15. package/dist/validate/index.js +1104 -0
  16. package/dist/vue-form/index.css +2516 -0
  17. package/dist/vue-form/index.js +8359 -0
  18. package/docs/.vuepress/client.ts +15 -0
  19. package/docs/.vuepress/components/code-preview.vue +203 -0
  20. package/docs/.vuepress/components/highlight.ts +53 -0
  21. package/docs/.vuepress/config.ts +39 -0
  22. package/docs/.vuepress/util.ts +7 -0
  23. package/docs/README.md +30 -0
  24. package/docs/components/anyOf.md +26 -0
  25. package/docs/components/array-cards.md +12 -0
  26. package/docs/components/array-collapse.md +12 -0
  27. package/docs/components/array-items.md +12 -0
  28. package/docs/components/array-table.md +12 -0
  29. package/docs/components/array-tabs.md +16 -0
  30. package/docs/components/cascader.md +12 -0
  31. package/docs/components/checkbox.md +12 -0
  32. package/docs/components/event.md +27 -0
  33. package/docs/components/hotArea.md +25 -0
  34. package/docs/components/index.md +4 -0
  35. package/docs/components/input.md +30 -0
  36. package/docs/components/layout-group.md +19 -0
  37. package/docs/components/link.md +22 -0
  38. package/docs/components/oneOf.md +8 -0
  39. package/docs/components/radio.md +12 -0
  40. package/docs/components/rich-editor.md +21 -0
  41. package/docs/components/select.md +34 -0
  42. package/docs/components/space.md +11 -0
  43. package/docs/components/switch.md +20 -0
  44. package/docs/components/text.md +21 -0
  45. package/docs/components/time-picker.md +11 -0
  46. package/docs/components/transfer.md +14 -0
  47. package/docs/components/upload-button.md +28 -0
  48. package/docs/demos/any-of/index.vue +66 -0
  49. package/docs/demos/array-cards/index.vue +105 -0
  50. package/docs/demos/array-collapse/index.vue +155 -0
  51. package/docs/demos/array-items/index.vue +171 -0
  52. package/docs/demos/array-table/index.vue +115 -0
  53. package/docs/demos/array-tabs/index.vue +56 -0
  54. package/docs/demos/cascader/index.vue +297 -0
  55. package/docs/demos/checkbox/index.vue +39 -0
  56. package/docs/demos/event/index.vue +436 -0
  57. package/docs/demos/hotArea/index.vue +240 -0
  58. package/docs/demos/index.vue +36 -0
  59. package/docs/demos/input/index.vue +46 -0
  60. package/docs/demos/layout-group/index.vue +51 -0
  61. package/docs/demos/link/index.vue +32 -0
  62. package/docs/demos/radio/index.vue +36 -0
  63. package/docs/demos/rich-editor/index.vue +22 -0
  64. package/docs/demos/select/index.vue +76 -0
  65. package/docs/demos/space/index.vue +93 -0
  66. package/docs/demos/switch/index.vue +31 -0
  67. package/docs/demos/text/index.vue +38 -0
  68. package/docs/demos/time-picker/index.vue +39 -0
  69. package/docs/demos/transfer/index.vue +26 -0
  70. package/docs/demos/upload-button/index.vue +27 -0
  71. package/docs/demos/x-data/add-button-title.vue +101 -0
  72. package/docs/demos/x-data/send-message.vue +33 -0
  73. package/docs/demos/x-reactions/any-of.vue +40 -0
  74. package/docs/demos/x-reactions/x-reactions.vue +39 -0
  75. package/docs/guide/component-extend.md +23 -0
  76. package/docs/guide/extra-bury-report.md +64 -0
  77. package/docs/guide/schema.md +22 -0
  78. package/docs/guide/x-data.md +41 -0
  79. package/docs/guide/x-reactions.md +20 -0
  80. package/example/.browserslistrc +4 -0
  81. package/example/.eslintrc.js +20 -0
  82. package/example/README.md +24 -0
  83. package/example/index.html +15 -0
  84. package/example/jest.config.js +26 -0
  85. package/example/package.json +50 -0
  86. package/example/public/favicon.ico +0 -0
  87. package/example/public/index.html +17 -0
  88. package/example/src/App.vue +25 -0
  89. package/example/src/assets/logo.png +0 -0
  90. package/example/src/components/HelloWorld.vue +148 -0
  91. package/example/src/components/group/index.vue +16 -0
  92. package/example/src/components/uploadBtn/index.vue +44 -0
  93. package/example/src/components/uploadBtn/upload-icon.svg +6 -0
  94. package/example/src/layout/component/Aside.vue +39 -0
  95. package/example/src/layout/component/Main.vue +9 -0
  96. package/example/src/layout/index.vue +15 -0
  97. package/example/src/main.ts +17 -0
  98. package/example/src/router/index.ts +99 -0
  99. package/example/src/shims-vue.d.ts +6 -0
  100. package/example/src/store/index.ts +9 -0
  101. package/example/src/views/demo/any-of/data.ts +38 -0
  102. package/example/src/views/demo/any-of/index.vue +35 -0
  103. package/example/src/views/demo/array-cards/data.ts +65 -0
  104. package/example/src/views/demo/array-cards/index.vue +33 -0
  105. package/example/src/views/demo/array-items/data.ts +29 -0
  106. package/example/src/views/demo/array-items/index.vue +33 -0
  107. package/example/src/views/demo/cloud-button/data.ts +14 -0
  108. package/example/src/views/demo/cloud-button/index.vue +22 -0
  109. package/example/src/views/demo/color-group/data.ts +15 -0
  110. package/example/src/views/demo/color-group/index.vue +22 -0
  111. package/example/src/views/demo/color-picker/data.ts +21 -0
  112. package/example/src/views/demo/color-picker/index.vue +33 -0
  113. package/example/src/views/demo/datatime/data.ts +62 -0
  114. package/example/src/views/demo/datatime/index.vue +22 -0
  115. package/example/src/views/demo/event/data.ts +184 -0
  116. package/example/src/views/demo/event/index.vue +33 -0
  117. package/example/src/views/demo/hot-area/data.ts +196 -0
  118. package/example/src/views/demo/hot-area/index.vue +33 -0
  119. package/example/src/views/demo/input/data.ts +39 -0
  120. package/example/src/views/demo/input/index.vue +33 -0
  121. package/example/src/views/demo/link/data.ts +23 -0
  122. package/example/src/views/demo/link/index.vue +22 -0
  123. package/example/src/views/demo/one-of/data.ts +139 -0
  124. package/example/src/views/demo/one-of/index.vue +33 -0
  125. package/example/src/views/demo/rich-editor/data.ts +12 -0
  126. package/example/src/views/demo/rich-editor/index.vue +24 -0
  127. package/example/src/views/demo/select/data.ts +38 -0
  128. package/example/src/views/demo/select/index.vue +33 -0
  129. package/example/src/views/demo/upload-button/data1.ts +11 -0
  130. package/example/src/views/demo/upload-button/data2.ts +12 -0
  131. package/example/src/views/demo/upload-button/index.vue +42 -0
  132. package/example/tsconfig.json +32 -0
  133. package/example/vite.config.ts +12 -0
  134. package/jest.config.js +4 -0
  135. package/package.json +92 -4
  136. package/src/components/__builtins__/configs/index.ts +1 -0
  137. package/src/components/__builtins__/index.ts +2 -0
  138. package/src/components/__builtins__/shared/create-context.ts +54 -0
  139. package/src/components/__builtins__/shared/index.ts +7 -0
  140. package/src/components/__builtins__/shared/loading.ts +20 -0
  141. package/src/components/__builtins__/shared/portal.ts +43 -0
  142. package/src/components/__builtins__/shared/resolve-component.ts +22 -0
  143. package/src/components/__builtins__/shared/transform-component.ts +33 -0
  144. package/src/components/__builtins__/shared/types.ts +8 -0
  145. package/src/components/__builtins__/shared/utils.ts +35 -0
  146. package/src/components/__builtins__/styles/common.scss +22 -0
  147. package/src/components/__builtins__/styles/element-plus.scss +1094 -0
  148. package/src/components/any-of/index.ts +20 -0
  149. package/src/components/array-base/index.ts +413 -0
  150. package/src/components/array-base/style.scss +53 -0
  151. package/src/components/array-base/style.ts +2 -0
  152. package/src/components/array-cards/index.ts +253 -0
  153. package/src/components/array-cards/style.scss +33 -0
  154. package/src/components/array-cards/style.ts +7 -0
  155. package/src/components/array-collapse/index.ts +381 -0
  156. package/src/components/array-collapse/style.scss +38 -0
  157. package/src/components/array-collapse/style.ts +10 -0
  158. package/src/components/array-items/index.ts +213 -0
  159. package/src/components/array-items/style.scss +82 -0
  160. package/src/components/array-items/style.ts +4 -0
  161. package/src/components/array-table/index.ts +567 -0
  162. package/src/components/array-table/style.scss +84 -0
  163. package/src/components/array-table/style.ts +11 -0
  164. package/src/components/array-tabs/index.ts +141 -0
  165. package/src/components/array-tabs/style.scss +16 -0
  166. package/src/components/array-tabs/style.ts +5 -0
  167. package/src/components/base/AnyOf/index.ts +155 -0
  168. package/src/components/base/AnyOf/index.vue +111 -0
  169. package/src/components/base/CloudButton/index.ts +46 -0
  170. package/src/components/base/CloudButton/index.vue +128 -0
  171. package/src/components/base/ColorGroup/index.ts +57 -0
  172. package/src/components/base/ColorGroup/index.vue +30 -0
  173. package/src/components/base/ColorPicker/index.ts +45 -0
  174. package/src/components/base/ColorPicker/index.vue +50 -0
  175. package/src/components/base/Container/index.vue +39 -0
  176. package/src/components/base/HotArea/index.ts +698 -0
  177. package/src/components/base/HotArea/index.vue +565 -0
  178. package/src/components/base/HotArea/type.ts +18 -0
  179. package/src/components/base/Input/index.vue +150 -0
  180. package/src/components/base/LayoutGroup/index.vue +40 -0
  181. package/src/components/base/Link/index.vue +43 -0
  182. package/src/components/base/Middleware/index.ts +235 -0
  183. package/src/components/base/Middleware/index.vue +169 -0
  184. package/src/components/base/OneOf/index.ts +105 -0
  185. package/src/components/base/OneOf/index.vue +85 -0
  186. package/src/components/base/RichEditor/index.ts +13 -0
  187. package/src/components/base/RichEditor/index.vue +120 -0
  188. package/src/components/base/RichEditor/options.ts +24 -0
  189. package/src/components/base/Select/index.ts +106 -0
  190. package/src/components/base/Select/index.vue +161 -0
  191. package/src/components/base/Switch/index.vue +42 -0
  192. package/src/components/base/Text/index.vue +47 -0
  193. package/src/components/base/event/index.ts +226 -0
  194. package/src/components/base/event/index.vue +356 -0
  195. package/src/components/cascader/index.ts +48 -0
  196. package/src/components/cascader/style.ts +5 -0
  197. package/src/components/checkbox/index.ts +166 -0
  198. package/src/components/checkbox/style.ts +5 -0
  199. package/src/components/cloud-button/index.ts +21 -0
  200. package/src/components/color-group/index.ts +18 -0
  201. package/src/components/color-picker/index.ts +18 -0
  202. package/src/components/container/index.ts +18 -0
  203. package/src/components/data-time/index.ts +24 -0
  204. package/src/components/date-picker/index.ts +51 -0
  205. package/src/components/date-picker/style.ts +4 -0
  206. package/src/components/editable/index.ts +261 -0
  207. package/src/components/editable/style.scss +55 -0
  208. package/src/components/editable/style.ts +5 -0
  209. package/src/components/el-form-item/index.ts +21 -0
  210. package/src/components/el-form-item/style.ts +3 -0
  211. package/src/components/event/index.ts +16 -0
  212. package/src/components/form/index.ts +94 -0
  213. package/src/components/form/style.scss +0 -0
  214. package/src/components/form/style.ts +3 -0
  215. package/src/components/form-button-group/index.ts +74 -0
  216. package/src/components/form-button-group/style.scss +0 -0
  217. package/src/components/form-button-group/style.ts +4 -0
  218. package/src/components/form-collapse/index.ts +215 -0
  219. package/src/components/form-collapse/style.scss +6 -0
  220. package/src/components/form-collapse/style.ts +4 -0
  221. package/src/components/form-dialog/index.ts +433 -0
  222. package/src/components/form-dialog/style.ts +4 -0
  223. package/src/components/form-drawer/index.ts +424 -0
  224. package/src/components/form-drawer/style.scss +21 -0
  225. package/src/components/form-drawer/style.ts +4 -0
  226. package/src/components/form-grid/index.ts +181 -0
  227. package/src/components/form-grid/style.scss +5 -0
  228. package/src/components/form-grid/style.ts +1 -0
  229. package/src/components/form-item/animation.scss +72 -0
  230. package/src/components/form-item/grid.scss +171 -0
  231. package/src/components/form-item/index.ts +642 -0
  232. package/src/components/form-item/style.scss +521 -0
  233. package/src/components/form-item/style.ts +2 -0
  234. package/src/components/form-item/var.scss +17 -0
  235. package/src/components/form-layout/index.ts +161 -0
  236. package/src/components/form-layout/style.scss +6 -0
  237. package/src/components/form-layout/style.ts +1 -0
  238. package/src/components/form-layout/useResponsiveFormLayout.ts +118 -0
  239. package/src/components/form-step/index.ts +210 -0
  240. package/src/components/form-step/style.ts +2 -0
  241. package/src/components/form-tab/index.ts +172 -0
  242. package/src/components/form-tab/style.scss +6 -0
  243. package/src/components/form-tab/style.ts +4 -0
  244. package/src/components/hot-area/index.ts +20 -0
  245. package/src/components/index.ts +49 -0
  246. package/src/components/input/index.ts +35 -0
  247. package/src/components/input/style.ts +4 -0
  248. package/src/components/input-number/index.ts +36 -0
  249. package/src/components/input-number/style.ts +3 -0
  250. package/src/components/layout-group/index.ts +18 -0
  251. package/src/components/link/index.ts +18 -0
  252. package/src/components/middleware/index.ts +21 -0
  253. package/src/components/one-of/index.ts +20 -0
  254. package/src/components/placeholder-input/index.ts +21 -0
  255. package/src/components/placeholder-input/index.vue +87 -0
  256. package/src/components/preview-text/index.ts +303 -0
  257. package/src/components/preview-text/style.ts +9 -0
  258. package/src/components/radio/index.ts +109 -0
  259. package/src/components/radio/style.ts +3 -0
  260. package/src/components/reset/index.ts +52 -0
  261. package/src/components/reset/style.ts +1 -0
  262. package/src/components/rich-editor/index.ts +18 -0
  263. package/src/components/row/index.ts +20 -0
  264. package/src/components/row/index.vue +53 -0
  265. package/src/components/select/index.ts +19 -0
  266. package/src/components/select/style.ts +5 -0
  267. package/src/components/space/index.ts +98 -0
  268. package/src/components/space/style.scss +24 -0
  269. package/src/components/space/style.ts +1 -0
  270. package/src/components/submit/index.ts +59 -0
  271. package/src/components/submit/style.ts +1 -0
  272. package/src/components/switch/index.ts +9 -0
  273. package/src/components/switch/style.ts +1 -0
  274. package/src/components/text/index.ts +21 -0
  275. package/src/components/time-picker/index.ts +21 -0
  276. package/src/components/time-picker/style.ts +4 -0
  277. package/src/components/transfer/index.ts +12 -0
  278. package/src/components/transfer/style.ts +1 -0
  279. package/src/components/upload/index.ts +136 -0
  280. package/src/components/upload/style.ts +2 -0
  281. package/src/components/upload-button/index.ts +21 -0
  282. package/src/components/upload-button/index.vue +199 -0
  283. package/src/createScemaField.ts +14 -0
  284. package/src/index.ts +41 -0
  285. package/src/schema-field/index.ts +11 -0
  286. package/src/scope.ts +29 -0
  287. package/src/transform/core.ts +404 -0
  288. package/src/transform/index.ts +11 -0
  289. package/src/transform/transform.ts +59 -0
  290. package/src/transform/utils/constant.ts +79 -0
  291. package/src/transform/utils/func.ts +145 -0
  292. package/src/typings/common.ts +37 -0
  293. package/src/typings/vue-shim.d.ts +7 -0
  294. package/src/typings/vue-test-utils.d.ts +11 -0
  295. package/src/utils/anyof_utils.ts +95 -0
  296. package/src/utils/common.ts +15 -0
  297. package/src/validate/index.ts +648 -0
  298. package/src/validate/utils/constant.ts +2 -0
  299. package/src/vue-form/index.ts +18 -0
  300. package/src/vue-form/index.vue +106 -0
  301. package/src/vue-form/useForm.ts +112 -0
  302. package/tests/data/anyof.ts +40 -0
  303. package/tests/data/image.ts +472 -0
  304. package/tests/fixtures/validate.ts +63 -0
  305. package/tests/unit/transform.spec.ts +253 -0
  306. package/tests/unit/utils.spec.ts +10 -0
  307. package/tests/unit/validate.spec.ts +256 -0
  308. package/tsconfig.json +23 -0
@@ -0,0 +1,105 @@
1
+ import {
2
+ createForm,
3
+ Form,
4
+ onFormInit,
5
+ onFormInputChange,
6
+ onFormMount,
7
+ onFormValuesChange,
8
+ } from '@formily/core';
9
+ import { computed, getCurrentInstance, ref, onMounted, watch } from 'vue';
10
+ import { transformSchema } from '../../../transform';
11
+ export default function (props, emit) {
12
+ const ctx = getCurrentInstance();
13
+ const selectValue = ref('');
14
+ let form = ref<Form>();
15
+ let schemaConfig = ref({});
16
+ let emitFlag = false;
17
+ const feedbackText = ref('');
18
+ watch(()=>selectValue.value,(val)=>{
19
+ if(!val && props.required){
20
+ feedbackText.value = '该字段是必填项'
21
+ }else feedbackText.value=''
22
+ },{deep:true,immediate:true})
23
+
24
+ const schemaList = computed(() => {
25
+ return JSON.parse(props?.list ?? '[]');
26
+ })
27
+ const options = computed(() => {
28
+ return schemaList.value.map(item => {
29
+ return {
30
+ label: item.title,
31
+ value: item.properties['name']?.default,
32
+ };
33
+ });
34
+ });
35
+ watch(() => options.value, (val) => {
36
+ if (!val.find(option => option.value === selectValue.value)) {
37
+ selectValue.value = '';
38
+ updateSchemaConfig();
39
+ }
40
+ })
41
+ const updateSchemaConfig = () => {
42
+ if (!Array.isArray(schemaList.value) || !schemaList.value.length) {
43
+ return {};
44
+ }
45
+ let curProperties = {};
46
+ for (let i = 0; i < schemaList.value.length; i++) {
47
+ // One Of 相当于是一个数组, 你选择了哪个,它就渲染哪个schema
48
+ // 这里获取需要渲染的schema
49
+ if (
50
+ schemaList.value[i].properties['name']?.default === selectValue.value
51
+ ) {
52
+ curProperties = {
53
+ type: 'object',
54
+ properties: schemaList.value[i]?.properties ?? {},
55
+ };
56
+ }
57
+ }
58
+ updateForm();
59
+ schemaConfig.value = transformSchema({ schema: curProperties, ctx});
60
+ };
61
+
62
+ function onSelectChange() {
63
+ emit('change', {});
64
+ updateSchemaConfig();
65
+ }
66
+
67
+ onMounted(() => {
68
+ //初始化
69
+ init();
70
+ });
71
+ // 更新(重新创建)表单单
72
+ function updateForm() {
73
+ form.value = createForm({
74
+ effects() {
75
+ onFormMount(form => {
76
+ const data = JSON.parse(
77
+ JSON.stringify(props.modelValue ?? {})
78
+ );
79
+ delete data.name;
80
+ form.setValues(data);
81
+ setTimeout(() => {
82
+ emitFlag = true;
83
+ }, 10);
84
+ });
85
+ onFormInputChange(form => {
86
+ const result = {
87
+ name: selectValue.value,
88
+ ...form.values,
89
+ };
90
+ emit('change', result);
91
+ });
92
+ },
93
+ readOnly: props.readOnly,
94
+ });
95
+ }
96
+
97
+ function init() {
98
+ if(props.modelValue?.name){
99
+ selectValue.value = props.modelValue.name;
100
+ updateSchemaConfig();
101
+ }
102
+ }
103
+
104
+ return { schemaConfig, feedbackText, form, options, selectValue, onSelectChange };
105
+ }
@@ -0,0 +1,85 @@
1
+ <template>
2
+ <div class="one-of-wrap">
3
+ <FormItem
4
+ :feedbackText="feedbackText"
5
+ feedbackStatus= "error"
6
+ :asterisk="required"
7
+ :label="title"
8
+ layout="vertical"
9
+ label-align="left"
10
+ >
11
+ <el-select
12
+ v-model="selectValue"
13
+ :suffix-icon="CaretBottom"
14
+ :disabled="readOnly"
15
+ placeholder="请选择"
16
+ @change="onSelectChange"
17
+ >
18
+ <el-option
19
+ v-for="item in options"
20
+ :key="item.value"
21
+ :label="item.label"
22
+ :value="item.value"
23
+ />
24
+ </el-select>
25
+ </FormItem>
26
+
27
+ <FormProvider :form="form">
28
+ <SchemaField :schema="schemaConfig" />
29
+ </FormProvider>
30
+ </div>
31
+ </template>
32
+
33
+ <script lang="ts" setup>
34
+ import { defineComponent } from 'vue';
35
+ import { FormProvider, createSchemaField } from '@formily/vue';
36
+ import { CaretTop, CaretBottom } from '@cicctencent/icons-vue';
37
+ import Select from '../../select';
38
+ import Input from '../../input';
39
+ import FormItem from '../../form-item';
40
+ import UploadButton from '../../upload-button';
41
+ const { SchemaField } = createSchemaField({
42
+ components: { Select, Input, FormItem, UploadButton },
43
+ });
44
+ //@ts-ignore
45
+ import useOneAny from './index';
46
+
47
+ defineComponent({
48
+ name:'OneOf'
49
+ })
50
+ const props = defineProps({
51
+ list: {
52
+ type: String,
53
+ default: () => '[]',
54
+ },
55
+ modelValue: {
56
+ type: Object,
57
+ default: () => {},
58
+ },
59
+ title: {
60
+ type: String,
61
+ default: '',
62
+ },
63
+ required: {
64
+ type: Boolean,
65
+ default: true,
66
+ },
67
+ readOnly: {
68
+ type: Boolean,
69
+ default: false,
70
+ }
71
+ });
72
+
73
+ const emits = defineEmits(['change', 'error']);
74
+
75
+ const {
76
+ schemaConfig,
77
+ form,
78
+ options,
79
+ selectValue,
80
+ onSelectChange,
81
+ feedbackText,
82
+ } = useOneAny(props, emits);
83
+ </script>
84
+
85
+ <style scoped></style>
@@ -0,0 +1,13 @@
1
+ import _Quill from 'quill';
2
+ import quillEditor from './index.vue';
3
+ const Quill = (window as any)?.Quill || _Quill;
4
+
5
+ const install = (Vue, globalOptions) => {
6
+ if (globalOptions) {
7
+ quillEditor.props.globalOptions.default = () => globalOptions;
8
+ }
9
+ Vue.component(quillEditor.name, quillEditor);
10
+ };
11
+ const VueQuillEditor = { Quill, quillEditor, install };
12
+ export default VueQuillEditor;
13
+ export { Quill, quillEditor, install };
@@ -0,0 +1,120 @@
1
+ <template>
2
+ <div class="rich-editor">
3
+ <template v-if="cmdname === 'ImportArticle'">
4
+ <div class="rich-editor--import">
5
+ <el-input placeholder="请输入公众号文章链接" v-model="importUrl"></el-input>
6
+ <el-button type="primary" link @click="handleImport" :disabled="!importUrl">导入</el-button>
7
+ </div>
8
+ </template>
9
+ <QuillEditor
10
+ theme="snow"
11
+ ref="editor"
12
+ :placeholder="modelValue ? ' ' : '请输入文本'"
13
+ @textChange="onTextChange"
14
+ :options="editorOptions"
15
+ :read-only="readOnly"
16
+ />
17
+ </div>
18
+ </template>
19
+
20
+ <script lang="ts">
21
+ import { defineComponent, ref, computed, onMounted, watch } from 'vue';
22
+ import { QuillEditor } from '@vueup/vue-quill'
23
+ import '@vueup/vue-quill/dist/vue-quill.snow.css';
24
+ import editorOptions from './options'
25
+ export default defineComponent({
26
+ name: 'rich-editor',
27
+ components: { QuillEditor },
28
+ props: {
29
+ modelValue: {
30
+ type:[String,Object],
31
+ default:''
32
+ },
33
+ cmdname:{
34
+ type: String,
35
+ default: ''
36
+ },
37
+ cmdParams:{
38
+ type:Object,
39
+ default:null
40
+ },
41
+ readOnly: {
42
+ type: Boolean,
43
+ default: false
44
+ }
45
+ },
46
+ emits: ['update:modelValue', 'change', 'selectRichImage', 'getData'],
47
+ setup(props, { emit }) {
48
+
49
+ // 导入链接
50
+ const importUrl = ref<string>();
51
+ // 富文本编辑器实例
52
+ const editor = ref();
53
+
54
+ onMounted(()=>{
55
+ editor.value.pasteHTML(props.modelValue)
56
+ })
57
+
58
+ const handleImport = () =>{
59
+ emit('getData', props.cmdname,(res)=>{
60
+ console.log("导入文章内容:",res);
61
+ emit('update:modelValue',res);
62
+ emit('change',res)
63
+ },{...props.cmdParams, url: importUrl.value })
64
+ }
65
+
66
+ watch(()=>props.modelValue,(val)=>{
67
+ if(val!== editor.value.getHTML()){
68
+ // editor.value.setHTML(val);
69
+ editor.value.pasteHTML(props.modelValue,'silent')
70
+
71
+ }
72
+ })
73
+
74
+
75
+ const onTextChange = ({delta, oldContents, source })=>{
76
+ console.log("onTextChange ",delta,oldContents,source)
77
+ console.log('onTextChange editor',editor.value.getHTML())
78
+ const html:string = editor.value.getHTML();
79
+ // 去除<p><br></p>,<h1><br></h1>.....
80
+ if(/^<([a-z,1-9]+)><br><\/\1>$/.test(html)){
81
+ emit('update:modelValue','');
82
+ emit('change','')
83
+ }
84
+ else{
85
+ emit('update:modelValue',html);
86
+ emit('change',html)
87
+ }
88
+ }
89
+
90
+ return { editor, importUrl, editorOptions, handleImport, onTextChange}
91
+ },
92
+ });
93
+ </script>
94
+
95
+ <style lang="scss">
96
+ .rich-editor {
97
+
98
+ &--import{
99
+ display: flex;
100
+ margin-bottom: 10px;
101
+ .el-button{
102
+ margin-left: 10px;
103
+ }
104
+ }
105
+
106
+ .ql-snow .ql-tooltip{
107
+ left:0 !important;
108
+ }
109
+ // min-width: 372px;
110
+ width: 100%;
111
+ .ql-toolbar {
112
+ line-height: 1.6;
113
+ }
114
+
115
+ .ql-editor {
116
+ height: 250px;
117
+ overflow-y: auto;
118
+ }
119
+ }
120
+ </style>
@@ -0,0 +1,24 @@
1
+ export default {
2
+ theme: 'snow',
3
+ boundary: document.body,
4
+ modules: {
5
+ toolbar: [
6
+ [{ header: [1, 2, 3, 4, 5, 6, false] }],
7
+ ['bold', 'italic', 'underline', 'strike'],
8
+ ['blockquote', 'code-block'],
9
+ [{ header: 1 }, { header: 2 }],
10
+ [{ list: 'ordered' }, { list: 'bullet' }],
11
+ [{ script: 'sub' }, { script: 'super' }],
12
+ [{ indent: '-1' }, { indent: '+1' }],
13
+ // [{ direction: 'rtl' }],
14
+ // [{ size: ['small', false, 'large', 'huge'] }],
15
+ [{ color: [] }, { background: [] }],
16
+ // [{ font: [] }],
17
+ [{ align: [] }],
18
+ // ['clean'],
19
+ ['link','image'],
20
+ ],
21
+ },
22
+ placeholder: 'Insert text here ...',
23
+ readOnly: false,
24
+ };
@@ -0,0 +1,106 @@
1
+ import { isEqual } from "lodash-es";
2
+ import { computed, onMounted, ref, watch } from "vue";
3
+
4
+ export default function(props,emits){
5
+
6
+ const loading = ref(false);
7
+
8
+ const optionsVal = ref([]);
9
+
10
+ const filterOptions = ref([])
11
+
12
+
13
+ const selectValue = computed(()=>{
14
+ return optionsVal.value.length ? props.modelValue : null;
15
+ })
16
+
17
+ onMounted(()=>{
18
+ if(props.cmdname){
19
+ remoteMethod('')
20
+ }else{
21
+ // 不是远程数据加载
22
+ optionsVal.value = props.options
23
+ }
24
+ })
25
+
26
+ watch(() => props.options, (newVal, oldVal)=> {
27
+ // 避免相等的时候重新赋值
28
+ if(!isEqual(newVal,oldVal)){
29
+ optionsVal.value = newVal
30
+ }
31
+ }, {deep: true})
32
+
33
+ const filter = computed(()=>{
34
+ return !!props.cmdname
35
+ })
36
+
37
+ watch(()=>props.cmdParams,(newVal,oldVal)=>{
38
+ if(!isEqual(newVal,oldVal)){
39
+ if(props.cmdname){
40
+ optionsVal.value = []
41
+ remoteMethod('')
42
+ emits('change','');
43
+ }
44
+ }
45
+ },{ deep: true})
46
+
47
+ watch(optionsVal, (options) => {
48
+ // 选项发生变化检查选项是否包含当前value
49
+ if (options.length) {
50
+ // 考虑多选的情况 是否选择了选项不包含的选项
51
+ if (props.multiple) {
52
+ if (!props.modelValue?.length) return;
53
+ // 若找不到当前value 则清空选择器
54
+ if (!props.modelValue.every(v => options.find(o => isEqual(o.value, v)) !== undefined) && props.modelValue.length) {
55
+ emits('change', []);
56
+ }
57
+ } else {
58
+ if (!props.modelValue) return;
59
+ const option = options.find(o => isEqual(o.value, props.modelValue));
60
+ // 若找不到当前value 则清空选择器
61
+ if (option === undefined && props.modelValue) {
62
+ emits('change', null);
63
+ }
64
+ }
65
+ } else {
66
+ // 选项为空时 可能为远程加载且数据还未请求到的情况 此时不将value置为空
67
+ if (!(props.cmdname && loading.value)) {
68
+ emits('change', props.multiple ? [] : null);
69
+ }
70
+ }
71
+ })
72
+
73
+ function onSelectChange(val) {
74
+ emits('change', val);
75
+ }
76
+ function remoteMethod(query: string){
77
+ loading.value = true;
78
+ emits('getData', props.cmdname,(res)=>{
79
+ loading.value = false;
80
+ optionsVal.value = res;
81
+ filterOptions.value = res;
82
+ },{...props.cmdParams,query:query })
83
+ }
84
+ /** 过滤选项 */
85
+ function filterMethod(value){
86
+ // 如果是 undefined 就返回所有 触发焦点 又失去焦点的时候, value 没编辑过会是 undefined
87
+ if(!value){
88
+ return optionsVal.value
89
+ }
90
+ filterOptions.value = optionsVal.value.filter(item => {
91
+ let isStr = typeof item?.value === 'string';
92
+ return item.label.indexOf(value) > -1 || ( isStr && item.value.indexOf(value) > -1 )
93
+ })
94
+ }
95
+ function onSelectBlur(){
96
+ // todo 失去焦点事件
97
+ }
98
+ function onVisibleChange(val){
99
+ // 下拉框出现 true 隐藏时 false
100
+ if(val){
101
+ // 初始化选项
102
+ filterOptions.value = optionsVal.value
103
+ }
104
+ }
105
+ return { onSelectChange, onSelectBlur, filterOptions, onVisibleChange, filterMethod, loading, filter, optionsVal, selectValue }
106
+ }
@@ -0,0 +1,161 @@
1
+ <template>
2
+ <div
3
+ class="formily-select"
4
+ :class="{ 'formily-select-prefix-class': prefix }"
5
+ >
6
+ <el-select
7
+ ref="selectRef"
8
+ :placeholder="placeholder"
9
+ :value-key="valueKey"
10
+ @change="onSelectChange"
11
+ @blur="onSelectBlur"
12
+ @visible-change="onVisibleChange"
13
+ :model-value="selectValue"
14
+ :multiple="multiple"
15
+ :disabled="readOnly"
16
+ :collapse-tags="collapseTags"
17
+ :loading="loading"
18
+ :filterable="filter"
19
+ :filter-method="filterMethod"
20
+ :clearable="clearable"
21
+ :size="size"
22
+ :collapse-tags-tooltip="collapseTagsTooltip"
23
+ :multiple-limit="multipleLimit"
24
+ :name="name"
25
+ :effect="effect"
26
+ :autocomplete="autocomplete"
27
+ :placement="placement"
28
+ >
29
+ <el-option
30
+ v-for="item in (filter? filterOptions : optionsVal)"
31
+ :key="item.value"
32
+ :label="item.label"
33
+ :value="item.value"
34
+ :disabled="item?.disabled || false"
35
+ />
36
+ <template #prefix v-if="prefix">
37
+ <span class="formly-select--prefix">{{ prefix }}</span>
38
+ </template>
39
+ </el-select>
40
+ </div>
41
+ </template>
42
+
43
+ <script lang="ts" setup>
44
+ //@ts-ignore
45
+ import { defineComponent, PropType } from 'vue';
46
+ //@element-plus/icons-vue
47
+ import { CaretBottom } from '@cicctencent/icons-vue';
48
+ import useSelect from './index';
49
+ const props = defineProps({
50
+ modelValue: {
51
+ type: Object,
52
+ default: '',
53
+ },
54
+ options: {
55
+ type: Object,
56
+ default: () => {
57
+ return [];
58
+ },
59
+ },
60
+ effect:{
61
+ type: String,
62
+ default: 'light'
63
+ },
64
+ collapseTagsTooltip:{
65
+ type: Boolean,
66
+ default: false
67
+ },
68
+ size:{
69
+ type: String,
70
+ default: 'default'
71
+ },
72
+ multipleLimit:{
73
+ type: Number,
74
+ default: 0
75
+ },
76
+ name:{
77
+ type: String,
78
+ default: ''
79
+ },
80
+ autocomplete:{
81
+ type: String,
82
+ default: 'off'
83
+ },
84
+ placement:{
85
+ type: String,
86
+ default: 'bottom-start'
87
+ },
88
+ // value-key
89
+ valueKey: {
90
+ type: String,
91
+ default: 'value',
92
+ },
93
+ // 后缀图标
94
+ suffixIcon: {
95
+ type: String,
96
+ default: 'CaretTop',
97
+ },
98
+ //前置文字
99
+ prefix: {
100
+ type: String,
101
+ default: '',
102
+ },
103
+ // 多选
104
+ multiple: {
105
+ type: Boolean,
106
+ default: false,
107
+ },
108
+ // 多选时是否将选中值按文字的形式展示
109
+ collapseTags: {
110
+ type: Boolean,
111
+ default: false,
112
+ },
113
+ cmdname:{
114
+ type: String,
115
+ default: ''
116
+ },
117
+ cmdParams:{
118
+ type:Object,
119
+ default:null
120
+ },
121
+ readOnly: {
122
+ type: Boolean,
123
+ default: false,
124
+ },
125
+ clearable:{
126
+ type: Boolean,
127
+ default: false
128
+ },
129
+ placeholder:{
130
+ type: String,
131
+ default: '请选择'
132
+ },
133
+ });
134
+ const emits = defineEmits(['change','getData']);
135
+
136
+
137
+ const { loading, filterOptions, selectValue, onSelectChange, onSelectBlur, onVisibleChange, filter, optionsVal, filterMethod } = useSelect(props,emits);
138
+ </script>
139
+
140
+ <style lang="scss">
141
+ .formily-select {
142
+ &-prefix-class {
143
+ .el-input__wrapper {
144
+ padding-left: 0 !important;
145
+ }
146
+ .el-input__inner {
147
+ text-align: right;
148
+ }
149
+ }
150
+ .formly-select--prefix{
151
+ color: rgba(75, 81, 94, .6);
152
+ font-weight: 400;
153
+ font-size: 14px;
154
+ line-height: 20px;
155
+ background: rgba(216, 220, 230, .2);
156
+ padding: 9px;
157
+ border-radius: 4px 0 0 4px;
158
+ border-right: 1px solid #D8DCE6;
159
+ }
160
+ }
161
+ </style>
@@ -0,0 +1,42 @@
1
+ <template>
2
+ <!-- 这是一个bug只有添加了loading disabled才能生效 -->
3
+ <el-switch
4
+ :model-value="modelValue"
5
+ :active-value="activeValue"
6
+ :inactive-value="inactiveValue"
7
+ :disabled="readOnly"
8
+ :loading="readOnly"
9
+ @change="emits('update:modelValue', $event)"
10
+ />
11
+ </template>
12
+
13
+ <script lang="ts" setup>
14
+ defineProps({
15
+ modelValue: [Boolean, String, Number],
16
+ readOnly: {
17
+ type: Boolean,
18
+ default: false,
19
+ },
20
+ activeValue: {
21
+ type: [Boolean, String, Number],
22
+ default: true,
23
+ },
24
+ inactiveValue: {
25
+ type: [Boolean, String, Number],
26
+ default: false,
27
+ },
28
+ });
29
+ const emits = defineEmits(['update:modelValue']);
30
+ </script>
31
+
32
+ <style lang="scss" scoped>
33
+ // 去掉loading的样式
34
+ :deep(.el-switch__action) {
35
+ .el-icon.is-loading {
36
+ animation: none;
37
+ svg {
38
+ display: none;
39
+ }
40
+ }
41
+ }
42
+ </style>
@@ -0,0 +1,47 @@
1
+ <template>
2
+ <div v-if="render" v-html="text" class="formily-text" :style="styles">
3
+ </div>
4
+ </template>
5
+
6
+ <script lang="ts">
7
+ // @ts-ignore
8
+ import { computed, defineComponent } from 'vue';
9
+
10
+ export default defineComponent({
11
+ props:{
12
+ text:{
13
+ type:String,
14
+ default: ''
15
+ },
16
+ color:{
17
+ type:String,
18
+ default:'#333'
19
+ }
20
+ },
21
+ setup(props){
22
+
23
+ const styles = computed(()=>{
24
+ const style = {};
25
+ if(props.color){
26
+ style['color'] = props.color;
27
+ }
28
+ return style;
29
+ })
30
+
31
+ const render = computed(()=>{
32
+ return props.text.indexOf('script') === -1 ? true : false;
33
+ })
34
+
35
+ return { styles,render }
36
+ }
37
+ })
38
+
39
+ </script>
40
+
41
+ <style lang="scss">
42
+ .formily-text{
43
+ width: 100%;
44
+ font-size: 14px;
45
+ line-height: 24px;
46
+ }
47
+ </style>