@oinone/kunlun-vue-widget 6.2.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/dist/oinone-kunlun-vue-widget.esm.js +16 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/src/basic/AsyncVueWidget.d.ts +7 -0
- package/dist/types/src/basic/VueFragment.vue.d.ts +2 -0
- package/dist/types/src/basic/VueWidget.d.ts +331 -0
- package/dist/types/src/basic/Widget.d.ts +234 -0
- package/dist/types/src/basic/index.d.ts +3 -0
- package/dist/types/src/data/ActiveRecordsWidget.d.ts +246 -0
- package/dist/types/src/data/PathWidget.d.ts +34 -0
- package/dist/types/src/data/index.d.ts +2 -0
- package/dist/types/src/dsl/DslDefinitionWidget.d.ts +61 -0
- package/dist/types/src/dsl/DslNodeWidget.d.ts +42 -0
- package/dist/types/src/dsl/DslRenderWidget.d.ts +44 -0
- package/dist/types/src/dsl/index.d.ts +3 -0
- package/dist/types/src/feature/index.d.ts +1 -0
- package/dist/types/src/feature/invisible-supported.d.ts +11 -0
- package/dist/types/src/hooks/all-mounted.d.ts +20 -0
- package/dist/types/src/hooks/index.d.ts +1 -0
- package/dist/types/src/index.d.ts +9 -0
- package/dist/types/src/token/index.d.ts +2 -0
- package/dist/types/src/typing/WidgetTagContext.d.ts +39 -0
- package/dist/types/src/typing/WidgetTagProps.d.ts +23 -0
- package/dist/types/src/typing/index.d.ts +3 -0
- package/dist/types/src/typing/typing.d.ts +7 -0
- package/dist/types/src/util/dsl-render.d.ts +106 -0
- package/dist/types/src/util/index.d.ts +4 -0
- package/dist/types/src/util/install.d.ts +4 -0
- package/dist/types/src/util/render.d.ts +7 -0
- package/dist/types/src/util/widget-manager.d.ts +4 -0
- package/dist/types/src/view/index.d.ts +161 -0
- package/index.ts +1 -0
- package/package.json +34 -0
- package/rollup.config.js +21 -0
- package/src/basic/AsyncVueWidget.ts +31 -0
- package/src/basic/VueFragment.vue +11 -0
- package/src/basic/VueWidget.ts +997 -0
- package/src/basic/Widget.ts +675 -0
- package/src/basic/index.ts +3 -0
- package/src/data/ActiveRecordsWidget.ts +572 -0
- package/src/data/PathWidget.ts +82 -0
- package/src/data/index.ts +2 -0
- package/src/dsl/DslDefinitionWidget.ts +235 -0
- package/src/dsl/DslNodeWidget.ts +130 -0
- package/src/dsl/DslRenderWidget.ts +106 -0
- package/src/dsl/index.ts +3 -0
- package/src/feature/index.ts +1 -0
- package/src/feature/invisible-supported.ts +29 -0
- package/src/hooks/all-mounted.ts +179 -0
- package/src/hooks/index.ts +1 -0
- package/src/index.ts +9 -0
- package/src/shim-translate.d.ts +7 -0
- package/src/shim-vue.d.ts +6 -0
- package/src/token/index.ts +8 -0
- package/src/typing/WidgetTagContext.ts +53 -0
- package/src/typing/WidgetTagProps.ts +24 -0
- package/src/typing/index.ts +3 -0
- package/src/typing/typing.ts +7 -0
- package/src/util/dsl-render.ts +464 -0
- package/src/util/index.ts +4 -0
- package/src/util/install.ts +29 -0
- package/src/util/render.ts +21 -0
- package/src/util/widget-manager.ts +14 -0
- package/src/view/index.ts +416 -0
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ComputeContext,
|
|
3
|
+
ComputeContextManager,
|
|
4
|
+
ROOT_HANDLE,
|
|
5
|
+
RuntimeContext,
|
|
6
|
+
RuntimeContextManager,
|
|
7
|
+
RuntimeModelField
|
|
8
|
+
} from '@oinone/kunlun-engine';
|
|
9
|
+
import { BooleanHelper } from '@oinone/kunlun-shared';
|
|
10
|
+
import { isNil } from 'lodash-es';
|
|
11
|
+
import { Widget } from '../basic';
|
|
12
|
+
import { InvisibleSupported, isAllInvisible } from '../feature';
|
|
13
|
+
import { DslRenderWidget, DslRenderWidgetProps } from './DslRenderWidget';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* dsl组件属性
|
|
17
|
+
*/
|
|
18
|
+
export interface DslDefinitionWidgetProps extends DslRenderWidgetProps {
|
|
19
|
+
/**
|
|
20
|
+
* 元数据视图handle
|
|
21
|
+
*/
|
|
22
|
+
metadataHandle?: string;
|
|
23
|
+
/**
|
|
24
|
+
* 根组件handle(一般为视图组件)
|
|
25
|
+
*/
|
|
26
|
+
rootHandle?: string;
|
|
27
|
+
/**
|
|
28
|
+
* 是否内联组件
|
|
29
|
+
*/
|
|
30
|
+
inline?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* 自动组件
|
|
33
|
+
*/
|
|
34
|
+
automatic?: boolean;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* dsl定义组件
|
|
39
|
+
*/
|
|
40
|
+
export class DslDefinitionWidget<Props extends DslDefinitionWidgetProps = DslDefinitionWidgetProps>
|
|
41
|
+
extends DslRenderWidget<Props>
|
|
42
|
+
implements InvisibleSupported
|
|
43
|
+
{
|
|
44
|
+
@Widget.Reactive()
|
|
45
|
+
protected automatic = false;
|
|
46
|
+
|
|
47
|
+
@Widget.Reactive()
|
|
48
|
+
protected metadataHandle: string | undefined;
|
|
49
|
+
|
|
50
|
+
public getMetadataHandle() {
|
|
51
|
+
return this.metadataHandle;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@Widget.Reactive()
|
|
55
|
+
protected rootHandle: string | undefined;
|
|
56
|
+
|
|
57
|
+
public getRootHandle() {
|
|
58
|
+
return this.rootHandle;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@Widget.Reactive()
|
|
62
|
+
protected readonly currentHandle: string;
|
|
63
|
+
|
|
64
|
+
public getCurrentHandle() {
|
|
65
|
+
return this.currentHandle;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@Widget.Reactive()
|
|
69
|
+
protected inline: boolean | undefined;
|
|
70
|
+
|
|
71
|
+
protected defaultAllInvisible = false;
|
|
72
|
+
|
|
73
|
+
@Widget.Reactive()
|
|
74
|
+
public get allInvisible(): boolean | undefined {
|
|
75
|
+
const { allInvisible } = this.getDsl();
|
|
76
|
+
if (isNil(allInvisible)) {
|
|
77
|
+
return this.defaultAllInvisible;
|
|
78
|
+
}
|
|
79
|
+
return BooleanHelper.toBoolean(allInvisible);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
@Widget.Reactive()
|
|
83
|
+
private invisibleState = false;
|
|
84
|
+
|
|
85
|
+
private lastedInvisibleState: boolean | undefined;
|
|
86
|
+
|
|
87
|
+
@Widget.Reactive()
|
|
88
|
+
@Widget.Inject()
|
|
89
|
+
public parentInvisible: boolean | undefined;
|
|
90
|
+
|
|
91
|
+
@Widget.Reactive()
|
|
92
|
+
public get invisible(): boolean {
|
|
93
|
+
let { invisible } = this.getDsl();
|
|
94
|
+
if (isNil(invisible)) {
|
|
95
|
+
invisible = false;
|
|
96
|
+
} else {
|
|
97
|
+
invisible = this.invisibleProcess(invisible);
|
|
98
|
+
}
|
|
99
|
+
if (invisible) {
|
|
100
|
+
return invisible;
|
|
101
|
+
}
|
|
102
|
+
if (!this.allInvisible) {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
this.invisibleState = this.childrenInvisibleProcess();
|
|
106
|
+
return this.invisibleState;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
@Widget.Reactive()
|
|
110
|
+
@Widget.Provide('parentInvisible')
|
|
111
|
+
public get parentInvisibleProvider() {
|
|
112
|
+
return this.parentInvisible || this.invisible;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
public constructor(handle?: string) {
|
|
116
|
+
super(handle);
|
|
117
|
+
this.currentHandle = this.getHandle();
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
public initialize(props: Props) {
|
|
121
|
+
super.initialize(props);
|
|
122
|
+
this.metadataHandle = props.metadataHandle;
|
|
123
|
+
this.rootHandle = props.rootHandle;
|
|
124
|
+
this.automatic = props.automatic || false;
|
|
125
|
+
this.inline = props.inline;
|
|
126
|
+
return this;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
public get metadataRuntimeContext(): RuntimeContext {
|
|
130
|
+
const { metadataHandle } = this;
|
|
131
|
+
let runtimeContext: RuntimeContext | undefined;
|
|
132
|
+
if (metadataHandle) {
|
|
133
|
+
runtimeContext = RuntimeContextManager.get(metadataHandle);
|
|
134
|
+
}
|
|
135
|
+
if (!runtimeContext) {
|
|
136
|
+
throw new Error('Invalid metadata runtime context.');
|
|
137
|
+
}
|
|
138
|
+
return runtimeContext;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
public get rootRuntimeContext(): RuntimeContext {
|
|
142
|
+
const { rootHandle } = this;
|
|
143
|
+
let runtimeContext: RuntimeContext | undefined;
|
|
144
|
+
if (rootHandle) {
|
|
145
|
+
runtimeContext = RuntimeContextManager.get(rootHandle);
|
|
146
|
+
}
|
|
147
|
+
if (!runtimeContext) {
|
|
148
|
+
throw new Error('Invalid root runtime context.');
|
|
149
|
+
}
|
|
150
|
+
return runtimeContext;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
public get rootComputeContext(): ComputeContext | undefined {
|
|
154
|
+
const { rootHandle } = this;
|
|
155
|
+
let computeContext: ComputeContext | undefined;
|
|
156
|
+
if (rootHandle) {
|
|
157
|
+
computeContext = ComputeContextManager.get(rootHandle);
|
|
158
|
+
}
|
|
159
|
+
return computeContext;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
public get rootViewRuntimeContext(): { runtimeContext: RuntimeContext; fields: RuntimeModelField[] } {
|
|
163
|
+
const fields: RuntimeModelField[] = [];
|
|
164
|
+
let targetRuntimeContext: RuntimeContext = this.rootRuntimeContext;
|
|
165
|
+
let field = targetRuntimeContext?.parentContext?.field;
|
|
166
|
+
while (field && targetRuntimeContext) {
|
|
167
|
+
fields.push(field);
|
|
168
|
+
|
|
169
|
+
const fieldRuntimeContextHandle = targetRuntimeContext?.parentContext?.handle;
|
|
170
|
+
if (!fieldRuntimeContextHandle) {
|
|
171
|
+
throw new Error('Invalid field runtime context handle');
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const nextTargetRuntimeContext = (Widget.select(fieldRuntimeContextHandle) as DslDefinitionWidget)
|
|
175
|
+
?.rootRuntimeContext;
|
|
176
|
+
|
|
177
|
+
const parentRuntimeContext = nextTargetRuntimeContext?.parentContext;
|
|
178
|
+
if (!parentRuntimeContext || parentRuntimeContext.handle === ROOT_HANDLE) {
|
|
179
|
+
break;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
field = parentRuntimeContext.field;
|
|
183
|
+
targetRuntimeContext = nextTargetRuntimeContext;
|
|
184
|
+
}
|
|
185
|
+
return {
|
|
186
|
+
runtimeContext: targetRuntimeContext,
|
|
187
|
+
fields
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
protected invisibleProcess(invisible: boolean | string) {
|
|
192
|
+
return BooleanHelper.toBoolean(invisible);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
protected childrenInvisibleProcess(): boolean {
|
|
196
|
+
return isAllInvisible(this.getChildren());
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
protected resetInvisible(): void {
|
|
200
|
+
if (this.allInvisible) {
|
|
201
|
+
this.invisibleState = this.childrenInvisibleProcess();
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
protected resetParentInvisible(): void {
|
|
206
|
+
(this.getParent() as DslDefinitionWidget | undefined)?.resetInvisible?.();
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
protected $$mounted() {
|
|
210
|
+
super.$$mounted();
|
|
211
|
+
this.resetInvisible();
|
|
212
|
+
this.lastedInvisibleState = this.invisible;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
protected $$updated() {
|
|
216
|
+
super.$$updated();
|
|
217
|
+
const { lastedInvisibleState, invisible } = this;
|
|
218
|
+
this.lastedInvisibleState = invisible;
|
|
219
|
+
if (lastedInvisibleState !== invisible) {
|
|
220
|
+
this.resetParentInvisible();
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
protected $$unmountedAfterProperties() {
|
|
225
|
+
super.$$unmountedAfterProperties();
|
|
226
|
+
if (!this.automatic && this.metadataHandle === this.rootHandle) {
|
|
227
|
+
RuntimeContextManager.delete(this.metadataHandle);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
@Widget.Method()
|
|
232
|
+
protected allMounted() {
|
|
233
|
+
this.resetInvisible();
|
|
234
|
+
}
|
|
235
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { DslDefinition, XMLTemplateParser } from '@oinone/kunlun-dsl';
|
|
2
|
+
import { DslProps, RuntimeContext, RuntimeContextManager } from '@oinone/kunlun-engine';
|
|
3
|
+
import { IDslNode } from '@oinone/kunlun-meta';
|
|
4
|
+
import { isNil } from 'lodash-es';
|
|
5
|
+
import { VueWidget, Widget } from '../basic';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @deprecated 请使用PathWidget或ActiveRecordsWidget
|
|
9
|
+
*/
|
|
10
|
+
export class DslNodeWidget<IViewProps extends DslProps = DslProps> extends VueWidget<IViewProps> {
|
|
11
|
+
@Widget.Reactive()
|
|
12
|
+
protected metadataHandle: string | undefined;
|
|
13
|
+
|
|
14
|
+
@Widget.Reactive()
|
|
15
|
+
protected rootHandle: string | undefined;
|
|
16
|
+
|
|
17
|
+
@Widget.Reactive()
|
|
18
|
+
protected currentHandle!: string;
|
|
19
|
+
|
|
20
|
+
@Widget.Reactive({ render: false })
|
|
21
|
+
protected dslNode?: IDslNode;
|
|
22
|
+
|
|
23
|
+
@Widget.Reactive({ render: false })
|
|
24
|
+
protected template: DslDefinition | undefined;
|
|
25
|
+
|
|
26
|
+
@Widget.Reactive()
|
|
27
|
+
protected slotName: string | undefined;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* 上级路径
|
|
31
|
+
*/
|
|
32
|
+
@Widget.Reactive()
|
|
33
|
+
@Widget.Inject('path')
|
|
34
|
+
protected parentPath: string | undefined;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* 当前子路径
|
|
38
|
+
*/
|
|
39
|
+
@Widget.Reactive()
|
|
40
|
+
protected subPath: string | undefined;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* 当前子路径
|
|
44
|
+
*/
|
|
45
|
+
@Widget.Reactive()
|
|
46
|
+
protected subIndex: string | number | undefined;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* 完整路径
|
|
50
|
+
*/
|
|
51
|
+
@Widget.Reactive()
|
|
52
|
+
@Widget.Provide()
|
|
53
|
+
protected get widgetPath() {
|
|
54
|
+
let path = this.parentPath || '';
|
|
55
|
+
const { subPath, subIndex } = this;
|
|
56
|
+
if (subPath) {
|
|
57
|
+
if (path) {
|
|
58
|
+
path = `${path}.${subPath}`;
|
|
59
|
+
} else {
|
|
60
|
+
path = subPath;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (subIndex != null) {
|
|
64
|
+
path = `${path}[${subIndex}]`;
|
|
65
|
+
}
|
|
66
|
+
return path;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@Widget.Reactive()
|
|
70
|
+
protected widgetInline: boolean | undefined;
|
|
71
|
+
|
|
72
|
+
@Widget.Reactive()
|
|
73
|
+
protected get variables(): Record<string, unknown> {
|
|
74
|
+
const vari = XMLTemplateParser.resolveVariables(this.getDsl());
|
|
75
|
+
return vari;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
public initialize(config: IViewProps) {
|
|
79
|
+
super.initialize(config);
|
|
80
|
+
this.dslNode = config.dslNode;
|
|
81
|
+
this.metadataHandle = config.metadataHandle;
|
|
82
|
+
this.rootHandle = config.rootHandle;
|
|
83
|
+
this.template = config.template;
|
|
84
|
+
this.slotName = config.slotName;
|
|
85
|
+
this.widgetInline = config.widgetInline;
|
|
86
|
+
this.currentHandle = this.getHandle();
|
|
87
|
+
const { subPath, subIndex } = config;
|
|
88
|
+
this.subPath = subPath || this.template?.dslNodeType || '';
|
|
89
|
+
if (isNil(subIndex)) {
|
|
90
|
+
this.subIndex = config.__index;
|
|
91
|
+
} else {
|
|
92
|
+
this.subIndex = subIndex;
|
|
93
|
+
}
|
|
94
|
+
return this;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
public getDsl(): IDslNode {
|
|
98
|
+
return this.dslNode || ({} as IDslNode);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
public getSlotName() {
|
|
102
|
+
return this.slotName;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* 根据标签名获取dsl
|
|
107
|
+
*/
|
|
108
|
+
public getDslChildrenByLabel(labelName: string) {
|
|
109
|
+
if (this.dslNode) {
|
|
110
|
+
return (this.dslNode.children || []).find((c) => c.tagName === labelName.toUpperCase());
|
|
111
|
+
}
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
public get metadataRuntimeContext(): RuntimeContext | undefined {
|
|
116
|
+
const { metadataHandle } = this;
|
|
117
|
+
if (metadataHandle) {
|
|
118
|
+
return RuntimeContextManager.get(metadataHandle);
|
|
119
|
+
}
|
|
120
|
+
return undefined;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
public get rootRuntimeContext(): RuntimeContext | undefined {
|
|
124
|
+
const { rootHandle } = this;
|
|
125
|
+
if (rootHandle) {
|
|
126
|
+
return RuntimeContextManager.get(rootHandle);
|
|
127
|
+
}
|
|
128
|
+
return undefined;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { DslDefinition, DslSlots, DslSlotUtils, UnknownDslDefinition } from '@oinone/kunlun-dsl';
|
|
2
|
+
import { WidgetProps } from '@oinone/kunlun-engine';
|
|
3
|
+
import { Slots, VNode } from 'vue';
|
|
4
|
+
import { VueWidget, Widget } from '../basic';
|
|
5
|
+
import { DslRender } from '../util';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* dsl渲染组件属性
|
|
9
|
+
*/
|
|
10
|
+
export interface DslRenderWidgetProps extends WidgetProps {
|
|
11
|
+
/**
|
|
12
|
+
* 内部组件
|
|
13
|
+
*/
|
|
14
|
+
internal?: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* 模板dsl定义
|
|
17
|
+
*/
|
|
18
|
+
template?: DslDefinition;
|
|
19
|
+
/**
|
|
20
|
+
* 在父组件中的插槽名
|
|
21
|
+
*/
|
|
22
|
+
slotName?: string;
|
|
23
|
+
/**
|
|
24
|
+
* 支持的插槽名称
|
|
25
|
+
*/
|
|
26
|
+
slotNames?: string[];
|
|
27
|
+
/**
|
|
28
|
+
* 插槽上下文
|
|
29
|
+
*/
|
|
30
|
+
slotContext?: Record<string, unknown>;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export class DslRenderWidget<Props extends DslRenderWidgetProps = DslRenderWidgetProps> extends VueWidget {
|
|
34
|
+
@Widget.Reactive()
|
|
35
|
+
protected internal = false;
|
|
36
|
+
|
|
37
|
+
@Widget.Reactive()
|
|
38
|
+
protected template: DslDefinition | undefined;
|
|
39
|
+
|
|
40
|
+
@Widget.Reactive()
|
|
41
|
+
protected slotName: string | undefined;
|
|
42
|
+
|
|
43
|
+
protected supportedSlotNames!: string[];
|
|
44
|
+
|
|
45
|
+
protected dslSlots: DslSlots | undefined;
|
|
46
|
+
|
|
47
|
+
protected slots: Slots | null | undefined;
|
|
48
|
+
|
|
49
|
+
public initialize(props: Props) {
|
|
50
|
+
super.initialize(props);
|
|
51
|
+
this.internal = props.internal || false;
|
|
52
|
+
this.template = props.template;
|
|
53
|
+
this.slotName = props.slotName;
|
|
54
|
+
this.supportedSlotNames = props.slotNames || [];
|
|
55
|
+
if (this.template && this.supportedSlotNames.length) {
|
|
56
|
+
this.dslSlots = DslSlotUtils.fetchSlotsBySlotNames(this.template, this.supportedSlotNames);
|
|
57
|
+
}
|
|
58
|
+
return this;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
public getDsl(): DslDefinition {
|
|
62
|
+
return this.template || UnknownDslDefinition;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
public getSlotName() {
|
|
66
|
+
return this.slotName;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
public render(ctx?: Record<string, unknown>, slots?: Slots): VNode | VNode[] {
|
|
70
|
+
if (this.template) {
|
|
71
|
+
if (this.slots === undefined) {
|
|
72
|
+
if (this.internal) {
|
|
73
|
+
this.slots = this.internalRender(slots) || null;
|
|
74
|
+
} else {
|
|
75
|
+
this.slots = this.commonRender(slots) || null;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (this.slots) {
|
|
79
|
+
return this.rawRender(ctx, this.slots);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return this.rawRender(ctx, slots);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
protected rawRender(ctx?: Record<string, unknown>, slots?: Slots): VNode | VNode[] {
|
|
86
|
+
return super.render(ctx, slots);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
protected internalRender(slots?: Slots): Slots | undefined {
|
|
90
|
+
if (slots && Object.keys(slots).length) {
|
|
91
|
+
return slots;
|
|
92
|
+
}
|
|
93
|
+
if (this.dslSlots && Object.keys(this.dslSlots).length) {
|
|
94
|
+
return DslRender.renderSlots(this.dslSlots);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
protected commonRender(slots?: Slots): Slots | undefined {
|
|
99
|
+
if (this.dslSlots && Object.keys(this.dslSlots).length) {
|
|
100
|
+
return DslRender.renderSlots(this.dslSlots);
|
|
101
|
+
}
|
|
102
|
+
if (slots && Object.keys(slots).length) {
|
|
103
|
+
return slots;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
package/src/dsl/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './invisible-supported';
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { isBoolean, isNil } from 'lodash-es';
|
|
2
|
+
import { Widget } from '../basic';
|
|
3
|
+
|
|
4
|
+
type InvisibleGetter = () => boolean;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 标记可隐藏功能支持
|
|
8
|
+
*/
|
|
9
|
+
export interface InvisibleSupported {
|
|
10
|
+
invisible: boolean | InvisibleGetter | undefined;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function executeInvisible(invisibleSupported: InvisibleSupported | undefined): boolean {
|
|
14
|
+
const invisible = invisibleSupported?.invisible;
|
|
15
|
+
if (isNil(invisible)) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
if (isBoolean(invisible)) {
|
|
19
|
+
return invisible;
|
|
20
|
+
}
|
|
21
|
+
return invisible();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function isAllInvisible(widgets: (Widget | InvisibleSupported)[] | undefined): boolean {
|
|
25
|
+
if (!widgets || !widgets.length) {
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
return widgets.every((widget) => executeInvisible(widget as unknown as InvisibleSupported));
|
|
29
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { isFunction, isNil } from 'lodash-es';
|
|
2
|
+
|
|
3
|
+
import { inject, InjectionKey, onBeforeMount, onMounted, onUnmounted, provide } from 'vue';
|
|
4
|
+
|
|
5
|
+
interface AllMountedContext {
|
|
6
|
+
reportBeforeMount: (key: string) => void;
|
|
7
|
+
reportMounted: (key: string) => void;
|
|
8
|
+
reportUnmounted: (key: string) => void;
|
|
9
|
+
reportAllBeforeMount: (key: string) => void;
|
|
10
|
+
reportAllMounted: (key: string) => void;
|
|
11
|
+
reportAllUnmounted: (key: string) => void;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const defaultAllMountedContext = {
|
|
15
|
+
reportBeforeMount: () => {},
|
|
16
|
+
reportMounted: () => {},
|
|
17
|
+
reportUnmounted: () => {},
|
|
18
|
+
reportAllBeforeMount: () => {},
|
|
19
|
+
reportAllMounted: () => {},
|
|
20
|
+
reportAllUnmounted: () => {}
|
|
21
|
+
} as AllMountedContext;
|
|
22
|
+
|
|
23
|
+
interface AllMountedContextOptions {
|
|
24
|
+
reportBeforeMount?: (key: string) => void;
|
|
25
|
+
reportMounted?: (key: string) => void;
|
|
26
|
+
reportUnmounted?: (key: string) => void;
|
|
27
|
+
reportAllBeforeMount?: (key: string) => void;
|
|
28
|
+
reportAllMounted?: (key: string) => void;
|
|
29
|
+
reportAllUnmounted?: (key: string) => void;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const AllMountedContextKey: InjectionKey<AllMountedContext> = Symbol('AllMountedContext');
|
|
33
|
+
|
|
34
|
+
const useProviderAllMountedContext = (state: AllMountedContextOptions): void => {
|
|
35
|
+
provide(AllMountedContextKey, {
|
|
36
|
+
...defaultAllMountedContext,
|
|
37
|
+
...state
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const useInjectAllMountedContext = (): AllMountedContext => {
|
|
42
|
+
return inject(AllMountedContextKey, defaultAllMountedContext);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
type onAllMountedFn = () => void;
|
|
46
|
+
|
|
47
|
+
type onAllMountedOptions = { allMounted?: () => void; allMountedUpdate?: () => void };
|
|
48
|
+
|
|
49
|
+
function computeAndExecute(records: Record<string, boolean>, fn: () => void): boolean {
|
|
50
|
+
if (Object.values(records).every((value) => value)) {
|
|
51
|
+
fn();
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
let allMountedCount = 0;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* 在子组件全部挂载时执行(需配合{@link reportAllMounted}使用)
|
|
61
|
+
* @param fn 全部挂载时执行函数; allMounted仅会调用一次,allMountedUpdate会重复调用;
|
|
62
|
+
*/
|
|
63
|
+
export function onAllMounted(fn: onAllMountedFn | onAllMountedOptions): void {
|
|
64
|
+
if (!fn) {
|
|
65
|
+
console.warn('all mounted method or object is required.');
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
let finalFn: (() => void) | undefined;
|
|
70
|
+
let finalObject: { allMounted?: () => void; allMountedUpdate?: () => void } | undefined;
|
|
71
|
+
if (isFunction(fn)) {
|
|
72
|
+
finalFn = fn;
|
|
73
|
+
} else {
|
|
74
|
+
finalObject = fn;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const {
|
|
78
|
+
reportAllBeforeMount: parentReportAllBeforeMount,
|
|
79
|
+
reportAllMounted: parentReportAllMounted,
|
|
80
|
+
reportAllUnmounted: parentReportAllUnmounted
|
|
81
|
+
} = useInjectAllMountedContext();
|
|
82
|
+
|
|
83
|
+
const allMountedKey = `all-mounted#${allMountedCount++}`;
|
|
84
|
+
|
|
85
|
+
const mountedSet: Record<string, boolean> = {};
|
|
86
|
+
const allMountedSet: Record<string, boolean> = {};
|
|
87
|
+
|
|
88
|
+
useProviderAllMountedContext({
|
|
89
|
+
reportBeforeMount: (key: string) => {
|
|
90
|
+
const value = mountedSet[key];
|
|
91
|
+
if (isNil(value)) {
|
|
92
|
+
mountedSet[key] = false;
|
|
93
|
+
}
|
|
94
|
+
parentReportAllBeforeMount?.(allMountedKey);
|
|
95
|
+
},
|
|
96
|
+
reportMounted: (key: string) => {
|
|
97
|
+
const value = mountedSet[key];
|
|
98
|
+
if (isNil(value) || value) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
mountedSet[key] = true;
|
|
102
|
+
if (computeAndExecute(mountedSet, finalObject?.allMounted || finalFn || (() => ({})))) {
|
|
103
|
+
parentReportAllMounted?.(allMountedKey);
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
reportUnmounted: (key: string) => {
|
|
107
|
+
delete mountedSet[key];
|
|
108
|
+
parentReportAllUnmounted?.(allMountedKey);
|
|
109
|
+
},
|
|
110
|
+
reportAllBeforeMount: (key: string) => {
|
|
111
|
+
const value = allMountedSet[key];
|
|
112
|
+
if (isNil(value)) {
|
|
113
|
+
allMountedSet[key] = false;
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
reportAllMounted: (key: string) => {
|
|
117
|
+
const value = allMountedSet[key];
|
|
118
|
+
if (isNil(value) || value) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
allMountedSet[key] = true;
|
|
122
|
+
computeAndExecute(allMountedSet, finalObject?.allMountedUpdate || (() => ({})));
|
|
123
|
+
},
|
|
124
|
+
reportAllUnmounted: (key: string) => {
|
|
125
|
+
delete allMountedSet[key];
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
let mountedCount = 0;
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* 子组件上报挂载状态,用于执行{@link onAllMounted}传入的全部挂载时执行函数,该方法会防止提供者方法向下透传,如需进行连续处理,应先使用reportAllMounted,再使用onAllMounted方法
|
|
134
|
+
* @param options
|
|
135
|
+
*/
|
|
136
|
+
export function reportAllMounted(options?: {
|
|
137
|
+
onBeforeMount?: () => void | Promise<void>;
|
|
138
|
+
onMounted?: () => void | Promise<void>;
|
|
139
|
+
onUnmounted?: () => void | Promise<void>;
|
|
140
|
+
}): void {
|
|
141
|
+
const { reportBeforeMount, reportMounted, reportUnmounted } = useInjectAllMountedContext();
|
|
142
|
+
|
|
143
|
+
const key = `mounted-#${mountedCount++}`;
|
|
144
|
+
|
|
145
|
+
onBeforeMount(() => {
|
|
146
|
+
const res = options?.onBeforeMount?.();
|
|
147
|
+
if (res instanceof Promise) {
|
|
148
|
+
res.then(() => {
|
|
149
|
+
reportBeforeMount?.(key);
|
|
150
|
+
});
|
|
151
|
+
} else {
|
|
152
|
+
reportBeforeMount?.(key);
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
onMounted(() => {
|
|
157
|
+
const res = options?.onMounted?.();
|
|
158
|
+
if (res instanceof Promise) {
|
|
159
|
+
res.then(() => {
|
|
160
|
+
reportMounted?.(key);
|
|
161
|
+
});
|
|
162
|
+
} else {
|
|
163
|
+
reportMounted?.(key);
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
onUnmounted(() => {
|
|
168
|
+
const res = options?.onUnmounted?.();
|
|
169
|
+
if (res instanceof Promise) {
|
|
170
|
+
res.then(() => {
|
|
171
|
+
reportUnmounted?.(key);
|
|
172
|
+
});
|
|
173
|
+
} else {
|
|
174
|
+
reportUnmounted?.(key);
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
useProviderAllMountedContext({});
|
|
179
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './all-mounted';
|
package/src/index.ts
ADDED