vue-super-crud 1.7.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 (291) hide show
  1. package/.browserslistrc +3 -0
  2. package/.versionrc.json +36 -0
  3. package/CHANGELOG.md +232 -0
  4. package/LICENSE +201 -0
  5. package/README.md +46 -0
  6. package/babel.config.js +12 -0
  7. package/build/alias.js +10 -0
  8. package/build/build.js +52 -0
  9. package/build/config.js +70 -0
  10. package/deploy.bat +14 -0
  11. package/docs/.vuepress/components/button/base.vue +88 -0
  12. package/docs/.vuepress/components/common/code-format.vue +331 -0
  13. package/docs/.vuepress/components/commonConfig/presetCodeTemplate/base.vue +68 -0
  14. package/docs/.vuepress/components/commonConfig/presetCodeTemplate/customParams.vue +73 -0
  15. package/docs/.vuepress/components/commonConfig/renderType/component.vue +160 -0
  16. package/docs/.vuepress/components/commonConfig/renderType/formatter.vue +49 -0
  17. package/docs/.vuepress/components/commonConfig/renderType/render.vue +91 -0
  18. package/docs/.vuepress/components/commonConfig/renderType/slot.vue +63 -0
  19. package/docs/.vuepress/components/crud/baseUse/baseUse.vue +98 -0
  20. package/docs/.vuepress/components/crud/baseUse/columnAction.vue +72 -0
  21. package/docs/.vuepress/components/crud/baseUse/columnWidth.vue +107 -0
  22. package/docs/.vuepress/components/crud/baseUse/handleRow.vue +65 -0
  23. package/docs/.vuepress/components/crud/baseUse/height.vue +82 -0
  24. package/docs/.vuepress/components/crud/baseUse/index.vue +54 -0
  25. package/docs/.vuepress/components/crud/baseUse/loading.vue +70 -0
  26. package/docs/.vuepress/components/crud/baseUse/pagination.vue +108 -0
  27. package/docs/.vuepress/components/crud/baseUse/selection.vue +114 -0
  28. package/docs/.vuepress/components/crud/baseUse/summaryMethod.vue +118 -0
  29. package/docs/.vuepress/components/crud/baseUse/title.vue +54 -0
  30. package/docs/.vuepress/components/crud/baseUse/toolbar.vue +69 -0
  31. package/docs/.vuepress/components/crud/buttons/common.vue +115 -0
  32. package/docs/.vuepress/components/crud/buttons/fast.vue +82 -0
  33. package/docs/.vuepress/components/crud/contextMenu/base.vue +72 -0
  34. package/docs/.vuepress/components/crud/copy.vue +52 -0
  35. package/docs/.vuepress/components/crud/crudEvents/api.vue +157 -0
  36. package/docs/.vuepress/components/crud/crudEvents/deleteTip.vue +93 -0
  37. package/docs/.vuepress/components/crud/crudEvents/events.vue +188 -0
  38. package/docs/.vuepress/components/crud/dataSort/base.vue +142 -0
  39. package/docs/.vuepress/components/crud/genDynamicColumns/base.vue +53 -0
  40. package/docs/.vuepress/components/crud/genDynamicColumns/dynamicAndFixed.vue +111 -0
  41. package/docs/.vuepress/components/crud/genDynamicColumns/treeDynamic.vue +68 -0
  42. package/docs/.vuepress/components/crud/handleBar/handleRow.vue +65 -0
  43. package/docs/.vuepress/components/crud/handleBar/toolbar.vue +69 -0
  44. package/docs/.vuepress/components/crud/renderType/1.vue +57 -0
  45. package/docs/.vuepress/components/crud/renderType/2.vue +63 -0
  46. package/docs/.vuepress/components/crud/renderType/3.vue +105 -0
  47. package/docs/.vuepress/components/crud/renderType/5.vue +91 -0
  48. package/docs/.vuepress/components/crud/search/1.vue +90 -0
  49. package/docs/.vuepress/components/crud/search/2.vue +78 -0
  50. package/docs/.vuepress/components/crud/search/3.vue +107 -0
  51. package/docs/.vuepress/components/crud/search/base.vue +123 -0
  52. package/docs/.vuepress/components/crud/search/localSearch.vue +124 -0
  53. package/docs/.vuepress/components/crud/search/special.vue +148 -0
  54. package/docs/.vuepress/components/crud/selection/events.vue +47 -0
  55. package/docs/.vuepress/components/crud/selection/pagination.vue +94 -0
  56. package/docs/.vuepress/components/crud/selection/singleSelection.vue +64 -0
  57. package/docs/.vuepress/components/crud/span/base.vue +69 -0
  58. package/docs/.vuepress/components/crud/span/special.vue +75 -0
  59. package/docs/.vuepress/components/crud/summary/base.vue +99 -0
  60. package/docs/.vuepress/components/crud/tableEdit/addDeleteBtn.vue +174 -0
  61. package/docs/.vuepress/components/crud/tableEdit/cellEdit.vue +194 -0
  62. package/docs/.vuepress/components/crud/tableEdit/controlEdit.vue +219 -0
  63. package/docs/.vuepress/components/crud/tableEdit/dialog.vue +172 -0
  64. package/docs/.vuepress/components/crud/tableEdit/free.vue +88 -0
  65. package/docs/.vuepress/components/crud/tableEdit/freeColumn.vue +82 -0
  66. package/docs/.vuepress/components/crud/tableEdit/methods.vue +154 -0
  67. package/docs/.vuepress/components/crud/tableEdit/rowAction.vue +107 -0
  68. package/docs/.vuepress/components/crud/tableEdit/rowBatch.vue +116 -0
  69. package/docs/.vuepress/components/crud/tableEdit/rowClick.vue +98 -0
  70. package/docs/.vuepress/components/crud/validate/base.vue +122 -0
  71. package/docs/.vuepress/components/crud/validate/custom.vue +82 -0
  72. package/docs/.vuepress/components/crud/validate/regulars.vue +88 -0
  73. package/docs/.vuepress/components/crud/validate/relation.vue +91 -0
  74. package/docs/.vuepress/components/crud/validate/tree.vue +82 -0
  75. package/docs/.vuepress/components/dialog/baseUse/base.vue +92 -0
  76. package/docs/.vuepress/components/dialog/baseUse/beforeConfirm.vue +78 -0
  77. package/docs/.vuepress/components/dialog/baseUse/control.vue +79 -0
  78. package/docs/.vuepress/components/dialog/baseUse/drawer.vue +59 -0
  79. package/docs/.vuepress/components/dialog/baseUse/footer.vue +87 -0
  80. package/docs/.vuepress/components/dialog/baseUse/insertSlot.vue +79 -0
  81. package/docs/.vuepress/components/dict/DictLinkage.vue +91 -0
  82. package/docs/.vuepress/components/dict/baseUse.vue +72 -0
  83. package/docs/.vuepress/components/dict/component.vue +82 -0
  84. package/docs/.vuepress/components/dict/localDict.vue +68 -0
  85. package/docs/.vuepress/components/form/baseUse/base.vue +48 -0
  86. package/docs/.vuepress/components/form/baseUse/dataFormat.vue +92 -0
  87. package/docs/.vuepress/components/form/baseUse/deep.vue +57 -0
  88. package/docs/.vuepress/components/form/baseUse/gridLayout.vue +47 -0
  89. package/docs/.vuepress/components/form/baseUse/group.vue +66 -0
  90. package/docs/.vuepress/components/form/baseUse/hidden.vue +40 -0
  91. package/docs/.vuepress/components/form/baseUse/inlineLayout.vue +48 -0
  92. package/docs/.vuepress/components/form/baseUse/label.vue +51 -0
  93. package/docs/.vuepress/components/form/baseUse/tooltip.vue +40 -0
  94. package/docs/.vuepress/components/form/baseUse/validate.vue +52 -0
  95. package/docs/.vuepress/components/form/detail/base.vue +78 -0
  96. package/docs/.vuepress/components/form/detail/border.vue +90 -0
  97. package/docs/.vuepress/components/form/detail/singleDetail.vue +72 -0
  98. package/docs/.vuepress/components/formatData/baseUse.vue +131 -0
  99. package/docs/.vuepress/components/mock/index.js +347 -0
  100. package/docs/.vuepress/components/mockData/custom.vue +69 -0
  101. package/docs/.vuepress/components/mockData/example.vue +290 -0
  102. package/docs/.vuepress/components/positionSlot/base.vue +24 -0
  103. package/docs/.vuepress/components/positionSlot/form.vue +71 -0
  104. package/docs/.vuepress/components/positionSlot/table.vue +85 -0
  105. package/docs/.vuepress/components/tabs/base.vue +57 -0
  106. package/docs/.vuepress/components/temp.js +195 -0
  107. package/docs/.vuepress/config.js +146 -0
  108. package/docs/.vuepress/enhanceApp.js +142 -0
  109. package/docs/.vuepress/public/favicon.ico +0 -0
  110. package/docs/.vuepress/public/super.png +0 -0
  111. package/docs/.vuepress/styles/index.styl +25 -0
  112. package/docs/.vuepress/styles/palette.styl +6 -0
  113. package/docs/README.md +14 -0
  114. package/docs/guide/button/base.md +31 -0
  115. package/docs/guide/commonConfig/jsx.md +166 -0
  116. package/docs/guide/commonConfig/presetCodeTemplate.md +68 -0
  117. package/docs/guide/commonConfig/renderType.md +181 -0
  118. package/docs/guide/crud/baseUse.md +120 -0
  119. package/docs/guide/crud/buttons.md +18 -0
  120. package/docs/guide/crud/config.md +217 -0
  121. package/docs/guide/crud/contextMenu.md +18 -0
  122. package/docs/guide/crud/dataSort.md +66 -0
  123. package/docs/guide/crud/genDynamicColumns.md +145 -0
  124. package/docs/guide/crud/handleBar.md +26 -0
  125. package/docs/guide/crud/renderType.md +4 -0
  126. package/docs/guide/crud/search.md +150 -0
  127. package/docs/guide/crud/selection.md +73 -0
  128. package/docs/guide/crud/span.md +98 -0
  129. package/docs/guide/crud/summary.md +167 -0
  130. package/docs/guide/crud/tableEdit.md +377 -0
  131. package/docs/guide/crud/validate.md +158 -0
  132. package/docs/guide/dialog/baseUse.md +81 -0
  133. package/docs/guide/dict/baseUse.md +174 -0
  134. package/docs/guide/dict/component.md +88 -0
  135. package/docs/guide/dict/config.md +44 -0
  136. package/docs/guide/form/baseUse.md +142 -0
  137. package/docs/guide/form/detail.md +38 -0
  138. package/docs/guide/formatData/baseUse.md +98 -0
  139. package/docs/guide/formatData/config.md +142 -0
  140. package/docs/guide/mockData/base.md +26 -0
  141. package/docs/guide/positionSlot/base.md +41 -0
  142. package/docs/guide/question/base.md +44 -0
  143. package/docs/guide/start/base.md +30 -0
  144. package/docs/guide/tabs/base.md +63 -0
  145. package/examples/App.vue +52 -0
  146. package/examples/Layout/components/AppMain.vue +40 -0
  147. package/examples/Layout/components/Item.vue +29 -0
  148. package/examples/Layout/components/Link.vue +44 -0
  149. package/examples/Layout/components/SidebarItem.vue +93 -0
  150. package/examples/Layout/index.vue +69 -0
  151. package/examples/assets/logo.png +0 -0
  152. package/examples/favicon.ico +0 -0
  153. package/examples/index.html +18 -0
  154. package/examples/main.js +54 -0
  155. package/examples/router/index.js +140 -0
  156. package/examples/store/index.js +0 -0
  157. package/examples/styles/index.scss +63 -0
  158. package/examples/styles/sidebar.scss +226 -0
  159. package/examples/styles/transition.scss +48 -0
  160. package/examples/styles/variables.scss +25 -0
  161. package/examples/views/crud/base.vue +68 -0
  162. package/examples/views/crud/handleRow.vue +84 -0
  163. package/examples/views/crud/search.vue +116 -0
  164. package/examples/views/dashboard/index.vue +244 -0
  165. package/examples/views/dashboard/index1.vue +234 -0
  166. package/examples/views/dashboard/test.vue +9 -0
  167. package/examples/views/formTest/index.vue +168 -0
  168. package/examples/views/nested/menu1/index.vue +7 -0
  169. package/examples/views/nested/menu1/menu1-1/index.vue +7 -0
  170. package/examples/views/nested/menu1/menu1-2/index.vue +7 -0
  171. package/examples/views/nested/menu1/menu1-2/menu1-2-1/index.vue +5 -0
  172. package/examples/views/nested/menu1/menu1-2/menu1-2-2/index.vue +5 -0
  173. package/examples/views/nested/menu1/menu1-3/index.vue +5 -0
  174. package/examples/views/nested/menu2/index.vue +5 -0
  175. package/gulpfile.js +84 -0
  176. package/lib/index.css +1 -0
  177. package/lib/super-crud.min.js +15 -0
  178. package/package.json +66 -0
  179. package/packages/button/index.vue +189 -0
  180. package/packages/core/components/comp.vue +223 -0
  181. package/packages/core/components/position.vue +135 -0
  182. package/packages/core/components/render.vue +460 -0
  183. package/packages/core/configManager.js +302 -0
  184. package/packages/core/create.js +8 -0
  185. package/packages/core/defaultRender.js +64 -0
  186. package/packages/core/dict/global.js +10 -0
  187. package/packages/core/dict/index.js +432 -0
  188. package/packages/core/dict/mixin.js +94 -0
  189. package/packages/core/event.js +60 -0
  190. package/packages/core/index.js +6 -0
  191. package/packages/core/init.js +122 -0
  192. package/packages/core/mock/genConfig.js +228 -0
  193. package/packages/core/mock/genData.js +422 -0
  194. package/packages/core/mock/index.js +4 -0
  195. package/packages/core/rules.js +111 -0
  196. package/packages/crud/column.vue +205 -0
  197. package/packages/crud/columnAction.vue +207 -0
  198. package/packages/crud/columnCell.vue +146 -0
  199. package/packages/crud/defaultColumn.vue +130 -0
  200. package/packages/crud/drawerColumn.vue +225 -0
  201. package/packages/crud/form.vue +69 -0
  202. package/packages/crud/index.vue +564 -0
  203. package/packages/crud/menuBar.vue +298 -0
  204. package/packages/crud/mixins/cacheHandler.js +36 -0
  205. package/packages/crud/mixins/calcColumnWidth.js +79 -0
  206. package/packages/crud/mixins/calcHeight.js +105 -0
  207. package/packages/crud/mixins/columnHandler.js +128 -0
  208. package/packages/crud/mixins/contextMenu.js +98 -0
  209. package/packages/crud/mixins/dataProcessor.js +202 -0
  210. package/packages/crud/mixins/dialog.js +109 -0
  211. package/packages/crud/mixins/excelHandler.js +150 -0
  212. package/packages/crud/mixins/exposeMethods.js +107 -0
  213. package/packages/crud/mixins/generateDynamicColumns.js +250 -0
  214. package/packages/crud/mixins/props.js +38 -0
  215. package/packages/crud/mixins/searchHandler.js +151 -0
  216. package/packages/crud/mixins/select.js +359 -0
  217. package/packages/crud/mixins/spanMethod.js +288 -0
  218. package/packages/crud/mixins/summary.js +177 -0
  219. package/packages/crud/mixins/tableEdit.js +547 -0
  220. package/packages/crud/mixins/validate.js +219 -0
  221. package/packages/crud/pagination.vue +110 -0
  222. package/packages/crud/search.vue +119 -0
  223. package/packages/crud/searchHeader.vue +231 -0
  224. package/packages/crud/selectBanner.vue +138 -0
  225. package/packages/crud/utils/EditState.js +319 -0
  226. package/packages/crud/utils/excelExport.js +112 -0
  227. package/packages/crud/utils/excelImport.js +112 -0
  228. package/packages/crud/utils/index.js +98 -0
  229. package/packages/dialog/dialog.js +233 -0
  230. package/packages/dialog/dialog.vue +15 -0
  231. package/packages/dialog/index.js +22 -0
  232. package/packages/dict/cascadeFormat.vue +179 -0
  233. package/packages/dict/dateFormat.vue +40 -0
  234. package/packages/dict/form/cascade.vue +61 -0
  235. package/packages/dict/form/checkbox.vue +90 -0
  236. package/packages/dict/form/extendMethod.js +22 -0
  237. package/packages/dict/form/input-base.js +31 -0
  238. package/packages/dict/form/input.js +20 -0
  239. package/packages/dict/form/radio.vue +69 -0
  240. package/packages/dict/form/select.vue +118 -0
  241. package/packages/dict/form/switch.vue +75 -0
  242. package/packages/dict/valueFormat.vue +188 -0
  243. package/packages/directive/dialog/drag.js +86 -0
  244. package/packages/directive/dialog/dragSize.js +42 -0
  245. package/packages/directive/index.js +9 -0
  246. package/packages/directive/insertSlot.js +10 -0
  247. package/packages/form/contextMenu.js +192 -0
  248. package/packages/form/draftDrawer.vue +391 -0
  249. package/packages/form/formAction.vue +97 -0
  250. package/packages/form/formItem.vue +259 -0
  251. package/packages/form/index.vue +451 -0
  252. package/packages/form/props.js +15 -0
  253. package/packages/grid/cell.vue +65 -0
  254. package/packages/grid/index.vue +130 -0
  255. package/packages/group/index.vue +96 -0
  256. package/packages/tabs/index.vue +290 -0
  257. package/packages/tooltip/index.js +9 -0
  258. package/packages/tooltip/tooltip.vue +32 -0
  259. package/packages/tooltip/tooltipComponent.js +38 -0
  260. package/packages/verifyInput/index.vue +131 -0
  261. package/src/config/common.js +88 -0
  262. package/src/config/crud.js +567 -0
  263. package/src/config/dialog.js +87 -0
  264. package/src/config/form.js +215 -0
  265. package/src/config/index.js +9 -0
  266. package/src/constants/index.js +72 -0
  267. package/src/index.js +67 -0
  268. package/src/template/btn/crud.js +6 -0
  269. package/src/template/btn/dialog.js +1 -0
  270. package/src/template/btn/form.js +3 -0
  271. package/src/template/btn/index.js +9 -0
  272. package/src/template/dicts.js +1 -0
  273. package/src/template/formatData.js +507 -0
  274. package/src/template/index.js +19 -0
  275. package/src/template/render.js +124 -0
  276. package/src/template/rules.js +53 -0
  277. package/src/utils/bem.js +49 -0
  278. package/src/utils/cache.js +77 -0
  279. package/src/utils/getType.js +34 -0
  280. package/src/utils/index.js +212 -0
  281. package/src/utils/mergeTemp.js +124 -0
  282. package/styles/button.scss +3 -0
  283. package/styles/crud.scss +425 -0
  284. package/styles/dialog.scss +95 -0
  285. package/styles/form.scss +532 -0
  286. package/styles/group.scss +78 -0
  287. package/styles/index.scss +94 -0
  288. package/styles/tabs.scss +139 -0
  289. package/styles/verifyInput.scss +56 -0
  290. package/vue-jsx-sync.js +90 -0
  291. package/vue.config.js +54 -0
