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,460 @@
1
+ <script>
2
+ import { isComponent, isVNode } from "utils";
3
+ import Comp from "./comp.vue";
4
+ import {
5
+ cloneDeep,
6
+ isFunction,
7
+ isPlainObject,
8
+ merge,
9
+ get,
10
+ set,
11
+ } from "lodash-es";
12
+ import { mergeTemp } from "utils/mergeTemp";
13
+ import { defaultRender as _defaultRender } from "core";
14
+ import DictMixin from "../dict/mixin";
15
+ import position from "./position.vue";
16
+ import { isEmptyData, resolveRender } from "utils";
17
+ import {
18
+ getComponentConfig,
19
+ generateMockData,
20
+ generateCustomMockData,
21
+ } from "../mock/index";
22
+ export default {
23
+ name: "render",
24
+ props: {
25
+ value: {},
26
+ prop: {
27
+ type: String,
28
+ default: "",
29
+ },
30
+ comp: [Object, Function],
31
+ render: Function,
32
+ item: Object,
33
+ raw: Object, // 未加工的item
34
+ slots: Object,
35
+ mode: [String, Boolean],
36
+ scope: {},
37
+ size: String,
38
+ controlDefault: Function, // 控制已有的默认渲染
39
+ defaultRender: Function, // 自定义默认渲染
40
+ position: Boolean, // 是否渲染位置
41
+ compStrategy: Array, // 渲染策略
42
+ commonCompStrategy: Object, // 公共组件策略
43
+ defaultComp: Object, // 默认组件
44
+ rawRules: Array, // 未加工的rules
45
+ strategies: Object, // 策略
46
+ },
47
+ inject: {
48
+ controlCtx: { default: undefined },
49
+ elForm: {
50
+ default: "",
51
+ },
52
+ },
53
+ mixins: [DictMixin],
54
+ computed: {
55
+ $value: {
56
+ get() {
57
+ try {
58
+ const input = this.item.formatData?.input;
59
+ if (input) return input(this.getRow(), this.scope);
60
+ return this.getRow();
61
+ } catch (error) {
62
+ console.error("获取格式化值失败:", error);
63
+ return this.getRow();
64
+ }
65
+ },
66
+ set(value) {
67
+ try {
68
+ this.setFormatValue(value);
69
+ } catch (error) {
70
+ console.error("设置格式化值失败:", error);
71
+ this.setRow(this.prop, value);
72
+ }
73
+ },
74
+ },
75
+ },
76
+ created() {
77
+ if (this.item.formatData) {
78
+ setTimeout(() => {
79
+ this.isSettingValue = false;
80
+ this.$watch("value", (val) => {
81
+ // 防止重复触发
82
+ if (this.isSettingValue) return;
83
+ this.setFormatValue(this.$value);
84
+ });
85
+ this.setFormatValue(this.$value);
86
+ }, 0);
87
+ }
88
+ if (this.compStrategy) {
89
+ this.matcher = this.createMatcher(this.compStrategy);
90
+ }
91
+ if (this.controlCtx) {
92
+ this.setupMockDataListener();
93
+ }
94
+ },
95
+ mounted() {
96
+ if (this.item.ref && typeof this.item.ref === "function") {
97
+ this.item.ref(this.$vnode.componentInstance);
98
+ }
99
+ },
100
+ destroyed() {
101
+ if (this.controlCtx && this.mockDataListener) {
102
+ this.controlCtx.$off("mockData", this.mockDataListener);
103
+ this.mockDataListener = null;
104
+ }
105
+ },
106
+ methods: {
107
+ setupMockDataListener() {
108
+ this.mockDataListener = () => {
109
+ if (
110
+ (this.elForm || {}).disabled ||
111
+ (!isEmptyData(this.$value) && this.$value !== 0)
112
+ )
113
+ return;
114
+ const config = this.getComponentConfig();
115
+ if (config && config.disabled) return;
116
+ if (this.item.mock) {
117
+ const mockValue = generateCustomMockData(this.item.mock, this.scope);
118
+ mockValue && this.setFormatValue(mockValue);
119
+ return;
120
+ }
121
+
122
+ const mockValue = generateMockData(config, {
123
+ pattern: this.getPattern(),
124
+ });
125
+ !isEmptyData(mockValue) && this.setFormatValue(mockValue);
126
+ };
127
+
128
+ this.controlCtx.$on("mockData", this.mockDataListener);
129
+ },
130
+ getComponentConfig() {
131
+ return getComponentConfig(this.$vnode);
132
+ },
133
+ getPattern() {
134
+ const rules = this.rawRules;
135
+ if (rules) {
136
+ const pattern = rules.find((rule) => rule.regular);
137
+ if (pattern) return pattern.regular;
138
+ }
139
+ },
140
+ getRow() {
141
+ if (!this.prop) return this.scope.row;
142
+ return get(this.scope.row, this.prop);
143
+ },
144
+ // 设置行数据
145
+ setRow(prop, val) {
146
+ if (!prop) {
147
+ this.$set(this.scope, "row", val);
148
+ return;
149
+ }
150
+ // 处理数组路径 ['a', 'b'] 或字符串路径 'a.b'
151
+ const path = Array.isArray(prop) ? prop : prop.split(".");
152
+ if (path.length > 1) {
153
+ if (!get(this.scope.row, path)) {
154
+ // 绑定深层响应式对象
155
+ path.slice(0, -1).reduce((obj, key, index) => {
156
+ // 如果当前key值不存在,创建一个新响应式对象
157
+ if (!obj[key] || typeof obj[key] !== "object") {
158
+ this.$set(obj, key, {});
159
+ }
160
+ return obj[key];
161
+ }, this.scope.row);
162
+
163
+ // 获取最后一层的父对象
164
+ const parentObj = path
165
+ .slice(0, -1)
166
+ .reduce((obj, key) => obj[key], this.scope.row);
167
+
168
+ this.$set(parentObj, path[path.length - 1], val);
169
+ } else {
170
+ set(this.scope.row, path, val);
171
+ this.$set(this.scope.row, path[0], this.scope.row[path[0]]);
172
+ }
173
+ } else {
174
+ // 触发响应式更新
175
+ this.$set(this.scope.row, prop, val);
176
+ }
177
+ },
178
+ setFormatValue(value) {
179
+ const output = this.item.formatData?.output;
180
+ if (output) {
181
+ this.isSettingValue = true; // 设置标志
182
+ const outputValue = output(value, this.scope, this.setRow);
183
+ const formatValueProp = get(this.item, ["formatData", "formatValue"]);
184
+ if (formatValueProp && typeof formatValueProp === "string") {
185
+ this.setRow(formatValueProp, value);
186
+ } else if (formatValueProp) {
187
+ this.setRow("$" + this.prop, value);
188
+ }
189
+ if (outputValue !== undefined) {
190
+ this.setRow(this.prop, outputValue);
191
+ }
192
+ this.$nextTick(() => {
193
+ this.isSettingValue = false; // 重置标志
194
+ });
195
+ } else {
196
+ this.setRow(this.prop, value);
197
+ }
198
+ },
199
+ interruptibleCompose(...funcs) {
200
+ return funcs.reduce((f1, f2) => {
201
+ return function (...args) {
202
+ var result = f1.apply(this, args);
203
+ return result ? result : f2.apply(this, args);
204
+ };
205
+ });
206
+ },
207
+ getSlot(h, scope) {
208
+ const slots = this.slots;
209
+ const prop = this.prop;
210
+ const mode = this.mode;
211
+ if (isFunction(slots)) slots = slots();
212
+ if (slots) {
213
+ let slotName;
214
+ if (prop && mode) {
215
+ slotName = `${prop}-${mode}`;
216
+ } else if (prop && !mode) {
217
+ slotName = prop;
218
+ } else if (!prop && mode) {
219
+ slotName = mode;
220
+ }
221
+ const slot = slots[slotName];
222
+ if (slot) return slot(scope);
223
+ }
224
+ },
225
+ getRender(h, scope) {
226
+ return resolveRender(this.render, h, scope);
227
+ },
228
+ // 合并一个函数和一个对象(或两个函数)
229
+ mergeFunctionAndObject(t, s, scope) {
230
+ if (!s) {
231
+ if (isFunction(t)) return t(scope);
232
+ return t;
233
+ }
234
+ if (isFunction(t) && isFunction(s))
235
+ return Object.assign(s(scope), t(scope));
236
+ if (isFunction(t) && isPlainObject(s)) return Object.assign(s, t(scope));
237
+ if (isPlainObject(t) && isFunction(s)) return Object.assign(s(scope), t);
238
+ return t;
239
+ },
240
+ createMatcher(strategies) {
241
+ const exactMatches = new Map();
242
+ const suffixMatches = new Map();
243
+ const functionMatches = [];
244
+ strategies.forEach(({ rule, comp }) => {
245
+ if (typeof rule === "string") {
246
+ if (rule.startsWith("*")) {
247
+ suffixMatches.set(rule.slice(1).toLowerCase(), comp);
248
+ } else {
249
+ exactMatches.set(rule, comp);
250
+ }
251
+ } else if (typeof rule === "function") {
252
+ functionMatches.push({ rule, comp });
253
+ }
254
+ });
255
+ return (name, comp, scope) => {
256
+ if (typeof name === "string") {
257
+ // 精确匹配
258
+ const exactMatch = exactMatches.get(name);
259
+ if (exactMatch) return exactMatch;
260
+
261
+ // 后缀匹配
262
+ const nameLower = name.toLowerCase();
263
+ for (const [suffix, comp] of suffixMatches) {
264
+ if (nameLower.endsWith(suffix)) {
265
+ return comp;
266
+ }
267
+ }
268
+ }
269
+ // 函数匹配
270
+ if (isFunction(name)) {
271
+ return functionMatches.find(({ rule }) => rule(name, comp, scope))
272
+ ?.comp;
273
+ }
274
+ };
275
+ },
276
+ getComponent(h, scope) {
277
+ if (this.comp || this.defaultComp) {
278
+ let comp = this.comp || this.defaultComp;
279
+ comp =
280
+ typeof comp === "string" || isComponent(comp)
281
+ ? { name: comp }
282
+ : this.mergeFunctionAndObject(comp, this.raw?.comp, scope);
283
+ if (this.compStrategy) {
284
+ const strategy = this.matcher(
285
+ isComponent(comp.name) ? comp.name.name : comp.name,
286
+ comp,
287
+ scope
288
+ );
289
+ if (strategy || this.commonCompStrategy) {
290
+ comp = merge(comp, this.commonCompStrategy, strategy);
291
+ }
292
+ }
293
+ return (
294
+ <Comp
295
+ props={{ ...comp, comp }}
296
+ prop={this.prop}
297
+ size={this.size}
298
+ scope={scope}
299
+ />
300
+ );
301
+ }
302
+ },
303
+ getDefaultRender(h, scope) {
304
+ if (this.$scopedSlots.default) {
305
+ return this.$scopedSlots.default(scope);
306
+ }
307
+ if (isFunction(this.defaultRender)) {
308
+ return this.defaultRender(h, scope);
309
+ }
310
+ if (this.controlDefault) {
311
+ const renderFunc = this.controlDefault(_defaultRender, scope);
312
+ const VNode = renderFunc && renderFunc(h, scope);
313
+ if (VNode) return VNode;
314
+ }
315
+ return _defaultRender.formatter(h, scope);
316
+ },
317
+ applyComponentSpecificModifications(vnode, scope) {
318
+ if (!vnode) return vnode;
319
+
320
+ // 从虚拟DOM中获取组件名称
321
+ let compName;
322
+ if (vnode.componentOptions && vnode.componentOptions.Ctor) {
323
+ compName =
324
+ vnode.componentOptions.Ctor.options.name ||
325
+ (vnode.componentOptions.tag || "").toLowerCase();
326
+ }
327
+
328
+ // 如果无法获取组件名称,则返回原始vnode
329
+ if (!compName) return vnode;
330
+
331
+ // 如果提供了组件特定的修改配置
332
+ if (this.strategies) {
333
+ const modifier = this.strategies[compName];
334
+
335
+ // 如果没有精确匹配,尝试后缀匹配
336
+ let matchedModifier = modifier;
337
+ if (!matchedModifier) {
338
+ const compNameLower = compName.toLowerCase();
339
+ // 查找所有以*开头的键,表示后缀匹配
340
+ for (const key in this.strategies) {
341
+ if (
342
+ key.startsWith("*") &&
343
+ compNameLower.endsWith(key.slice(1).toLowerCase())
344
+ ) {
345
+ matchedModifier = this.strategies[key];
346
+ break;
347
+ }
348
+ }
349
+ }
350
+
351
+ if (typeof matchedModifier === "function") {
352
+ // 允许通过函数完全控制VNode的修改
353
+ return matchedModifier(vnode, scope, this);
354
+ } else if (matchedModifier && typeof matchedModifier === "object") {
355
+ // 应用预定义的修改
356
+ if (matchedModifier.props && vnode.componentOptions) {
357
+ vnode.componentOptions.propsData = {
358
+ ...vnode.componentOptions.propsData,
359
+ ...(typeof matchedModifier.props === "function"
360
+ ? matchedModifier.props(scope)
361
+ : matchedModifier.props),
362
+ };
363
+ }
364
+
365
+ // 添加或修改事件
366
+ if (matchedModifier.on && vnode.componentOptions) {
367
+ vnode.componentOptions.listeners =
368
+ vnode.componentOptions.listeners || {};
369
+ Object.entries(matchedModifier.on).forEach(([event, handler]) => {
370
+ const originalHandler = vnode.componentOptions.listeners[event];
371
+ vnode.componentOptions.listeners[event] = originalHandler
372
+ ? (...args) => {
373
+ originalHandler(...args);
374
+ handler(...args, scope, this);
375
+ }
376
+ : (...args) => handler(...args, scope, this);
377
+ });
378
+ }
379
+
380
+ // 添加或修改样式
381
+ if (matchedModifier.style && vnode.data) {
382
+ vnode.data.style = {
383
+ ...(vnode.data.style || {}),
384
+ ...(typeof matchedModifier.style === "function"
385
+ ? matchedModifier.style(scope)
386
+ : matchedModifier.style),
387
+ };
388
+ }
389
+
390
+ // 添加或修改类名
391
+ if (matchedModifier.class && vnode.data) {
392
+ const newClass =
393
+ typeof matchedModifier.class === "function"
394
+ ? matchedModifier.class(scope)
395
+ : matchedModifier.class;
396
+
397
+ if (Array.isArray(vnode.data.class)) {
398
+ vnode.data.class = [
399
+ ...vnode.data.class,
400
+ ...(Array.isArray(newClass) ? newClass : [newClass]),
401
+ ];
402
+ } else if (typeof vnode.data.class === "object") {
403
+ vnode.data.class = { ...vnode.data.class, ...newClass };
404
+ } else {
405
+ vnode.data.class = newClass;
406
+ }
407
+ }
408
+
409
+ // 添加或修改属性
410
+ if (matchedModifier.attrs && vnode.data) {
411
+ vnode.data.attrs = {
412
+ ...(vnode.data.attrs || {}),
413
+ ...(typeof matchedModifier.attrs === "function"
414
+ ? matchedModifier.attrs(scope)
415
+ : matchedModifier.attrs),
416
+ };
417
+ }
418
+ }
419
+ }
420
+
421
+ return vnode;
422
+ },
423
+ },
424
+ render(h) {
425
+ const chains = this.interruptibleCompose(
426
+ this.getSlot,
427
+ this.getRender,
428
+ this.getComponent,
429
+ this.getDefaultRender
430
+ );
431
+ const VNode = chains(h, {
432
+ ...this.scope,
433
+ item: this.item,
434
+ mode: this.mode,
435
+ dict: this.dictData,
436
+ self: this,
437
+ $value: {
438
+ get: this.$value,
439
+ set: this.setFormatValue,
440
+ },
441
+ });
442
+
443
+ if (this.position) {
444
+ return (
445
+ <position
446
+ slotName={this.prop}
447
+ slots={this.slots}
448
+ scope={this.scope}
449
+ style={{
450
+ width: "100%",
451
+ }}
452
+ >
453
+ {VNode}
454
+ </position>
455
+ );
456
+ }
457
+ return VNode;
458
+ },
459
+ };
460
+ </script>