resolver-egretimp-plus 0.1.124 → 0.1.126

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "resolver-egretimp-plus",
3
- "version": "0.1.124",
3
+ "version": "0.1.126",
4
4
  "description": "交付体验渲染",
5
5
  "main": "./dist/web/index.js",
6
6
  "module": "./dist/web/index.js",
@@ -235,7 +235,6 @@ export default {
235
235
  */
236
236
  const parent = inject('parent', null)
237
237
  const dynamicMapComp = inject('dynamicMapComp')
238
-
239
238
  const configLinks = [parent, ...props.additionConfigs, props.config]
240
239
  configLinks.reduce((parent, config) => {
241
240
  definePrivatelyProp(config, 'parent', parent)
@@ -0,0 +1 @@
1
+ export {default as default} from './src/LazyLoadComponent'
@@ -0,0 +1,137 @@
1
+ import { onMounted, onUnmounted, reactive, ref, TransitionGroup } from "vue"
2
+ import './LazyLoadComponent.scss'
3
+
4
+ export default {
5
+ name: 'LazyLoadComponent',
6
+ props: {
7
+ timeout: {
8
+ type: Number
9
+ },
10
+ tagName: {
11
+ type: String,
12
+ default: 'div'
13
+ },
14
+ viewport: {
15
+ type: typeof window !== 'undefined' ? window.HTMLElement : Object,
16
+ default: () => null
17
+ },
18
+ threshold: {
19
+ type: String,
20
+ default: '0px'
21
+ },
22
+ direction: {
23
+ type: String,
24
+ default: 'vertical'
25
+ },
26
+ maxWaitingTime: {
27
+ type: Number,
28
+ default: 50
29
+ }
30
+ },
31
+ setup(props, { slots, emit }) {
32
+ const el = ref(null)
33
+ let timer = null
34
+ let io = null
35
+ const data = reactive({
36
+ isInit: false,
37
+ timer: null,
38
+ io: null,
39
+ loading: false
40
+ })
41
+ // 如果指定timeout则无论可见与否都是在timeout之后初始化
42
+ if (props.timeout) {
43
+ timer = setTimeout(() => {
44
+ toInit()
45
+ }, props.timeout)
46
+ }
47
+
48
+ function intersectionHandler (entries) {
49
+ if (
50
+ // 正在交叉
51
+ entries[0].isIntersecting ||
52
+ // 交叉率大于0
53
+ entries[0].intersectionRatio
54
+ ) {
55
+ toInit()
56
+ io?.unobserve(el.value)
57
+ }
58
+ }
59
+
60
+ function requestAnimationFrame (callback) {
61
+ // 防止等待太久没有执行回调
62
+ // 设置最大等待时间
63
+ setTimeout(() => {
64
+ if (data.isInit) return
65
+ callback()
66
+ }, props.maxWaitingTime)
67
+
68
+ // 兼容不支持requestAnimationFrame 的浏览器
69
+ return (window.requestAnimationFrame || ((callback) => setTimeout(callback, 1000 / 60)))(callback)
70
+ }
71
+ // 处理组件和骨架组件的切换
72
+ function toInit () {
73
+ debugger
74
+ // 此时说明骨架组件即将被切换
75
+ emit('beforeInit')
76
+
77
+ // 此时可以准备加载懒加载组件的资源
78
+ data.loading = true
79
+
80
+ // 由于函数会在主线程中执行,加载懒加载组件非常耗时,容易卡顿
81
+ // 所以在requestAnimationFrame回调中延后执行
82
+ requestAnimationFrame(() => {
83
+ data.isInit = true
84
+ emit('init')
85
+ })
86
+ }
87
+
88
+ onMounted(() => {
89
+ if (!props.timeout) {
90
+ // 根据滚动方向来构造视口外边距,用于提前加载
91
+ let rootMargin
92
+ switch (props.direction) {
93
+ case 'vertical':
94
+ rootMargin = `${props.threshold} 0px`
95
+ break
96
+ case 'horizontal':
97
+ rootMargin = `0px ${props.threshold}`
98
+ break
99
+ }
100
+
101
+ try {
102
+ // 观察视口与组件容器的交叉情况
103
+ io = new window.IntersectionObserver(intersectionHandler, {
104
+ rootMargin,
105
+ root: props.viewport,
106
+ threshold: [0, Number.MIN_VALUE, 0.01]
107
+ });
108
+ io.observe(el.value);
109
+ } catch (e) {
110
+ toInit()
111
+ }
112
+ }
113
+ })
114
+ onUnmounted(() => {
115
+ if (io) {
116
+ io.unobserve(el.value)
117
+ }
118
+ })
119
+
120
+ return () => (
121
+ <TransitionGroup ref={(e) => {el.value= e.$el}} tag={props.tagName} name="lazy-component" className="lazy-load-component"
122
+ onBeforeEnter={(el) => emit('before-enter', el)}
123
+ onBbeforeLeave={(el) => emit('before-leave', el)}
124
+ onAfterEnter={(el) => emit('after-enter', el)}
125
+ onAfterLeave={(el) => emit('after-leave', el)}
126
+ >
127
+ {
128
+ data.isInit ?
129
+ slots?.default(data.loading) :
130
+ slots?.skeleton ?
131
+ slots?.skeleton() :
132
+ null
133
+ }
134
+ </TransitionGroup>
135
+ )
136
+ }
137
+ }
@@ -0,0 +1,36 @@
1
+ .lazy-load-component {
2
+ position: relative;
3
+ width: 100%;
4
+ }
5
+ .CustomComponentRow {
6
+ & > .lazy-load-component {
7
+ width: unset;
8
+ }
9
+ }
10
+
11
+ .lazy-component-enter {
12
+ opacity: 0;
13
+ }
14
+
15
+ .lazy-component-enter-to {
16
+ opacity: 1;
17
+ }
18
+
19
+ .lazy-component-enter-active {
20
+ transition: opacity 0.3s 0.2s;
21
+ position: absolute;
22
+ top: 0;
23
+ width: 100%;
24
+ }
25
+
26
+ .lazy-component-leave {
27
+ opacity: 1;
28
+ }
29
+
30
+ .lazy-component-leave-to {
31
+ opacity: 0;
32
+ }
33
+
34
+ .lazy-component-leave-active {
35
+ transition: opacity 0.5s;
36
+ }
@@ -7,14 +7,14 @@ import { commonPropsType, PLAIN_TYPE_OPTIONS_COLUMNS } from '../../utils/const'
7
7
  import { computed, defineModel, defineProps, inject, getCurrentInstance, watch, nextTick, useAttrs } from 'vue'
8
8
  import dayjs from 'dayjs'
9
9
  import { isNaN } from '../../utils/is';
10
- import { useFormItem } from 'element-plus'
11
10
 
11
+ const useFormItem = inject('_useFormItem', null)
12
12
  defineOptions({
13
13
  inheritAttrs: false
14
14
  })
15
15
 
16
16
  const attrs = useAttrs()
17
- const { formItem: elFormItem } = useFormItem()
17
+ const { formItem: elFormItem } = useFormItem?.() || {}
18
18
  const modelValue = defineModel()
19
19
  const props = defineProps({
20
20
  ...commonPropsType,
@@ -230,6 +230,7 @@ function formatValue(value) {
230
230
  : formatted
231
231
  }
232
232
 
233
+
233
234
  watch(modelValue, () => {
234
235
  nextTick(() => {
235
236
  elFormItem?.validate?.('blur').catch()
@@ -11,10 +11,9 @@ import { ElTabs } from 'element-plus'
11
11
  import Tabs from '../tabs'
12
12
  import Renderer from '../../renderer.jsx'
13
13
  import { computed, useAttrs, useSlots } from 'vue'
14
- import { commonPropsType, hasOwn } from '../../utils/index.js'
14
+ import { assertMetaType, commonPropsType, hasOwn } from '../../utils/index.js'
15
15
  import { watch } from 'vue'
16
16
  import { OPEN_DATA_RULES } from '../../config.js'
17
-
18
17
  // import * as lib from 'element-plus/es/utils/index.mjs'
19
18
 
20
19
  const slots = useSlots()
@@ -127,9 +126,6 @@ if (OPEN_DATA_RULES) {
127
126
  })
128
127
  }
129
128
 
130
- function assertMetaType(config, metaType) {
131
- return config.renderby === metaType || config.metaType === metaType
132
- }
133
129
 
134
130
  defineExpose({
135
131
  setActiveTab(tabMetaCode) {
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <ElDatePicker v-bind="{ ...attrs, ...datePickerProps}" :disabledDate="disabledDate" v-model="value">
2
+ <ElDatePicker v-bind="{ ...attrs, ...normalDatePickerProps}" :disabledDate="disabledDate" v-model="value">
3
3
  <template v-for="(_, key) in slots" :key="key" v-slot:[key]="scope">
4
4
  <slot :name="key" v-bind="scope"></slot>
5
5
  </template>
@@ -46,22 +46,38 @@ const datePickerProps = computed(() => {
46
46
  }
47
47
  return ret
48
48
  })
49
+ const normalDatePickerProps = computed(() => {
50
+ const ret = {
51
+ ...datePickerProps.value
52
+ }
53
+ delete ret.valueFormat
54
+ return ret
55
+ })
56
+
49
57
  const attrs = useAttrs()
50
58
  const modeValue = defineModel()
51
59
 
52
60
  const value = computed({
53
61
  get() {
54
- if (isNaN(Number(modeValue.value))) {
55
- return modeValue.value
56
- } else {
57
- if (datePickerProps.value.valueFormat === 'timestamp' || `${modeValue.value}`.length >= 13) {
58
- return Number(modeValue.value)
62
+ let ret = modeValue.value
63
+ if (!isNaN(Number(modeValue.value))) {
64
+ if (
65
+ datePickerProps.value.valueFormat === 'x' ||
66
+ datePickerProps.value.valueFormat === 'timestamp' ||
67
+ `${modeValue.value}`.length >= 13
68
+ ) {
69
+ ret = Number(modeValue.value)
59
70
  }
60
- return modeValue.value
61
71
  }
72
+ ret = dayjs(ret).toDate()
73
+ return ret
62
74
  },
63
75
  set(val) {
64
- modeValue.value = val
76
+ let valueFormat = datePickerProps.value?.valueFormat
77
+ if (valueFormat === 'timestamp') {
78
+ valueFormat = 'x'
79
+ }
80
+ modeValue.value = dayjs(val).format(valueFormat)
65
81
  }
66
82
  })
67
83
  watch(value, () => {
@@ -1,4 +1,4 @@
1
- import { generateFormConfig, parsePageConfig } from "../utils"
1
+ import { generateFormConfig, parsePageConfig } from "../utils/index.js"
2
2
  import { ref } from 'vue'
3
3
  import { buildInRequest } from "../utils/request"
4
4
  import { GET_SYS_PARAM_CACHE, QUERY_PAGE_CONFIG_DATA } from "../api/builtIn"
@@ -11,6 +11,11 @@ export function usePageConfig() {
11
11
  const hireRelatMapRulesRef = ref(null)
12
12
  const mapCompRef = ref(null)
13
13
  function initPageConfig({
14
+ components,
15
+ confirmInstance,
16
+ openChildDialogInstance,
17
+ buttonActions,
18
+ builtPolyfillReq,
14
19
  requestTraceId,
15
20
  dialogReq,
16
21
  mode,
@@ -30,6 +35,11 @@ export function usePageConfig() {
30
35
  messageCb
31
36
  }) {
32
37
  const { pageConfig, mapComp, hireRelatMapRules } = parsePageConfig({
38
+ components,
39
+ confirmInstance,
40
+ openChildDialogInstance,
41
+ buttonActions,
42
+ builtPolyfillReq,
33
43
  requestTraceId,
34
44
  dialogReq,
35
45
  mode,
package/src/index.jsx CHANGED
@@ -3,6 +3,7 @@ import Renderer from './renderer.jsx'
3
3
  // import './style/index.scss'
4
4
  import { usePageConfig } from './hooks/pageConfig'
5
5
  import { toValidate } from './utils/valid.js'
6
+ import { toValidate as validateByData } from './utils/validateByData.js'
6
7
  import { MODE } from "./utils/const.js"
7
8
  import { generateRequester } from "./utils/request.js"
8
9
  import { executeLoadServices, resetConfigEventInit } from "./components/helper/resolver.js"
@@ -207,6 +208,7 @@ export default {
207
208
  },
208
209
  emits: ['update:modelValue', 'rootStoreChange'],
209
210
  setup(props, { emit, attrs, expose }) {
211
+ const componentsRef = toRef(props, 'components')
210
212
  const configsSet = new Set()
211
213
  const dynamicMapComp = reactive({})
212
214
  const instance = getCurrentInstance()
@@ -298,6 +300,11 @@ export default {
298
300
  )
299
301
  }
300
302
  initPageConfig({
303
+ components: props.components,
304
+ confirmInstance: props.confirmInstance,
305
+ openChildDialogInstance: props.openChildDialogInstance,
306
+ buttonActions: props.buttonActions,
307
+ builtPolyfillReq: props.builtPolyfillReq,
301
308
  requestTraceId: props.requestTraceId,
302
309
  dialogReq: props.dialogReq,
303
310
  mode: props.mode,
@@ -320,6 +327,11 @@ export default {
320
327
 
321
328
  watch(toRef(props, 'config'), () => {
322
329
  initPageConfig({
330
+ components: props.components,
331
+ confirmInstance: props.confirmInstance,
332
+ openChildDialogInstance: props.openChildDialogInstance,
333
+ buttonActions: props.buttonActions,
334
+ builtPolyfillReq: props.builtPolyfillReq,
323
335
  requestTraceId: props.requestTraceId,
324
336
  dialogReq: props.dialogReq,
325
337
  mode: props.mode,
@@ -361,7 +373,7 @@ export default {
361
373
  provide('hireRelatMapRules', hireRelatMapRulesRef) // 组件对应的规则集合
362
374
 
363
375
  provide('buttonActions', props.buttonActions)
364
- provide('components', toRef(props, 'components'))
376
+ provide('components', componentsRef)
365
377
  provide('selects', toRef(props, 'selects'))
366
378
  provide('_rootInstance', instance)
367
379
  provide('rootValue', computed({
@@ -381,13 +393,27 @@ export default {
381
393
  provide('_parentDynamicMapComp', props.parentDynamicMapComp)
382
394
  provide('_selectionsObj', props.selectionsObj)
383
395
  provide('_polyfillConfigs', props.polyfillConfigs)
384
- provide('requestTraceId', toRef(props, 'requestTraceId')) // 所有渲染器调用的接口,都需要加次参数(生哥提)
396
+ const requestTraceIdRef = toRef(props, 'requestTraceId')
397
+ provide('requestTraceId', requestTraceIdRef) // 所有渲染器调用的接口,都需要加次参数(生哥提)
385
398
 
386
399
  const rootForm = ref(null)
387
400
  provide('rootForm', rootForm)
388
401
 
389
402
  const validate = (cb) => {
390
- toValidate(rootForm, cb, dynamicMapComp)
403
+ if (OPEN_DATA_RULES) {
404
+ validateByData({
405
+ rootConfig: props.config,
406
+ rootValue: props.modelValue,
407
+ mode: props.mode,
408
+ lang: props.lang,
409
+ messageInstance: props.messageInstance,
410
+ formRef:rootForm,
411
+ cb,
412
+ dynamicMapComp,
413
+ })
414
+ } else {
415
+ toValidate(rootForm, cb, dynamicMapComp)
416
+ }
391
417
  }
392
418
  provide('_validate', validate)
393
419
  expose({
@@ -1,6 +1,6 @@
1
1
  <script setup>
2
2
  import getNativeComps from './components/patchComponents-web'
3
- import { ElMessage, ElMessageBox, formContextKey } from "element-plus"
3
+ import { ElMessage, ElMessageBox, formContextKey, useFormItem } from "element-plus"
4
4
  import { loadingInstance } from './components/loading'
5
5
  import { computed, provide, ref, useAttrs } from 'vue';
6
6
  import Resolver from './resolver-common.vue'
@@ -48,6 +48,8 @@ const attrs = useAttrs()
48
48
  const resolverRef = ref(null)
49
49
 
50
50
  provide('_formContextKey', formContextKey)
51
+ provide('_useFormItem', useFormItem)
52
+
51
53
 
52
54
  defineExpose({
53
55
  dynamicMapComp: computed({
@@ -637,6 +637,7 @@ export function assignmentPathVal(obj = {}, path, val, separator = '.') {
637
637
  const currentIdx = parseInt(match[2])
638
638
  if (!Number.isNaN(currentIdx)) {
639
639
  !retObj[currentIdx] && (retObj[currentIdx] = {})
640
+ retObj = retObj[currentIdx]
640
641
  }
641
642
  }
642
643
  }
@@ -0,0 +1,69 @@
1
+ export class LazyLoader {
2
+ el = null
3
+ io = null
4
+ isInit = false
5
+ options = {}
6
+ constructor(el, options) {
7
+ this.options = options
8
+ this.el = el
9
+ let { viewport, direction = 'vertical', threshold = '10px'} = this.options
10
+ let rootMargin
11
+ switch (direction) {
12
+ case 'vertical':
13
+ rootMargin = `${threshold} 0px`
14
+ break
15
+ case 'horizontal':
16
+ rootMargin = `0px ${threshold}`
17
+ break
18
+ }
19
+
20
+ try {
21
+ // 观察视口与组件容器的交叉情况
22
+ this.io = new window.IntersectionObserver(this.intersectionHandler.bind(this), {
23
+ rootMargin,
24
+ root: viewport,
25
+ threshold: [0, Number.MIN_VALUE, 0.01]
26
+ });
27
+ this.io.observe(el);
28
+ } catch (e) {
29
+ this.toInit()
30
+ }
31
+ }
32
+ intersectionHandler (entries) {
33
+ if (
34
+ // 正在交叉
35
+ entries[0].isIntersecting ||
36
+ // 交叉率大于0
37
+ entries[0].intersectionRatio
38
+ ) {
39
+ this.toInit()
40
+ this.io?.unobserve(this.el)
41
+ }
42
+ }
43
+ toInit () {
44
+ // 此时说明骨架组件即将被切换
45
+ this.options?.beforeInit?.()
46
+
47
+ // 此时可以准备加载懒加载组件的资源
48
+ this.options?.beginLoading?.()
49
+
50
+ // 由于函数会在主线程中执行,加载懒加载组件非常耗时,容易卡顿
51
+ // 所以在requestAnimationFrame回调中延后执行
52
+ this.requestAnimationFrame(() => {
53
+ this.isInit = true
54
+ this.options?.init?.()
55
+ })
56
+ }
57
+ requestAnimationFrame (callback) {
58
+ const { maxWaitingTime = 50 } = this.options
59
+ // 防止等待太久没有执行回调
60
+ // 设置最大等待时间
61
+ setTimeout(() => {
62
+ if (this.isInit) return
63
+ callback()
64
+ }, maxWaitingTime)
65
+
66
+ // 兼容不支持requestAnimationFrame 的浏览器
67
+ return (window.requestAnimationFrame || ((callback) => setTimeout(callback, 1000 / 60)))(callback)
68
+ }
69
+ }