@@ -0,0 +1,451 @@
1
+ <template>
2
+ <div
3
+ :class="[
4
+ b(),
5
+ { 'sc-form--border': isDetail && isBorder, 'sc-form--group': isGroup },
6
+ ]"
7
+ :style="{ padding: formOptions.gap }"
8
+ @contextmenu="handleContextMenu"
9
+ >
10
+ <div style="min-height: 0; position: relative;">
11
+ <position
12
+ slotName="title"
13
+ :render="formOptions.titleRender"
14
+ :slots="$scopedSlots"
15
+ ><div v-if="formOptions.title" class="sc-title">
16
+ {{ formOptions.title }}
17
+ </div></position
18
+ >
19
+ <el-form
20
+ v-loading="isLoading"
21
+ :disabled="isDisabled"
22
+ ref="formRef"
23
+ :model="value"
24
+ v-bind="formProps"
25
+ :key="key"
26
+ @submit.native.prevent
27
+ >
28
+ <template v-if="isGroup">
29
+ <group
30
+ v-for="(item, index) in columns"
31
+ v-bind="item"
32
+ :key="index"
33
+ :border="!isBorder"
34
+ >
35
+ <component
36
+ v-if="item.children"
37
+ :is="formOptions.layout"
38
+ v-bind="item"
39
+ :style="{ padding: `0 ${item.gap}px` }"
40
+ >
41
+ <formItem
42
+ v-for="(i, idx) in item.children"
43
+ :key="idx"
44
+ :col="i"
45
+ v-bind="i"
46
+ :is-first-row="idx <= firstRowLastCellIndex[index]"
47
+ :ref="i.prop"
48
+ ></formItem
49
+ ></component>
50
+ <position
51
+ v-else
52
+ :slotName="item.prop"
53
+ :render="item.render"
54
+ :slots="slots"
55
+ :scope="formScope"
56
+ />
57
+ </group>
58
+ <formAction />
59
+ </template>
60
+ <component
61
+ v-else
62
+ :is="formOptions.layout"
63
+ v-bind="formOptions"
64
+ :style="{ padding: `0 ${formOptions.gap}px` }"
65
+ >
66
+ <formItem
67
+ v-for="(item, index) in columns"
68
+ :key="index"
69
+ :col="item"
70
+ v-bind="item"
71
+ :is-first-row="index <= firstRowLastCellIndex"
72
+ :ref="item.prop"
73
+ ></formItem
74
+ ><formAction
75
+ /></component>
76
+ </el-form>
77
+ </div>
78
+ <draftDrawer ref="draftDrawer" />
79
+ </div>
80
+ </template>
81
+
82
+ <script>
83
+ // TODO 详情模式:增加 detail 配置详情单独渲染的组件
84
+ // TODO 提交清除hidden 字段
85
+ import { create, init, event } from "core";
86
+ import formItem from "./formItem.vue";
87
+ import grid from "../grid/index.vue";
88
+ import cell from "pak/grid/cell.vue";
89
+ import group from "../group/index.vue";
90
+ import formAction from "./formAction.vue";
91
+ import draftDrawer from "./draftDrawer.vue";
92
+ import contextMenu from "./contextMenu";
93
+ import {
94
+ isFunction,
95
+ isPlainObject,
96
+ uniqueId,
97
+ set,
98
+ get,
99
+ cloneDeep,
100
+ merge,
101
+ omit,
102
+ pick,
103
+ } from "lodash-es";
104
+ import { mergeTemp } from "utils/mergeTemp";
105
+ import { isEmptyData, toCamelCase, filterColumns } from "utils";
106
+ import position from "core/components/position";
107
+ import formProps from "./props";
108
+
109
+ // 表单初始化队列
110
+ const formInitQueue = {
111
+ promise: Promise.resolve(),
112
+ isProcessing: false, // 添加标记表示队列是否正在处理
113
+ add(callback) {
114
+ this.isProcessing = true;
115
+ const currentPromise = this.promise.then(async () => {
116
+ try {
117
+ await callback();
118
+ } catch (error) {
119
+ console.error("Form init error:", error);
120
+ } finally {
121
+ // 检查是否还有待处理的 promise
122
+ if (this.promise === currentPromise) {
123
+ this.isProcessing = false;
124
+ }
125
+ }
126
+ });
127
+ this.promise = currentPromise;
128
+ return currentPromise;
129
+ },
130
+ };
131
+ export default create({
132
+ name: "form",
133
+ components: {
134
+ grid,
135
+ cell,
136
+ group,
137
+ formItem,
138
+ formAction,
139
+ position,
140
+ draftDrawer,
141
+ },
142
+ props: {
143
+ value: {
144
+ type: Object,
145
+ default: () => {
146
+ return {};
147
+ },
148
+ },
149
+ scope: {
150
+ type: Object,
151
+ default: () => {
152
+ return {};
153
+ },
154
+ },
155
+ loading: {
156
+ type: Boolean,
157
+ },
158
+ },
159
+ provide() {
160
+ return {
161
+ formCtx: this,
162
+ controlCtx: this,
163
+ };
164
+ },
165
+ mixins: [init("formOptions"), event, contextMenu],
166
+ data() {
167
+ return {
168
+ key: 1,
169
+ loadingStatus: false,
170
+ formBind: {},
171
+ isInitializing: false, // 添加初始化状态标记
172
+ };
173
+ },
174
+ created() {
175
+ this.initFormValue();
176
+ },
177
+ mounted() {
178
+ this.extendMethod(this.$refs.formRef);
179
+ },
180
+ computed: {
181
+ formOptions() {
182
+ return this.resultOptions;
183
+ },
184
+ isGroup() {
185
+ return this.formOptions.group || this.formOptions.group === "";
186
+ },
187
+ isDetail() {
188
+ return this.formOptions.detail || this.formOptions.detail === "";
189
+ },
190
+ isBorder() {
191
+ return this.formOptions.border || this.formOptions.border === "";
192
+ },
193
+ isDisabled() {
194
+ return this.isDetail || this.loadingStatus || this.formOptions.disabled;
195
+ },
196
+ isLoading() {
197
+ if (this.isDetail) return this.loadingStatus;
198
+ return false;
199
+ },
200
+ columns() {
201
+ return this.groupBy(filterColumns(this.resultColumns, this.formScope));
202
+ },
203
+ trueRenderColumns() {
204
+ let columns = [];
205
+ this.columns.forEach((item) => {
206
+ if (item.children) {
207
+ columns.push(...item.children);
208
+ } else {
209
+ columns.push(item);
210
+ }
211
+ });
212
+ return columns;
213
+ },
214
+ columnsMap() {
215
+ const map = {};
216
+ this.trueRenderColumns.forEach((i) => {
217
+ map[i.prop] = i;
218
+ });
219
+ return map;
220
+ },
221
+ formScope() {
222
+ const baseScope = {
223
+ row: this.value,
224
+ form: this.$refs.formRef,
225
+ };
226
+
227
+ if (!this.scope) return baseScope;
228
+
229
+ return {
230
+ ...this.scope,
231
+ ...baseScope,
232
+ };
233
+ },
234
+ slots() {
235
+ return this.formOptions.slots || this.$scopedSlots;
236
+ },
237
+ layoutCell() {
238
+ if (this.formOptions.layout === "grid") {
239
+ return "cell";
240
+ }
241
+ if (this.formOptions.layout === "el-row") {
242
+ return "el-col";
243
+ }
244
+ },
245
+ firstRowLastCellIndex() {
246
+ if (this.isGroup) {
247
+ const map = this.columns.reduce((acc, cur, index) => {
248
+ acc[index] = this.getFirstRowLastCellIndex(cur.children, cur.columns);
249
+ return acc;
250
+ }, {});
251
+ return map || {};
252
+ }
253
+ return this.getFirstRowLastCellIndex(
254
+ this.columns,
255
+ this.formOptions.columns
256
+ );
257
+ },
258
+ formProps() {
259
+ const obj = {};
260
+ Object.keys(this.formOptions).forEach((key) => {
261
+ obj[toCamelCase(key)] = this.formOptions[key];
262
+ });
263
+ const props = pick(obj, formProps);
264
+ return props;
265
+ },
266
+ },
267
+ watch: {
268
+ value() {
269
+ // value重新赋值时需要再初始化
270
+ if (!this.isInitializing && !formInitQueue.isProcessing) {
271
+ this.initFormValue();
272
+ }
273
+ },
274
+ loading: {
275
+ handler(val) {
276
+ val !== undefined && (this.loadingStatus = val);
277
+ },
278
+ immediate: true,
279
+ },
280
+ loadingStatus(val) {
281
+ this.$emit("update:loading", val);
282
+ },
283
+ },
284
+ methods: {
285
+ initColumn(item, index) {
286
+ if (item.detail) {
287
+ item.detail = this.extendsOption(
288
+ item,
289
+ item.detail,
290
+ omit(item, ["detail"])
291
+ );
292
+ }
293
+ },
294
+ extendsOption(item, current, extendsObj) {
295
+ if (current === false) return;
296
+ // current 可能为 undefined || true 转换为 {}
297
+ current = isPlainObject(current) ? current : {};
298
+ current = mergeTemp("render", current.presetType, current);
299
+ extendsObj = cloneDeep(extendsObj);
300
+ if (current.hidden !== true) {
301
+ return merge(
302
+ {
303
+ label: item.label,
304
+ prop: item.prop,
305
+ ...extendsObj,
306
+ },
307
+ current
308
+ );
309
+ }
310
+ },
311
+ //初始化表单
312
+ async initFormValue() {
313
+ if (this.isInitializing) return;
314
+
315
+ // 将初始化操作添加到队列
316
+ await formInitQueue.add(async () => {
317
+ this.isInitializing = true;
318
+
319
+ try {
320
+ // 确保获取最新的 value
321
+ await this.$nextTick();
322
+ let form = { ...this.value };
323
+
324
+ this.trueRenderColumns.forEach((col) => {
325
+ if (form[col.prop] === undefined) {
326
+ if (col.initValue) {
327
+ form[col.prop] = col.initValue;
328
+ } else {
329
+ form[col.prop] = "";
330
+ }
331
+ }
332
+ });
333
+
334
+ this.setControl();
335
+
336
+ // 发出更新事件
337
+ this.$emit("input", form);
338
+
339
+ // 等待更新完成
340
+ await this.$nextTick();
341
+ this.clearValidate();
342
+ } finally {
343
+ this.isInitializing = false;
344
+ }
345
+ });
346
+ },
347
+ setControl() {
348
+ this.trueRenderColumns.forEach((column) => {
349
+ let prop = column.prop;
350
+ let bind = column.deepProp;
351
+ if (!this.formBind[prop]) {
352
+ let bindList = [];
353
+ if (bind) {
354
+ // 实际与表单绑定的值还是浅层的值,通过watch,浅层的值改变会修改深层,深层改变也会修改浅层
355
+ let formProp = this.$watch("value." + prop, (n, o) => {
356
+ if (n != o) set(this.value, bind, n);
357
+ });
358
+ let formDeep = this.$watch("value." + bind, (n, o) => {
359
+ if (n != o) this.$set(this.value, prop, n);
360
+ });
361
+ bindList.push(formProp);
362
+ bindList.push(formDeep);
363
+ this.$set(this.value, prop, get(this.value, bind));
364
+ }
365
+ this.formBind[prop] = bindList;
366
+ }
367
+ });
368
+ },
369
+ groupBy(column) {
370
+ let group = this.formOptions.group;
371
+
372
+ if (group && Array.isArray(group)) {
373
+ return group.map((item) => {
374
+ return {
375
+ label: item.label,
376
+ children: item.children.map((i) => {
377
+ return column.find((c) => c.prop === i);
378
+ }),
379
+ };
380
+ });
381
+ }
382
+ return column;
383
+ },
384
+ validate(callBack) {
385
+ return new Promise((resolve, reject) => {
386
+ this.$refs.formRef.validate((valid, obj) => {
387
+ if (!valid) {
388
+ reject(obj);
389
+ callBack && callBack(false);
390
+ if (this.formOptions.scrollError) {
391
+ const key = Object.keys(obj)[0];
392
+ const itemRef =
393
+ this.$refs[key] && this.$refs[key][0].$refs.formItem;
394
+ if (Object.keys(obj).length && itemRef) {
395
+ itemRef.$el.scrollIntoView({
396
+ behavior: "smooth",
397
+ block: "center",
398
+ });
399
+ }
400
+ }
401
+ } else {
402
+ callBack && callBack(true);
403
+ resolve();
404
+ }
405
+ });
406
+ });
407
+ },
408
+ async submit() {
409
+ await this.validate();
410
+ this.loadingStatus = true;
411
+ this.runBefore(
412
+ "submit",
413
+ () => {
414
+ this.loadingStatus = false;
415
+ },
416
+ this.value
417
+ );
418
+ },
419
+ resetField(prop) {
420
+ // 通知子组件执行重置
421
+ this.$emit("handleChild", "resetField", prop);
422
+ },
423
+ reset() {
424
+ this.$refs.formRef && this.$refs.formRef.resetFields();
425
+ this.$emit("reset");
426
+ },
427
+ clearValidate(prop) {
428
+ this.$refs.formRef && this.$refs.formRef.clearValidate(prop);
429
+ },
430
+ validateField(prop) {
431
+ this.$refs.formRef && this.$refs.formRef.validateField(prop);
432
+ },
433
+ refreshForm() {
434
+ const tempValue = cloneDeep(this.value);
435
+ this.$emit("input", {});
436
+ this.key = Math.random();
437
+ setTimeout(() => {
438
+ this.$emit("input", tempValue);
439
+ }, 100);
440
+ },
441
+ getFirstRowLastCellIndex(columns = [], columnsNumber = 1) {
442
+ let widthSize = 0;
443
+ const lastIndex = columns.findIndex((item, idx) => {
444
+ widthSize += item.widthSize || 1;
445
+ return widthSize === columnsNumber;
446
+ });
447
+ return lastIndex === -1 ? columns.length - 1 : lastIndex;
448
+ },
449
+ },
450
+ });
451
+ </script>
@@ -0,0 +1,15 @@
1
+ export default [
2
+ "model",
3
+ "rules",
4
+ "labelPosition",
5
+ "labelWidth",
6
+ "labelSuffix",
7
+ "inline",
8
+ "inlineMessage",
9
+ "statusIcon",
10
+ "showMessage",
11
+ "size",
12
+ "disabled",
13
+ "validateOnRuleChange",
14
+ "hideRequiredAsterisk",
15
+ ];
@@ -0,0 +1,65 @@
1
+ <template>
2
+ <div :class="b()" :style="mergeStyle">
3
+ <slot></slot>
4
+ </div>
5
+ </template>
6
+
7
+ <script>
8
+ import create from "core/create";
9
+ export default create({
10
+ inheritAttrs: false,
11
+ name: "cell",
12
+ props: {
13
+ widthSize: {
14
+ type: [Number, String],
15
+ default: 1,
16
+ },
17
+ heightSize: {
18
+ type: [Number, String],
19
+ default: 1,
20
+ },
21
+ area: {},
22
+ center: {},
23
+ left: {},
24
+ top: {},
25
+ center: {},
26
+ cellStyle: {
27
+ type: Object,
28
+ default: () => ({}),
29
+ },
30
+ },
31
+ computed: {
32
+ mergeStyle() {
33
+ return {
34
+ height: "100%",
35
+ minWidth: 0,
36
+ gridArea: this.area || "auto",
37
+ gridColumnEnd: `span ${this.widthSize}`, // 使用 grid-column-end 属性设置网格元素跨越多少列,或者在哪一列结束。
38
+ gridRowEnd: `span ${this.heightSize}`, // grid-row-start 属性指定哪一行开始显示网格元素
39
+ gridColumnStart: this.left, // grid-column-start 属性定义了网格元素从哪一列开始
40
+ gridRowStart: this.top, // grid-row-end 属性指定哪一行停止显示网格元素,或设置跨越多少行
41
+ textAlign:
42
+ this.center !== undefined && this.center !== null && "center",
43
+ ...this.middleStyle(this.center),
44
+ boxSizing: "border-box",
45
+ ...this.$attrs,
46
+ ...this.cellStyle,
47
+ };
48
+ },
49
+ },
50
+ methods: {
51
+ middleStyle(center) {
52
+ if (center !== undefined && center !== null) {
53
+ return {
54
+ display: "inline-flex",
55
+ flexFlow: "column wrap",
56
+ justifyContent: "center",
57
+ justifySelf: "stretch",
58
+ };
59
+ }
60
+ },
61
+ },
62
+ });
63
+ </script>
64
+
65
+ <style></style>
@@ -0,0 +1,130 @@
1
+ <template>
2
+ <div :class="b()" :style="mergeStyle">
3
+ <slot></slot>
4
+ </div>
5
+ </template>
6
+
7
+ <script>
8
+ import create from "core/create";
9
+ import { setPx, setPxSaveSource } from "utils";
10
+ export default create({
11
+ inheritAttrs: false,
12
+ name: "grid",
13
+ props: {
14
+ columns: {
15
+ type: Number,
16
+ default: 1,
17
+ },
18
+ autoFill: [Boolean, String],
19
+ fillCell: Boolean,
20
+ minColumns: Number,
21
+ maxColumns: Number,
22
+ columnWidth: [String, Number],
23
+ minColumnWidth: [String, Number],
24
+ maxColumnWidth: [String, Number],
25
+ gap: {}, // 防止覆盖column-gap
26
+ columnGap: {},
27
+ rowGap: {},
28
+ areas: {},
29
+ minRowHeight: [String, Number],
30
+ maxRowHeight: [String, Number],
31
+ alignContent: {},
32
+ rows: {},
33
+ justifyContent: {},
34
+ flow: {},
35
+ height: { default: "auto" },
36
+ gridStyle: {
37
+ type: Object,
38
+ default: () => ({}),
39
+ },
40
+ },
41
+ computed: {
42
+ mergeStyle() {
43
+ return {
44
+ display: "grid", // 布局是grid布局
45
+ height: this.height, // 设置容器高度
46
+ gridAutoFlow: this.fillCell ? "row dense" : this.flow, // 设置容器内元素是从左往右(默认),还是从右往左
47
+ gridAutoRows: this.autoRows(), // grid-auto-rows设置默认单元格高度
48
+ gridTemplateRows: this.frGetter(this.rows), // 当传递一个数字时,它是指定行数的简写,平分高度,自适应。如果是例如100px,就是以这个数值为宽度
49
+ gridTemplateColumns: this.gridTemplateColumns,
50
+ areas: this.formatAreas(this.areas), // 传递一个字符串数组,例如 [“a a”,“b c”]。 默认不提供。
51
+ justifyContent: this.justifyContent, // 决定整个内容区域在容器里面的水平位置(左中右)
52
+ columnGap: this.columnGap,
53
+ rowGap: this.rowGap,
54
+ alignContent: this.alignContent, // 决定整个内容区域的垂直位置(上中下)
55
+ ...this.$attrs,
56
+ ...this.gridStyle,
57
+ };
58
+ },
59
+ gridTemplateColumns() {
60
+ // 处理自动填充模式
61
+ if (this.autoFill) {
62
+ const columnWidth = this.getAutoFillColumnWidth();
63
+ const autoFill = this.autoFill === "autoFit" ? "auto-fit" : "auto-fill";
64
+ return this.getAutoFillTemplate(autoFill, columnWidth);
65
+ }
66
+
67
+ // 处理固定列数模式
68
+ return this.getFixedColumnsTemplate();
69
+ },
70
+ },
71
+ methods: {
72
+ getAutoFillColumnWidth() {
73
+ if (this.autoFill === "fixedWidth") {
74
+ return setPx(this.columnWidth || "300px");
75
+ }
76
+ return `minmax(${setPx(this.columnWidth || "300px")}, 1fr)`;
77
+ },
78
+ getAutoFillTemplate(autoFill, columnWidth) {
79
+ if (this.minColumns && this.maxColumns) {
80
+ return `repeat(max(${this.minColumns}, min(${this.maxColumns}, ${autoFill})), ${columnWidth})`;
81
+ }
82
+ if (this.minColumns) {
83
+ return `repeat(max(${this.minColumns}, ${autoFill}), ${columnWidth})`;
84
+ }
85
+ if (this.maxColumns) {
86
+ return `repeat(min(${this.maxColumns}, ${autoFill}), ${columnWidth})`;
87
+ }
88
+ return `repeat(${autoFill}, ${columnWidth})`;
89
+ },
90
+
91
+ getFixedColumnsTemplate() {
92
+ if (this.columnWidth) {
93
+ return `repeat(${this.columns}, ${setPx(this.columnWidth)})`;
94
+ }
95
+ if (this.minColumnWidth && this.maxColumnWidth) {
96
+ return `repeat(${this.columns}, minmax(${setPx(
97
+ this.minColumnWidth
98
+ )}, ${setPx(this.maxColumnWidth)}))`;
99
+ }
100
+ if (this.minColumnWidth) {
101
+ return `repeat(${this.columns}, minmax(${setPx(
102
+ this.minColumnWidth
103
+ )}, 1fr))`;
104
+ }
105
+ if (this.maxColumnWidth) {
106
+ return `repeat(${this.columns}, minmax(200px, ${setPx(
107
+ this.maxColumnWidth
108
+ )}))`;
109
+ }
110
+ return `repeat(${this.columns}, 1fr)`;
111
+ },
112
+ autoRows() {
113
+ return `minmax(${setPx(this.minRowHeight)}, ${setPxSaveSource(
114
+ this.maxRowHeight || "auto"
115
+ )})`;
116
+ },
117
+ frGetter(value) {
118
+ if (!value) return;
119
+ return typeof value === "number" ? `repeat(${value}, 1fr)` : value;
120
+ },
121
+ formatAreas(areas) {
122
+ if (!areas) return;
123
+ if (typeof areas === "string") return areas;
124
+ return areas.map((area) => `"${area}"`).join(" ");
125
+ },
126
+ },
127
+ });
128
+ </script>
129
+
130
+ <style></style>