@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,416 @@
|
|
|
1
|
+
import { EntityBody, IViewProps, ListVM, ObjectVM, RuntimeModel, ViewVM } from '@oinone/kunlun-engine';
|
|
2
|
+
import { LifeCycleTypes, ViewEventName } from '@oinone/kunlun-event';
|
|
3
|
+
import { createViewElement, Entity, IDslNode, IModel, IView, ViewElement, ViewId, ViewType } from '@oinone/kunlun-meta';
|
|
4
|
+
import { Matched, useMatched } from '@oinone/kunlun-router';
|
|
5
|
+
import { Constructor } from '@oinone/kunlun-shared';
|
|
6
|
+
import { SPI, SPIOptions, SPISingleSelector, SPITokenFactory } from '@oinone/kunlun-spi';
|
|
7
|
+
import { Subscription } from '@oinone/kunlun-state';
|
|
8
|
+
|
|
9
|
+
import { Widget } from '../basic';
|
|
10
|
+
|
|
11
|
+
import { DslNodeWidget } from '../dsl/DslNodeWidget';
|
|
12
|
+
|
|
13
|
+
export interface IViewFilterOptions extends SPIOptions {
|
|
14
|
+
id?: ViewId[] | ViewId;
|
|
15
|
+
name?: string[] | string;
|
|
16
|
+
type?: ViewType[] | ViewType;
|
|
17
|
+
model?: string[] | string;
|
|
18
|
+
widget?: string[] | string;
|
|
19
|
+
tagName?: string[] | string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
type WatchCb<T> = (value: T, oldValue: T) => void;
|
|
23
|
+
|
|
24
|
+
@SPI.Base('View', ['id', 'name', 'type', 'model', 'widget', 'tagName'])
|
|
25
|
+
export abstract class ViewWidget<
|
|
26
|
+
ViewData = any,
|
|
27
|
+
VP extends IViewProps = any,
|
|
28
|
+
VM extends ListVM | ObjectVM = any
|
|
29
|
+
> extends DslNodeWidget<VP> {
|
|
30
|
+
public static Token: SPITokenFactory<IViewFilterOptions>;
|
|
31
|
+
|
|
32
|
+
public static Selector: SPISingleSelector<IViewFilterOptions, Constructor<ViewWidget>>;
|
|
33
|
+
|
|
34
|
+
@Widget.Reactive()
|
|
35
|
+
protected loading = false;
|
|
36
|
+
|
|
37
|
+
protected currentRoute: Matched = {} as Matched;
|
|
38
|
+
|
|
39
|
+
public rootData!: EntityBody;
|
|
40
|
+
|
|
41
|
+
private subjectRoute$!: Subscription;
|
|
42
|
+
|
|
43
|
+
private $$vm!: VM;
|
|
44
|
+
|
|
45
|
+
public getVM(): VM {
|
|
46
|
+
return this.$$vm;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
public setVM($$vm: VM) {
|
|
50
|
+
this.$$vm = $$vm;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* 设置loading
|
|
55
|
+
*/
|
|
56
|
+
public setBusy(busy: boolean) {
|
|
57
|
+
this.getVM().setBusy(busy);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* 获取url参数
|
|
62
|
+
*
|
|
63
|
+
* @returns {Record<string, string>}
|
|
64
|
+
*/
|
|
65
|
+
public getUrlParams() {
|
|
66
|
+
const { page = {} } = useMatched().matched.segmentParams;
|
|
67
|
+
return page;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* 获取当前是否处于loading状态
|
|
72
|
+
*/
|
|
73
|
+
public getBusy() {
|
|
74
|
+
return this.loading;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
public initialize(props: VP) {
|
|
78
|
+
if (props.isRootView == null) {
|
|
79
|
+
props.isRootView = true;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
super.initialize(props);
|
|
83
|
+
|
|
84
|
+
this.isRootView = props.isRootView || false;
|
|
85
|
+
|
|
86
|
+
if (props.view) {
|
|
87
|
+
this.view = props.view;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (this.rootHandleStr == null && props.isRootWidget) {
|
|
91
|
+
this.currentRootHandlerStr = this.getHandle();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
this.selfHandleStr = this.getHandle();
|
|
95
|
+
this.isDialogView = props.isDialogView || false;
|
|
96
|
+
|
|
97
|
+
this.model = props.model! as unknown as RuntimeModel;
|
|
98
|
+
|
|
99
|
+
this.setVM(
|
|
100
|
+
new ViewVM({
|
|
101
|
+
view: props.view!,
|
|
102
|
+
dslNode: props.dslNode,
|
|
103
|
+
model: props.model!,
|
|
104
|
+
isRootWidget: props.isRootWidget === false ? props.isRootWidget : true,
|
|
105
|
+
isDialogView: props.isDialogView || false,
|
|
106
|
+
isRootView: props.isRootView
|
|
107
|
+
}) as VM
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
this.getVM().isRootWidget = this.isRoot;
|
|
111
|
+
this.getVM().isDialogView = this.isDialogView;
|
|
112
|
+
|
|
113
|
+
// this.watchRootData$();
|
|
114
|
+
|
|
115
|
+
return this;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
protected domain = '';
|
|
119
|
+
|
|
120
|
+
@Widget.Inject()
|
|
121
|
+
@Widget.Reactive()
|
|
122
|
+
private filter!: string;
|
|
123
|
+
|
|
124
|
+
@Widget.Reactive()
|
|
125
|
+
@Widget.Inject('rootHandleStr')
|
|
126
|
+
private parentRootHandlerStr: string | undefined;
|
|
127
|
+
|
|
128
|
+
@Widget.Reactive()
|
|
129
|
+
private currentRootHandlerStr: string | undefined;
|
|
130
|
+
|
|
131
|
+
@Widget.Reactive()
|
|
132
|
+
@Widget.Provide()
|
|
133
|
+
private get rootHandleStr(): string | undefined {
|
|
134
|
+
return this.currentRootHandlerStr || this.parentRootHandlerStr;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
@Widget.Reactive()
|
|
138
|
+
public isRootView = true;
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* 监听视图的事件
|
|
142
|
+
* @param event 事件名 / 事件对象
|
|
143
|
+
* @param handler? 回调函数
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
*
|
|
147
|
+
* 单个事件监听
|
|
148
|
+
* viewWidget.on('change', (fieldInstance) => {})
|
|
149
|
+
* viewWidget.on('blur', (fieldInstance) => {})
|
|
150
|
+
*/
|
|
151
|
+
public on<V = ViewWidget>(event: { [key in ViewEventName]?: (view: V) => void }): void;
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* 多个事件监听
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
*
|
|
158
|
+
* viewWidget.on({
|
|
159
|
+
* change(fieldInstance) => {},
|
|
160
|
+
* blur(fieldInstance) => {},
|
|
161
|
+
* })
|
|
162
|
+
*/
|
|
163
|
+
public on<V = ViewWidget>(event: ViewEventName, handler: (view: V) => void): void;
|
|
164
|
+
|
|
165
|
+
public on<V = ViewWidget>(
|
|
166
|
+
event: ViewEventName | { [key in ViewEventName]?: (view: V) => void },
|
|
167
|
+
handler?: (view: V) => void
|
|
168
|
+
) {
|
|
169
|
+
this.getVM().on(event as any, handler as any);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* 用来监听视图数据的的变化
|
|
174
|
+
*
|
|
175
|
+
* @param {(value, oldValue):void} cb 监听数据发生变化的回调函数
|
|
176
|
+
* @param {object} options 可配置选项
|
|
177
|
+
* watchKey -> 当key对应的value发生变化后,才会触发回调用函数
|
|
178
|
+
* "如果要监听的数据是对象,那么该参数不会生效"
|
|
179
|
+
* distinct -> 是否去重(当上一个值跟当前的值相当的时候,就不会处理)
|
|
180
|
+
*
|
|
181
|
+
* @example
|
|
182
|
+
* const widget = this.createWidget(FormWidget, undefined, {....})
|
|
183
|
+
* widget.watch((value) => {....})
|
|
184
|
+
*
|
|
185
|
+
*/
|
|
186
|
+
public watch(cb: WatchCb<ViewData>);
|
|
187
|
+
public watch(cb: WatchCb<ViewData>, options: { watchKey?: string; distinct?: boolean });
|
|
188
|
+
public watch(cb: WatchCb<ViewData>, options: { watchKey?: string[]; distinct?: boolean });
|
|
189
|
+
|
|
190
|
+
public watch(cb: WatchCb<ViewData>, options?: { watchKey?: string | string[]; distinct?: boolean }) {
|
|
191
|
+
this.getVM().watch(cb as any, options as any);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* 如果没有key,就不做任何处理
|
|
196
|
+
* 如果key不是字符串类型,也不是数组类型,那么不做任何处理
|
|
197
|
+
*/
|
|
198
|
+
protected filterWatchData(pre: ViewData, next: ViewData, key: string | string[]) {
|
|
199
|
+
return this.getVM().filterWatchData(pre as any, next as any, key as any);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
public isDialogView = false;
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* 当前的widget是不是更节点
|
|
206
|
+
*/
|
|
207
|
+
@Widget.Reactive()
|
|
208
|
+
public get isRoot() {
|
|
209
|
+
return this.rootHandleStr === this.getHandle();
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
@Widget.Reactive()
|
|
213
|
+
public get useConstruct() {
|
|
214
|
+
return this.isRoot || this.isDialogView;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
@Widget.Provide()
|
|
218
|
+
private selfHandleStr = '';
|
|
219
|
+
|
|
220
|
+
@Widget.Reactive()
|
|
221
|
+
@Widget.Provide('view')
|
|
222
|
+
public view!: IView;
|
|
223
|
+
|
|
224
|
+
@Widget.Reactive()
|
|
225
|
+
@Widget.Provide('viewModel')
|
|
226
|
+
protected model: RuntimeModel | null = null;
|
|
227
|
+
|
|
228
|
+
protected type: 'FORM' | 'TABLE' | 'UNKNOWN' = 'UNKNOWN';
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* 页面默认的参数, A页面跳转到B页面,期望能带入参数过去
|
|
232
|
+
*/
|
|
233
|
+
protected initQueryParams: Record<string, string> | null = null;
|
|
234
|
+
|
|
235
|
+
public get viewElement(): ViewElement | any {
|
|
236
|
+
return createViewElement(this.dslNode);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
protected resolveTemplate() {}
|
|
240
|
+
|
|
241
|
+
public fetchData(data?: Entity[], options?, variables?: Record<string, unknown>): unknown {
|
|
242
|
+
return {};
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
public onRowsChange(data: any[]) {}
|
|
246
|
+
|
|
247
|
+
public loadData(data: ViewData, reset?: boolean): unknown {
|
|
248
|
+
return {};
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* 加载`rootData` 数据
|
|
253
|
+
*/
|
|
254
|
+
public loadRootData(content: any) {
|
|
255
|
+
this.getVM().setRootData(content);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
public setRootDataByKey(key: string, value: any) {
|
|
259
|
+
const data = this.getVM().getRootData();
|
|
260
|
+
|
|
261
|
+
if (data) {
|
|
262
|
+
data[key] = value;
|
|
263
|
+
this.getVM().setRootData(data as any);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
public submit(): unknown {
|
|
268
|
+
return {};
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
public getData() {
|
|
272
|
+
return this.getVM().getData() as ViewData;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
public setData(content: ViewData) {
|
|
276
|
+
this.getVM().setData(content as any);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
public async validator(): Promise<any[]> {
|
|
280
|
+
return [];
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* 加载元数据,允许被重写
|
|
285
|
+
*
|
|
286
|
+
* @param {IModel} model 模型
|
|
287
|
+
* @param {IDslNode} dslNode? dslNode,如果不传入,会自动创建
|
|
288
|
+
* @param {IView} view? 视图,如果不传入,会自动创建
|
|
289
|
+
* @param {ViewType} viewType? 指定视图类型
|
|
290
|
+
*/
|
|
291
|
+
public loadMetadata(model: IModel, dslNode?: IDslNode, view?: IView, viewType?: ViewType) {
|
|
292
|
+
this.getVM().loadMetadata(model as unknown as IModel, dslNode, view, viewType);
|
|
293
|
+
|
|
294
|
+
this.model = this.getVM().getModel() as unknown as RuntimeModel;
|
|
295
|
+
this.view = this.getVM().getView();
|
|
296
|
+
|
|
297
|
+
if (!this.dslNode) {
|
|
298
|
+
if (dslNode) {
|
|
299
|
+
this.dslNode = dslNode;
|
|
300
|
+
} else {
|
|
301
|
+
this.dslNode = this.getVM().getDslNode();
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
public getActiveRecords(): Entity[] {
|
|
307
|
+
return [];
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
public setDomain(domain: string) {
|
|
311
|
+
this.domain = domain;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
public getDomain() {
|
|
315
|
+
return this.domain;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
public setFilter(f: string) {
|
|
319
|
+
this.filter = f;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
public getFilter() {
|
|
323
|
+
return this.filter;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
public getModel() {
|
|
327
|
+
return this.getVM().getModel();
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
public getView() {
|
|
331
|
+
return this.getVM().getView();
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
@Widget.Reactive()
|
|
335
|
+
public path!: string;
|
|
336
|
+
|
|
337
|
+
public getPath() {
|
|
338
|
+
return this.path;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
public notify(type: LifeCycleTypes) {
|
|
342
|
+
this.getVM().notify(type);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
public $$beforeCreated() {
|
|
346
|
+
const { initQueryParams = '{}' } = this.getUrlParams();
|
|
347
|
+
try {
|
|
348
|
+
const params = JSON.parse(initQueryParams);
|
|
349
|
+
this.initQueryParams = Object.keys(params).length ? params : null;
|
|
350
|
+
} catch (error) {
|
|
351
|
+
this.initQueryParams = null;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
this.notify(LifeCycleTypes.ON_VIEW_BEFORE_CREATED);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
public $$created() {
|
|
358
|
+
this.notify(LifeCycleTypes.ON_VIEW_CREATED);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
public $$beforeMount() {
|
|
362
|
+
this.notify(LifeCycleTypes.ON_VIEW_BEFORE_MOUNT);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
public $$mounted() {
|
|
366
|
+
this.getVM().setPageViewState('mount');
|
|
367
|
+
|
|
368
|
+
this.getVM().watchLoading((loading) => {
|
|
369
|
+
this.loading = loading;
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
const { getMatched$ } = useMatched();
|
|
373
|
+
|
|
374
|
+
this.subjectRoute$ = getMatched$()!.subscribe((route) => {
|
|
375
|
+
this.currentRoute = route;
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
this.notify(LifeCycleTypes.ON_VIEW_MOUNTED);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
public $$beforeUpdate() {
|
|
382
|
+
this.notify(LifeCycleTypes.ON_VIEW_BEFORE_UPDATE);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
public $$updated() {
|
|
386
|
+
this.notify(LifeCycleTypes.ON_VIEW_UPDATED);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
public $$beforeUnmount() {
|
|
390
|
+
this.notify(LifeCycleTypes.ON_VIEW_BEFORE_UNMOUNT);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
public $$unmounted() {
|
|
394
|
+
this.getVM().setPageViewState('unmount');
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* 只有当视图真正被卸载的时候,才需要销毁数据流。
|
|
398
|
+
* 当视图状态频繁的从 mounted -> unmounted -> mounted -> unmounted ->mounted 并且以 mounted 结尾的时候,是不需要触发数据流的销毁
|
|
399
|
+
*
|
|
400
|
+
* 因为视图的 挂载、销毁是 同步 执行的,需要需要开启一个 宏任务 来判断
|
|
401
|
+
*/
|
|
402
|
+
|
|
403
|
+
const t = setTimeout(() => {
|
|
404
|
+
if (this.getVM().getPageViewState() === 'unmount') {
|
|
405
|
+
this.notify(LifeCycleTypes.ON_VIEW_UNMOUNTED);
|
|
406
|
+
this.getVM().unsubscribe();
|
|
407
|
+
}
|
|
408
|
+
clearTimeout(t);
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* @deprecated 移动端未修改,必须移除该定义
|
|
415
|
+
*/
|
|
416
|
+
export const ViewSubSymbol = Symbol('view');
|