@vxe-ui/plugin-render-element 3.0.0

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.
package/package.json ADDED
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "@vxe-ui/plugin-render-element",
3
+ "version": "3.0.0",
4
+ "description": "Vxe UI plug-in for compatibility with the element-ui component.",
5
+ "scripts": {
6
+ "lib": "gulp build"
7
+ },
8
+ "files": [
9
+ "types",
10
+ "dist",
11
+ "src"
12
+ ],
13
+ "main": "dist/index.common.js",
14
+ "unpkg": "dist/index.umd.js",
15
+ "jsdelivr": "dist/index.umd.js",
16
+ "style": "dist/style.css",
17
+ "typings": "types/index.d.ts",
18
+ "devDependencies": {
19
+ "@babel/core": "^7.12.3",
20
+ "@babel/plugin-transform-runtime": "^7.12.1",
21
+ "@babel/preset-env": "^7.12.1",
22
+ "@babel/runtime": "^7.12.5",
23
+ "@typescript-eslint/eslint-plugin": "^4.6.1",
24
+ "@typescript-eslint/parser": "^4.6.1",
25
+ "browserify": "^17.0.0",
26
+ "del": "^6.0.0",
27
+ "eslint": "^7.13.0",
28
+ "eslint-config-prettier": "^6.15.0",
29
+ "eslint-config-standard": "^16.0.1",
30
+ "eslint-friendly-formatter": "^4.0.1",
31
+ "eslint-plugin-import": "^2.22.1",
32
+ "eslint-plugin-node": "^11.1.0",
33
+ "eslint-plugin-prettier": "^3.1.4",
34
+ "eslint-plugin-promise": "^4.2.1",
35
+ "eslint-plugin-standard": "^4.0.2",
36
+ "eslint-plugin-typescript": "^0.14.0",
37
+ "gulp": "^4.0.2",
38
+ "gulp-autoprefixer": "^8.0.0",
39
+ "gulp-babel": "^8.0.0",
40
+ "gulp-clean-css": "^4.3.0",
41
+ "gulp-concat": "^2.6.1",
42
+ "gulp-rename": "^2.0.0",
43
+ "gulp-replace": "^1.1.3",
44
+ "gulp-sass": "^5.1.0",
45
+ "gulp-sourcemaps": "^3.0.0",
46
+ "gulp-typescript": "^5.0.1",
47
+ "gulp-uglify": "^3.0.2",
48
+ "markdown-doctest": "^1.1.0",
49
+ "prettier": "^2.1.2",
50
+ "sass": "^1.55.0",
51
+ "typescript": "^4.6.4",
52
+ "vinyl-source-stream": "^2.0.0",
53
+ "vue": "^2.6.14",
54
+ "vxe-pc-ui": "^3.1.8",
55
+ "vxe-table": "^3.9.0-rc.15"
56
+ },
57
+ "repository": {
58
+ "type": "git",
59
+ "url": "git+https://github.com/x-extends/vxe-ui-plugins.git"
60
+ },
61
+ "keywords": [
62
+ "vxe-ui-plugins"
63
+ ],
64
+ "author": {
65
+ "name": "Xu Liangzhan",
66
+ "email": "xu_liangzhan@163.com"
67
+ },
68
+ "license": "MIT",
69
+ "bugs": {
70
+ "url": "https://github.com/x-extends/vxe-ui-plugins/issues"
71
+ },
72
+ "homepage": "https://github.com/x-extends/vxe-ui-plugins#readme"
73
+ }
@@ -0,0 +1,406 @@
1
+ import { CreateElement } from 'vue'
2
+ import XEUtils from 'xe-utils'
3
+
4
+ import type { VxeUIExport, VxeGlobalRendererHandles, VxeGlobalInterceptorHandles } from 'vxe-pc-ui'
5
+
6
+ /**
7
+ * 表单 - 渲染器
8
+ */
9
+ export function defineFormRender (VxeUI: VxeUIExport) {
10
+ function isEmptyValue (cellValue: any) {
11
+ return cellValue === null || cellValue === undefined || cellValue === ''
12
+ }
13
+
14
+ function getOnName (type: string) {
15
+ return type
16
+ }
17
+
18
+ function getModelProp (renderOpts: VxeGlobalRendererHandles.RenderOptions) {
19
+ return 'value'
20
+ }
21
+
22
+ function getModelEvent (renderOpts: VxeGlobalRendererHandles.RenderOptions) {
23
+ return 'input'
24
+ }
25
+
26
+ function getChangeEvent (renderOpts: VxeGlobalRendererHandles.RenderOptions) {
27
+ let type = 'change'
28
+ switch (renderOpts.name) {
29
+ case 'ElAutocomplete':
30
+ type = 'select'
31
+ break
32
+ case 'ElInput':
33
+ case 'ElInputNumber':
34
+ type = 'input'
35
+ break
36
+ }
37
+ return type
38
+ }
39
+
40
+ function getItemProps (renderOpts: VxeGlobalRendererHandles.RenderOptions, params: any, value: any, defaultProps?: { [prop: string]: any }) {
41
+ return XEUtils.assign({}, defaultProps, renderOpts.props, { [getModelProp(renderOpts)]: value })
42
+ }
43
+
44
+ function formatText (cellValue: any) {
45
+ return '' + (isEmptyValue(cellValue) ? '' : cellValue)
46
+ }
47
+
48
+ function getOns (renderOpts: VxeGlobalRendererHandles.RenderOptions, params: VxeGlobalRendererHandles.RenderParams, inputFunc?: Function, changeFunc?: Function) {
49
+ const { events } = renderOpts
50
+ const modelEvent = getModelEvent(renderOpts)
51
+ const changeEvent = getChangeEvent(renderOpts)
52
+ const isSameEvent = changeEvent === modelEvent
53
+ const ons: { [type: string]: Function } = {}
54
+ XEUtils.objectEach(events, (func: Function, key: string) => {
55
+ ons[getOnName(key)] = function (...args: any[]) {
56
+ func(params, ...args)
57
+ }
58
+ })
59
+ if (inputFunc) {
60
+ ons[getOnName(modelEvent)] = function (targetEvnt: any) {
61
+ inputFunc(targetEvnt)
62
+ if (events && events[modelEvent]) {
63
+ events[modelEvent](params, targetEvnt)
64
+ }
65
+ if (isSameEvent && changeFunc) {
66
+ changeFunc(targetEvnt)
67
+ }
68
+ }
69
+ }
70
+ if (!isSameEvent && changeFunc) {
71
+ ons[getOnName(changeEvent)] = function (...args: any[]) {
72
+ changeFunc(...args)
73
+ if (events && events[changeEvent]) {
74
+ events[changeEvent](params, ...args)
75
+ }
76
+ }
77
+ }
78
+ return ons
79
+ }
80
+
81
+ function getItemOns (renderOpts: VxeGlobalRendererHandles.RenderOptions, params: any) {
82
+ const { $form, data, field } = params
83
+ return getOns(renderOpts, params, (value: any) => {
84
+ // 处理 model 值双向绑定
85
+ XEUtils.set(data, field, value)
86
+ }, () => {
87
+ // 处理 change 事件相关逻辑
88
+ $form.updateStatus(params)
89
+ })
90
+ }
91
+
92
+ function renderOptions (h: CreateElement, options: any[], optionProps: VxeGlobalRendererHandles.RenderOptionProps) {
93
+ const labelProp = optionProps.label || 'label'
94
+ const valueProp = optionProps.value || 'value'
95
+ return XEUtils.map(options, (item, oIndex) => {
96
+ return h('el-option', {
97
+ key: oIndex,
98
+ props: {
99
+ value: item[valueProp],
100
+ label: item[labelProp],
101
+ disabled: item.disabled
102
+ }
103
+ })
104
+ })
105
+ }
106
+
107
+ function cellText (cellValue: any): string[] {
108
+ return [formatText(cellValue)]
109
+ }
110
+
111
+ function createFormItemRender (defaultProps?: { [key: string]: any }) {
112
+ return function (h: CreateElement, renderOpts: VxeGlobalRendererHandles.RenderItemContentOptions & { name: string }, params: any) {
113
+ const { data, field } = params
114
+ const { name } = renderOpts
115
+ const { attrs } = renderOpts
116
+ const itemValue = XEUtils.get(data, field)
117
+ return [
118
+ h(name, {
119
+ attrs,
120
+ props: {
121
+ ...getItemProps(renderOpts, params, itemValue, defaultProps)
122
+ },
123
+ on: getItemOns(renderOpts, params)
124
+ })
125
+ ]
126
+ }
127
+ }
128
+
129
+ function defaultButtonItemRender (h: CreateElement, renderOpts: VxeGlobalRendererHandles.RenderItemContentOptions, params: any) {
130
+ const { attrs } = renderOpts
131
+ const props = getItemProps(renderOpts, params, null)
132
+ return [
133
+ h('el-button', {
134
+ attrs,
135
+ props: {
136
+ ...props
137
+ },
138
+ on: getOns(renderOpts, params),
139
+ scopedSlots: {
140
+ default: () => cellText(renderOpts.content || props.content)
141
+ }
142
+ })
143
+ ]
144
+ }
145
+
146
+ function defaultButtonsItemRender (h: CreateElement, renderOpts: VxeGlobalRendererHandles.RenderItemContentOptions, params: any) {
147
+ const { children } = renderOpts
148
+ if (children) {
149
+ return children.map((childRenderOpts: VxeGlobalRendererHandles.RenderItemContentOptions) => defaultButtonItemRender(h, childRenderOpts, params)[0])
150
+ }
151
+ return []
152
+ }
153
+
154
+ /**
155
+ * 已废弃
156
+ * @deprecated
157
+ */
158
+ function createOldFormItemRadioAndCheckboxRender () {
159
+ return function (h: CreateElement, renderOpts: VxeGlobalRendererHandles.RenderItemContentOptions & { name: string }, params: any) {
160
+ const { name, options = [], optionProps = {}, attrs } = renderOpts
161
+ const { data, field } = params
162
+ const labelProp = optionProps.label || 'label'
163
+ const valueProp = optionProps.value || 'value'
164
+ const itemValue = XEUtils.get(data, field)
165
+ return [
166
+ h(`${name}Group`, {
167
+ attrs,
168
+ props: {
169
+ ...getItemProps(renderOpts, params, itemValue)
170
+ },
171
+ on: getItemOns(renderOpts, params),
172
+ scopedSlots: {
173
+ default: () => {
174
+ return options.map((option, oIndex) => {
175
+ return h(name, {
176
+ key: oIndex,
177
+ props: {
178
+ label: option[valueProp],
179
+ disabled: option.disabled
180
+ },
181
+ scopedSlots: {
182
+ default: () => cellText(option[labelProp])
183
+ }
184
+ })
185
+ })
186
+ }
187
+ }
188
+ })
189
+ ]
190
+ }
191
+ }
192
+
193
+ /**
194
+ * 检查触发源是否属于目标节点
195
+ */
196
+ function getEventTargetNode (evnt: any, container: HTMLElement, className: string) {
197
+ let targetElem
198
+ let target = evnt.target
199
+ while (target && target.nodeType && target !== document) {
200
+ if (className && target.className && target.className.split && target.className.split(' ').indexOf(className) > -1) {
201
+ targetElem = target
202
+ } else if (target === container) {
203
+ return { flag: className ? !!targetElem : true, container, targetElem: targetElem }
204
+ }
205
+ target = target.parentNode
206
+ }
207
+ return { flag: false }
208
+ }
209
+
210
+ /**
211
+ * 事件兼容性处理
212
+ */
213
+ function handleClearEvent (params: VxeGlobalInterceptorHandles.InterceptorClearFilterParams | VxeGlobalInterceptorHandles.InterceptorClearEditParams | VxeGlobalInterceptorHandles.InterceptorClearAreasParams) {
214
+ const { $event } = params
215
+ const bodyElem = document.body
216
+ if (
217
+ // 远程搜索
218
+ getEventTargetNode($event, bodyElem, 'el-autocomplete-suggestion').flag ||
219
+ // 下拉框
220
+ getEventTargetNode($event, bodyElem, 'el-select-dropdown').flag ||
221
+ // 级联
222
+ getEventTargetNode($event, bodyElem, 'el-cascader__dropdown').flag ||
223
+ getEventTargetNode($event, bodyElem, 'el-cascader-menus').flag ||
224
+ // 日期
225
+ getEventTargetNode($event, bodyElem, 'el-time-panel').flag ||
226
+ getEventTargetNode($event, bodyElem, 'el-picker-panel').flag ||
227
+ // 颜色
228
+ getEventTargetNode($event, bodyElem, 'el-color-dropdown').flag
229
+ ) {
230
+ return false
231
+ }
232
+ }
233
+
234
+ VxeUI.renderer.mixin({
235
+ ElAutocomplete: {
236
+ renderFormItemContent: createFormItemRender()
237
+ },
238
+ ElInput: {
239
+ renderFormItemContent: createFormItemRender()
240
+ },
241
+ ElInputNumber: {
242
+ renderFormItemContent: createFormItemRender()
243
+ },
244
+ ElSelect: {
245
+ renderFormItemContent (h, renderOpts, params) {
246
+ const { options = [], optionGroups, optionProps = {}, optionGroupProps = {} } = renderOpts
247
+ const { data, field } = params
248
+ const { attrs } = renderOpts
249
+ const itemValue = XEUtils.get(data, field)
250
+ const props = getItemProps(renderOpts, params, itemValue)
251
+ const ons = getItemOns(renderOpts, params)
252
+ if (optionGroups) {
253
+ const groupOptions = optionGroupProps.options || 'options'
254
+ const groupLabel = optionGroupProps.label || 'label'
255
+ return [
256
+ h('el-select', {
257
+ attrs,
258
+ props: {
259
+ ...props
260
+ },
261
+ on: ons,
262
+ scopedSlots: {
263
+ default: () => {
264
+ return XEUtils.map(optionGroups, (group, gIndex) => {
265
+ return h('el-option-group', {
266
+ key: gIndex,
267
+ props: {
268
+ label: group[groupLabel]
269
+ },
270
+ scopedSlots: {
271
+ default: () => renderOptions(h, group[groupOptions], optionProps)
272
+ }
273
+ })
274
+ })
275
+ }
276
+ }
277
+ })
278
+ ]
279
+ }
280
+ return [
281
+ h('el-select', {
282
+ attrs,
283
+ props: {
284
+ ...props
285
+ },
286
+ on: ons,
287
+ scopedSlots: {
288
+ default: () => renderOptions(h, options, optionProps)
289
+ }
290
+ })
291
+ ]
292
+ }
293
+ },
294
+ ElCascader: {
295
+ renderFormItemContent: createFormItemRender()
296
+ },
297
+ ElDatePicker: {
298
+ renderFormItemContent: createFormItemRender()
299
+ },
300
+ ElTimePicker: {
301
+ renderFormItemContent: createFormItemRender()
302
+ },
303
+ ElTimeSelect: {
304
+ renderFormItemContent: createFormItemRender()
305
+ },
306
+ ElRate: {
307
+ renderFormItemContent: createFormItemRender()
308
+ },
309
+ ElSwitch: {
310
+ renderFormItemContent: createFormItemRender()
311
+ },
312
+ ElSlider: {
313
+ renderFormItemContent: createFormItemRender()
314
+ },
315
+ ElRadioGroup: {
316
+ renderFormItemContent (h, renderOpts, params) {
317
+ const { options = [], optionProps = {}, attrs } = renderOpts
318
+ const { data, field } = params
319
+ const labelProp = optionProps.label || 'label'
320
+ const valueProp = optionProps.value || 'value'
321
+ const itemValue = XEUtils.get(data, field)
322
+ return [
323
+ h('el-radio-group', {
324
+ attrs,
325
+ props: {
326
+ ...getItemProps(renderOpts, params, itemValue)
327
+ },
328
+ on: {
329
+ ...getItemOns(renderOpts, params)
330
+ },
331
+ scopedSlots: {
332
+ default: () => {
333
+ return options.map((option, oIndex) => {
334
+ return h('el-radio', {
335
+ key: oIndex,
336
+ props: {
337
+ value: option[valueProp],
338
+ disabled: option.disabled
339
+ },
340
+ scopedSlots: {
341
+ default: () => cellText(option[labelProp])
342
+ }
343
+ })
344
+ })
345
+ }
346
+ }
347
+ })
348
+ ]
349
+ }
350
+ },
351
+ ElCheckboxGroup: {
352
+ renderFormItemContent (h, renderOpts, params) {
353
+ const { options = [], optionProps = {}, attrs } = renderOpts
354
+ const { data, field } = params
355
+ const labelProp = optionProps.label || 'label'
356
+ const valueProp = optionProps.value || 'value'
357
+ const itemValue = XEUtils.get(data, field)
358
+ return [
359
+ h('el-checkbox-group', {
360
+ attrs,
361
+ props: {
362
+ ...getItemProps(renderOpts, params, itemValue)
363
+ },
364
+ on: {
365
+ ...getItemOns(renderOpts, params)
366
+ },
367
+ scopedSlots: {
368
+ default: () => {
369
+ return options.map((option, oIndex) => {
370
+ return h('el-checkbox', {
371
+ key: oIndex,
372
+ props: {
373
+ value: option[valueProp],
374
+ label: option[labelProp],
375
+ disabled: option.disabled
376
+ }
377
+ })
378
+ })
379
+ }
380
+ }
381
+ })
382
+ ]
383
+ }
384
+ },
385
+ ElButton: {
386
+ renderFormItemContent: defaultButtonItemRender
387
+ },
388
+
389
+ // 已废弃
390
+ ElRadio: {
391
+ renderFormItemContent: createOldFormItemRadioAndCheckboxRender()
392
+ },
393
+ ElCheckbox: {
394
+ renderFormItemContent: createOldFormItemRadioAndCheckboxRender()
395
+ },
396
+ ElButtons: {
397
+ renderFormItemContent: defaultButtonsItemRender
398
+ }
399
+ })
400
+
401
+ VxeUI.interceptor.add('event.clearFilter', handleClearEvent)
402
+ VxeUI.interceptor.add('event.clearEdit', handleClearEvent)
403
+ VxeUI.interceptor.add('event.clearAreas', handleClearEvent)
404
+ // 兼容老版本
405
+ VxeUI.interceptor.add('event.clearActived', handleClearEvent)
406
+ }
package/src/index.ts ADDED
@@ -0,0 +1,76 @@
1
+ import { defineTableRender } from './table'
2
+ import { defineFormRender } from './form'
3
+
4
+ import type { VxeUIPluginObject, VxeGlobalInterceptorHandles } from 'vxe-pc-ui'
5
+
6
+ // eslint-disable-next-line no-unused-vars
7
+ let ElementPlus: any
8
+
9
+ /**
10
+ * 检查触发源是否属于目标节点
11
+ */
12
+ function getEventTargetNode (evnt: any, container: HTMLElement, className: string) {
13
+ let targetElem
14
+ let target = evnt.target
15
+ while (target && target.nodeType && target !== document) {
16
+ if (className && target.className && target.className.split && target.className.split(' ').indexOf(className) > -1) {
17
+ targetElem = target
18
+ } else if (target === container) {
19
+ return { flag: className ? !!targetElem : true, container, targetElem: targetElem }
20
+ }
21
+ target = target.parentNode
22
+ }
23
+ return { flag: false }
24
+ }
25
+
26
+ /**
27
+ * 事件兼容性处理
28
+ */
29
+ function handleClearEvent (params: VxeGlobalInterceptorHandles.InterceptorClearFilterParams | VxeGlobalInterceptorHandles.InterceptorClearEditParams | VxeGlobalInterceptorHandles.InterceptorClearAreasParams) {
30
+ const { $event } = params
31
+ const bodyElem = document.body
32
+ if (
33
+ // 远程搜索
34
+ getEventTargetNode($event, bodyElem, 'el-autocomplete-suggestion').flag ||
35
+ // 下拉框
36
+ getEventTargetNode($event, bodyElem, 'el-select-dropdown').flag ||
37
+ // 级联
38
+ getEventTargetNode($event, bodyElem, 'el-cascader__dropdown').flag ||
39
+ getEventTargetNode($event, bodyElem, 'el-cascader-menus').flag ||
40
+ // 日期
41
+ getEventTargetNode($event, bodyElem, 'el-time-panel').flag ||
42
+ getEventTargetNode($event, bodyElem, 'el-picker-panel').flag ||
43
+ // 颜色
44
+ getEventTargetNode($event, bodyElem, 'el-color-dropdown').flag
45
+ ) {
46
+ return false
47
+ }
48
+ }
49
+
50
+ export const VxeUIPluginRenderElement: VxeUIPluginObject = {
51
+ install (VxeUI, options?: {
52
+ ElementPlus?: any
53
+ }) {
54
+ ElementPlus = options ? options.ElementPlus : {}
55
+
56
+ // 检查版本
57
+ if (!/^(3)\./.test(VxeUI.uiVersion)) {
58
+ console.error('[plugin-render-element 3.x] Version 3.x is required')
59
+ }
60
+
61
+ defineTableRender(VxeUI)
62
+ defineFormRender(VxeUI)
63
+
64
+ VxeUI.interceptor.add('event.clearFilter', handleClearEvent)
65
+ VxeUI.interceptor.add('event.clearEdit', handleClearEvent)
66
+ VxeUI.interceptor.add('event.clearAreas', handleClearEvent)
67
+ // 兼容老版本
68
+ VxeUI.interceptor.add('event.clearActived', handleClearEvent)
69
+ }
70
+ }
71
+
72
+ if (typeof window !== 'undefined' && window.VxeUI && window.VxeUI.use) {
73
+ window.VxeUI.use(VxeUIPluginRenderElement)
74
+ }
75
+
76
+ export default VxeUIPluginRenderElement