cloud-web-corejs 1.1.0-dev.11 → 1.1.0-dev.13
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 +1 -1
- package/src/components/VabUpload/view.vue +25 -25
- package/src/components/excelExport/exportColumnMemory.js +118 -0
- package/src/components/excelExport/exportFieldDialog.vue +50 -38
- package/src/components/excelExport/index.js +30 -13
- package/src/components/excelExport/mixins.js +390 -64
- package/src/components/excelImport/mixins.js +898 -850
- package/src/components/mobile/wf/addTaskUserdialog.vue +100 -100
- package/src/components/mobile/wf/content.vue +4 -4
- package/src/components/mobile/wf/deleteTaskUserDialog.vue +73 -73
- package/src/components/mobile/wf/setCandidateDialog.vue +69 -69
- package/src/components/mobile/wf/urgingDialog.vue +75 -75
- package/src/components/table/index.js +14 -1
- package/src/components/table/vxeFilter/mixin.js +28 -18
- package/src/components/xform/docs/2026-07 table/344/270/216excelExport/344/277/256/345/244/215/345/217/212/345/257/274/345/207/272/344/274/230/345/214/226.md" +64 -57
- package/src/components/xform/docs/2026-08 xform H5 P0 /345/256/236/347/216/260/350/247/204/346/240/274.md" +528 -0
- package/src/components/xform/docs/2026-08 xform H5 P1 /345/256/236/347/216/260/350/247/204/346/240/274.md" +412 -0
- package/src/components/xform/docs/2026-08 xform H5 P2 /345/256/236/347/216/260/350/247/204/346/240/274.md" +287 -0
- package/src/components/xform/docs/2026-08 xform /347/247/273/345/212/250/347/253/257/345/270/203/345/261/200/345/257/271/351/275/220 bill_setting /346/226/271/346/241/210.md" +400 -0
- package/src/components/xform/docs/2026-09 /346/235/241/344/273/266/345/257/274/345/207/272/345/244/247/346/225/260/346/215/256/351/207/217/345/264/251/346/272/203/346/216/222/346/237/245.md" +389 -0
- package/src/components/xform/form-designer/form-widget/container-widget/detail-h5-widget.vue +243 -243
- package/src/components/xform/form-designer/form-widget/container-widget/h5-card-pane-widget.vue +228 -228
- package/src/components/xform/form-designer/form-widget/container-widget/h5-card-widget.vue +165 -165
- package/src/components/xform/form-designer/form-widget/dialog/importDialogMixin.js +61 -2
- package/src/components/xform/form-designer/form-widget/field-widget/select-export-item-button-widget.vue +3 -0
- package/src/components/xform/form-designer/form-widget/field-widget/singleUpload-widget.vue +145 -145
- package/src/components/xform/form-render/container-item/data-table-item.vue +350 -347
- package/src/components/xform/form-render/container-item/data-table-mixin.js +240 -37
- package/src/components/xform/form-render/container-item/list-h5-item.vue +1 -1
- package/src/components/xform/utils/dynamicSchemaUtil.js +385 -361
- package/src/layout/components/TagsView/index.vue +325 -323
- package/src/store/modules/tagsView.js +241 -217
- package/src/utils/importLimit.js +72 -0
- package/src/utils/pdfUtil.js +6 -1
- package/src/utils/request.js +17 -0
- package/src/views/demo/bizTab/bill/billConfig.js +41 -0
- package/src/views/demo/bizTab/bill/detail.vue +436 -0
- package/src/views/demo/bizTab/bill/list.vue +288 -0
- package/src/views/demo/bizTab/bill/productDialog.vue +176 -0
- package/src/views/demo/bizTab/simple/billApi.js +123 -0
- package/src/views/demo/bizTab/simple/detail.vue +407 -0
- package/src/views/demo/bizTab/simple/list.vue +217 -0
- package/src/views/demo/bizTab/standalone/index.vue +121 -0
- package/src/views/demo/bizTab/wf/billConfig.js +44 -0
- package/src/views/demo/bizTab/wf/detail.vue +661 -0
- package/src/views/demo/bizTab/wf/list.vue +242 -0
- package/src/views/user/home/wjl/content.vue +1569 -0
- package/src/views/user/outLink/cc_form_view.vue +188 -0
package/package.json
CHANGED
|
@@ -176,20 +176,20 @@
|
|
|
176
176
|
/>
|
|
177
177
|
<!-- H5 非图片文件预览:结构与 mobile/wf/content.vue 的流程图预览一致,
|
|
178
178
|
样式走 xform/styles/h5.scss 块 L 的 .pop-box(全屏 fixed + 内部 flex)。
|
|
179
|
-
只在宿主传了 h5Preview 时才会被 openPreview 打开,PC 上永远不渲染。 -->
|
|
180
|
-
<el-dialog
|
|
181
|
-
title="文件预览"
|
|
182
|
-
:modal-append-to-body="false"
|
|
183
|
-
:close-on-click-modal="false"
|
|
184
|
-
:visible.sync="showFilePreviewDialog"
|
|
185
|
-
:modal="false"
|
|
186
|
-
custom-class="dialog-style h5view-dialog"
|
|
187
|
-
width="100%"
|
|
188
|
-
top="0px"
|
|
189
|
-
v-el-drag-dialog
|
|
190
|
-
v-el-dialog-center
|
|
191
|
-
:append-to-body ="true"
|
|
192
|
-
:destroy-on-close="true"
|
|
179
|
+
只在宿主传了 h5Preview 时才会被 openPreview 打开,PC 上永远不渲染。 -->
|
|
180
|
+
<el-dialog
|
|
181
|
+
title="文件预览"
|
|
182
|
+
:modal-append-to-body="false"
|
|
183
|
+
:close-on-click-modal="false"
|
|
184
|
+
:visible.sync="showFilePreviewDialog"
|
|
185
|
+
:modal="false"
|
|
186
|
+
custom-class="dialog-style h5view-dialog"
|
|
187
|
+
width="100%"
|
|
188
|
+
top="0px"
|
|
189
|
+
v-el-drag-dialog
|
|
190
|
+
v-el-dialog-center
|
|
191
|
+
:append-to-body ="true"
|
|
192
|
+
:destroy-on-close="true"
|
|
193
193
|
>
|
|
194
194
|
<div class="flex">
|
|
195
195
|
<div class="form-box">
|
|
@@ -201,17 +201,17 @@
|
|
|
201
201
|
:src="previewFileUrl"
|
|
202
202
|
></iframe>
|
|
203
203
|
</div>
|
|
204
|
-
</div>
|
|
205
|
-
<span slot="footer" class="dialog-footer">
|
|
206
|
-
<el-button
|
|
207
|
-
type="primary"
|
|
208
|
-
plain
|
|
209
|
-
class="button-sty"
|
|
210
|
-
icon="el-icon-close"
|
|
211
|
-
@click="showFilePreviewDialog = false"
|
|
212
|
-
>{{$t2('关 闭', 'system.button.close2')}}</el-button
|
|
213
|
-
>
|
|
214
|
-
</span>
|
|
204
|
+
</div>
|
|
205
|
+
<span slot="footer" class="dialog-footer">
|
|
206
|
+
<el-button
|
|
207
|
+
type="primary"
|
|
208
|
+
plain
|
|
209
|
+
class="button-sty"
|
|
210
|
+
icon="el-icon-close"
|
|
211
|
+
@click="showFilePreviewDialog = false"
|
|
212
|
+
>{{$t2('关 闭', 'system.button.close2')}}</el-button
|
|
213
|
+
>
|
|
214
|
+
</span>
|
|
215
215
|
</el-dialog>
|
|
216
216
|
</div>
|
|
217
217
|
</template>
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 导出字段勾选记忆的读写口径。
|
|
3
|
+
*
|
|
4
|
+
* 记忆存在表格的运行时状态里(随 addTableJson 落到服务端那条表格记录),历史上只有两条:
|
|
5
|
+
* - `exportColumns` 主表导出,一张表只有一套表格列,整体重写即可;
|
|
6
|
+
* - `exportItemColumns` 明细导出,**整张表共用一条扁平的 field→export 表**。
|
|
7
|
+
*
|
|
8
|
+
* 后者在"同一张表挂多个明细导出按钮、各配各的列"的用法下会串台:按钮 A 与按钮 B 只要
|
|
9
|
+
* 字段名有交集(order_no / create_date 这类基础字段几乎必然交集),A 的勾选就会被 B 覆盖。
|
|
10
|
+
* 且同一按钮内部若配了两条同字段的列(如「服务单价」「网点服务费」都取 site_amount),
|
|
11
|
+
* 保存时后者会覆盖前者,前者的勾选态永远存不下来。
|
|
12
|
+
*
|
|
13
|
+
* 现在改为按按钮分组存放:`exportItemColumnsMap = { [按钮名]: [{field, export}] }`,
|
|
14
|
+
* 组内条目**按该按钮的导出列顺序排列**,读取时同名字段按出现次序一一对应,重复字段互不干扰。
|
|
15
|
+
*
|
|
16
|
+
* 兼容:
|
|
17
|
+
* - 旧记录里的扁平 `exportItemColumns` 仍然读,作为"该按钮还没有自己那组"时的回落;
|
|
18
|
+
* 回落匹配退化为首个同名条目(扁平表是跨按钮合并出来的,顺序本就没有意义)。
|
|
19
|
+
* - 拿不到按钮名时(自定义脚本直接调 $excelExport)行为与改造前完全一致:读写扁平表。
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/** 表格状态里存放按钮分组记忆的键名。 */
|
|
23
|
+
export const ITEM_MEMORY_MAP_KEY = "exportItemColumnsMap";
|
|
24
|
+
/** 表格状态里存放扁平(跨按钮共用)记忆的键名,仅作回落。 */
|
|
25
|
+
export const ITEM_MEMORY_FLAT_KEY = "exportItemColumns";
|
|
26
|
+
/** 表格状态里存放主表导出记忆的键名。 */
|
|
27
|
+
export const MAIN_MEMORY_KEY = "exportColumns";
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* 把记忆条目整理成"字段 → 勾选态队列",供按序取用。
|
|
31
|
+
* @param {Array} entries 记忆条目 `[{field, export}]`。
|
|
32
|
+
* @param {Boolean} ordered 同名字段是否按出现次序一一对应;false 时恒取首个。
|
|
33
|
+
* @returns {{next: function(String): (Boolean|undefined)}} 读取器;
|
|
34
|
+
* `next(field)` 返回 true/false 表示记过,undefined 表示没记过(调用方按"新增列"处理)。
|
|
35
|
+
*/
|
|
36
|
+
export function createMemoryReader(entries, ordered = true) {
|
|
37
|
+
let queues = new Map();
|
|
38
|
+
(entries || []).forEach((item) => {
|
|
39
|
+
if (!item || !item.field) return;
|
|
40
|
+
if (!queues.has(item.field)) queues.set(item.field, []);
|
|
41
|
+
queues.get(item.field).push(!!item.export);
|
|
42
|
+
});
|
|
43
|
+
let cursors = new Map();
|
|
44
|
+
return {
|
|
45
|
+
next(field) {
|
|
46
|
+
let queue = queues.get(field);
|
|
47
|
+
if (!queue || !queue.length) return undefined;
|
|
48
|
+
if (!ordered) return queue[0];
|
|
49
|
+
let index = cursors.get(field) || 0;
|
|
50
|
+
// 记忆条目比当前同名列少(后来又加了一条同字段的列):多出来的按"没记过"处理
|
|
51
|
+
if (index >= queue.length) return undefined;
|
|
52
|
+
cursors.set(field, index + 1);
|
|
53
|
+
return queue[index];
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* 取本次明细导出该用的勾选记忆。
|
|
60
|
+
* @param {Object} $vxeTableUtil 表格状态工具($grid 上的读写口径收在这里)。
|
|
61
|
+
* @param {Object} $grid vxe-grid 实例。
|
|
62
|
+
* @param {String} [buttonName] 导出按钮标识;缺省时读扁平表。
|
|
63
|
+
* @returns {{next: function(String): (Boolean|undefined)}} 读取器。
|
|
64
|
+
*/
|
|
65
|
+
export function getItemMemoryReader($vxeTableUtil, $grid, buttonName) {
|
|
66
|
+
if (buttonName) {
|
|
67
|
+
let map = $vxeTableUtil.getTableStateValue($grid, ITEM_MEMORY_MAP_KEY);
|
|
68
|
+
let entries = map && map[buttonName];
|
|
69
|
+
// 该按钮已经有自己那组:按序匹配,重复字段互不干扰
|
|
70
|
+
if (entries && entries.length) return createMemoryReader(entries, true);
|
|
71
|
+
}
|
|
72
|
+
// 回落到改造前的扁平表(旧记录 / 无按钮标识)
|
|
73
|
+
let flat = $vxeTableUtil.getTableStateValue($grid, ITEM_MEMORY_FLAT_KEY);
|
|
74
|
+
return createMemoryReader(flat, false);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* 保存本次明细导出的勾选记忆。
|
|
79
|
+
*
|
|
80
|
+
* 有按钮标识时整组重写(组内就是该按钮自己的列,重写可顺带清掉已删除的列),
|
|
81
|
+
* 其它按钮那几组原样保留;无按钮标识时沿用改造前的扁平表增量合并。
|
|
82
|
+
* @param {Object} $vxeTableUtil 表格状态工具。
|
|
83
|
+
* @param {Object} $grid vxe-grid 实例。
|
|
84
|
+
* @param {String} [buttonName] 导出按钮标识。
|
|
85
|
+
* @param {Array} entries 本次的记忆条目 `[{field, export}]`,须与导出列同序。
|
|
86
|
+
*/
|
|
87
|
+
export function saveItemMemory($vxeTableUtil, $grid, buttonName, entries) {
|
|
88
|
+
if (!entries || !entries.length) return;
|
|
89
|
+
if (buttonName) {
|
|
90
|
+
let oldMap = $vxeTableUtil.getTableStateValue($grid, ITEM_MEMORY_MAP_KEY);
|
|
91
|
+
let map = { ...(oldMap || {}) };
|
|
92
|
+
map[buttonName] = entries;
|
|
93
|
+
$vxeTableUtil.setTableState($grid, ITEM_MEMORY_MAP_KEY, map);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
// 扁平表是跨按钮共用的,整体覆盖会清掉别人的记忆,只能按字段增量合并
|
|
97
|
+
let flat = (
|
|
98
|
+
$vxeTableUtil.getTableStateValue($grid, ITEM_MEMORY_FLAT_KEY) || []
|
|
99
|
+
).map((item) => ({ ...item }));
|
|
100
|
+
entries.forEach((entry) => {
|
|
101
|
+
let item = flat.find((t) => t.field === entry.field);
|
|
102
|
+
if (!item) {
|
|
103
|
+
item = { field: entry.field };
|
|
104
|
+
flat.push(item);
|
|
105
|
+
}
|
|
106
|
+
item.export = entry.export;
|
|
107
|
+
});
|
|
108
|
+
$vxeTableUtil.setTableState($grid, ITEM_MEMORY_FLAT_KEY, flat);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export default {
|
|
112
|
+
ITEM_MEMORY_MAP_KEY,
|
|
113
|
+
ITEM_MEMORY_FLAT_KEY,
|
|
114
|
+
MAIN_MEMORY_KEY,
|
|
115
|
+
createMemoryReader,
|
|
116
|
+
getItemMemoryReader,
|
|
117
|
+
saveItemMemory,
|
|
118
|
+
};
|
|
@@ -45,6 +45,11 @@
|
|
|
45
45
|
import xeUtils from "xe-utils";
|
|
46
46
|
import { isItemExport } from "./exportType";
|
|
47
47
|
import { getExportItemColumns } from "./exportItemConfigUtil";
|
|
48
|
+
import {
|
|
49
|
+
MAIN_MEMORY_KEY,
|
|
50
|
+
getItemMemoryReader,
|
|
51
|
+
saveItemMemory,
|
|
52
|
+
} from "./exportColumnMemory";
|
|
48
53
|
export default {
|
|
49
54
|
name: "exportFieldDialog",
|
|
50
55
|
props: ["param"],
|
|
@@ -166,27 +171,24 @@ export default {
|
|
|
166
171
|
let defaultCheckedKeys = [];
|
|
167
172
|
let cols = [];
|
|
168
173
|
|
|
169
|
-
let yesFields = [];
|
|
170
|
-
let noFields = [];
|
|
171
|
-
|
|
172
|
-
let exportColumns =
|
|
173
|
-
this.$vxeTableUtil.getTableStateValue(
|
|
174
|
-
target,
|
|
175
|
-
!exportItem ? "exportColumns" : "exportItemColumns"
|
|
176
|
-
) || [];
|
|
177
|
-
|
|
178
|
-
this.loopColumnHandle(exportColumns, (item) => {
|
|
179
|
-
if (item.field) {
|
|
180
|
-
if (item.export) {
|
|
181
|
-
yesFields.push(item.field);
|
|
182
|
-
} else {
|
|
183
|
-
noFields.push(item.field);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
});
|
|
187
|
-
|
|
188
174
|
if (!exportItem) {
|
|
189
175
|
//导出主表数据
|
|
176
|
+
// 主表列一张表只有一套,记忆仍是一条扁平的 field→export 表
|
|
177
|
+
let yesFields = [];
|
|
178
|
+
let noFields = [];
|
|
179
|
+
let mainMemory = this.$vxeTableUtil.getTableStateValue(
|
|
180
|
+
target,
|
|
181
|
+
MAIN_MEMORY_KEY
|
|
182
|
+
);
|
|
183
|
+
this.loopColumnHandle(mainMemory || [], (item) => {
|
|
184
|
+
if (item.field) {
|
|
185
|
+
if (item.export) {
|
|
186
|
+
yesFields.push(item.field);
|
|
187
|
+
} else {
|
|
188
|
+
noFields.push(item.field);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
});
|
|
190
192
|
|
|
191
193
|
fullColumn.forEach((column) => {
|
|
192
194
|
if (column.field && !column.params?.exportDisabled) {
|
|
@@ -211,12 +213,18 @@ export default {
|
|
|
211
213
|
// 配了 checkMethod 时才有内容,而全库未配任何 checkMethod → 恒为空数组 → 明细列
|
|
212
214
|
// 一个都勾不上,连 exportItemColumns 的勾选记忆也一并失效。明细列与主表列本就是两套
|
|
213
215
|
// 字段,取交集没有意义,故去掉该门槛。
|
|
216
|
+
//
|
|
217
|
+
// 记忆按导出按钮分组存放(详见 exportColumnMemory.js):next 必须按导出列顺序、
|
|
218
|
+
// 对每个有字段的列各调一次,重复字段才能按出现次序一一对应。
|
|
219
|
+
let reader = getItemMemoryReader(
|
|
220
|
+
this.$vxeTableUtil,
|
|
221
|
+
target,
|
|
222
|
+
this.getExportButtonName()
|
|
223
|
+
);
|
|
214
224
|
this.loopColumnHandle(oriExportItemColumns, (item) => {
|
|
215
225
|
item.id = this.generateId();
|
|
216
226
|
if (!item.field) return;
|
|
217
|
-
|
|
218
|
-
let isNo = noFields.includes(item.field);
|
|
219
|
-
if (isYes || !isNo) {
|
|
227
|
+
if (reader.next(item.field) !== false) {
|
|
220
228
|
defaultCheckedKeys.push(item.id);
|
|
221
229
|
}
|
|
222
230
|
});
|
|
@@ -260,29 +268,26 @@ export default {
|
|
|
260
268
|
exportColumns.push(item);
|
|
261
269
|
}
|
|
262
270
|
});
|
|
263
|
-
this.$vxeTableUtil.setTableState($grid,
|
|
271
|
+
this.$vxeTableUtil.setTableState($grid, MAIN_MEMORY_KEY, exportColumns);
|
|
264
272
|
} else {
|
|
265
273
|
//导出子表数据
|
|
266
274
|
let columns = this.getExportItemColumns();
|
|
267
275
|
if (columns.length) {
|
|
268
|
-
//
|
|
269
|
-
//
|
|
270
|
-
let
|
|
271
|
-
this.$vxeTableUtil.getTableStateValue($grid, "exportItemColumns") || []
|
|
272
|
-
).map((item) => ({ ...item }));
|
|
276
|
+
// 条目顺序必须与导出列一致:读取端靠这个顺序把同名字段一一对应上。
|
|
277
|
+
// 判定条件也要与读取端一致(只看 field),否则两端的游标会错位。
|
|
278
|
+
let entries = [];
|
|
273
279
|
this.loopColumnHandle(columns, (column) => {
|
|
274
|
-
if (!column.field
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
}
|
|
280
|
-
item.export = checkLeafIds.includes(column.id);
|
|
280
|
+
if (!column.field) return;
|
|
281
|
+
entries.push({
|
|
282
|
+
field: column.field,
|
|
283
|
+
export: checkLeafIds.includes(column.id),
|
|
284
|
+
});
|
|
281
285
|
});
|
|
282
|
-
|
|
286
|
+
saveItemMemory(
|
|
287
|
+
this.$vxeTableUtil,
|
|
283
288
|
$grid,
|
|
284
|
-
|
|
285
|
-
|
|
289
|
+
this.getExportButtonName(),
|
|
290
|
+
entries
|
|
286
291
|
);
|
|
287
292
|
}
|
|
288
293
|
}
|
|
@@ -367,6 +372,13 @@ export default {
|
|
|
367
372
|
getExportItemColumns() {
|
|
368
373
|
return getExportItemColumns(this.param, this.getGrid());
|
|
369
374
|
},
|
|
375
|
+
/**
|
|
376
|
+
* @returns {String|null} 本次导出的按钮标识(勾选记忆按它分组)。自定义脚本直接调
|
|
377
|
+
* $excelExport 时没有这一项,此时记忆退回改造前的表格级扁平表。
|
|
378
|
+
*/
|
|
379
|
+
getExportButtonName() {
|
|
380
|
+
return this.param?.exportButtonName || null;
|
|
381
|
+
},
|
|
370
382
|
getGrid() {
|
|
371
383
|
let that = this.param.vue;
|
|
372
384
|
let tableRef = this.param.targetRef;
|
|
@@ -4,17 +4,27 @@ import excelExport from "./index.vue";
|
|
|
4
4
|
const moudule = {};
|
|
5
5
|
const ExcelExportInstance = vue.extend(excelExport);
|
|
6
6
|
let instance = null;
|
|
7
|
+
/**
|
|
8
|
+
* 回收一个导出实例:销毁 vue 实例并摘掉 DOM。
|
|
9
|
+
* 只认传进来的这一个 —— 期间可能已经有新的导出把模块级 instance 顶掉,
|
|
10
|
+
* 那个新实例还在跑,不能连坐。
|
|
11
|
+
* @param {Object} target 要回收的导出实例
|
|
12
|
+
*/
|
|
13
|
+
function destroyInstance(target) {
|
|
14
|
+
if (!target) return;
|
|
15
|
+
try {
|
|
16
|
+
// $destroy 会走组件的 beforeDestroy:置终止标记、停定时器、掐在途请求、解页签锁
|
|
17
|
+
target.$destroy();
|
|
18
|
+
target.$el && target.$el.remove();
|
|
19
|
+
} catch (e) {
|
|
20
|
+
console.error(e);
|
|
21
|
+
}
|
|
22
|
+
if (instance === target) instance = null;
|
|
23
|
+
}
|
|
24
|
+
|
|
7
25
|
const initInstance = (containter) => {
|
|
8
26
|
// 已有未销毁的导出实例时先销毁,避免覆盖引用造成旧实例与 DOM 泄漏
|
|
9
|
-
|
|
10
|
-
try {
|
|
11
|
-
instance.$destroy();
|
|
12
|
-
instance.$el && instance.$el.remove();
|
|
13
|
-
} catch (e) {
|
|
14
|
-
console.error(e);
|
|
15
|
-
}
|
|
16
|
-
instance = null;
|
|
17
|
-
}
|
|
27
|
+
destroyInstance(instance);
|
|
18
28
|
// 实例化vue实例
|
|
19
29
|
instance = new ExcelExportInstance({ i18n: window.$vueRoot._i18n }).$mount();
|
|
20
30
|
let dom = instance.$el;
|
|
@@ -29,6 +39,12 @@ function toDo(options) {
|
|
|
29
39
|
|
|
30
40
|
let vueTarget = this && this.$el ? this : window.$vueRoot;
|
|
31
41
|
let currentInstance = initInstance(containter);
|
|
42
|
+
// 导出实例是独立根实例:DOM 虽然 append 在宿主 $el 里,但两者没有父子关系。
|
|
43
|
+
// 宿主销毁(关页签、页面重建)只会把 DOM 带走,实例本身连同定时器、在途请求、
|
|
44
|
+
// 页签锁全都留着,要等下一次导出的 initInstance 才回收。把回收挂到宿主销毁上。
|
|
45
|
+
if (this && typeof this.$once === "function") {
|
|
46
|
+
this.$once("hook:beforeDestroy", () => destroyInstance(currentInstance));
|
|
47
|
+
}
|
|
32
48
|
currentInstance.param = {};
|
|
33
49
|
Object.assign(
|
|
34
50
|
currentInstance.param,
|
|
@@ -39,11 +55,12 @@ function toDo(options) {
|
|
|
39
55
|
}
|
|
40
56
|
|
|
41
57
|
function destroyComponent(loadingObj) {
|
|
42
|
-
|
|
58
|
+
// 必须在调用当时就捉住实例:下面的 setTimeout 里再读模块级 instance,
|
|
59
|
+
// 期间新开的一次导出会被误销毁
|
|
60
|
+
let target = instance;
|
|
61
|
+
if (target) {
|
|
43
62
|
setTimeout(() => {
|
|
44
|
-
|
|
45
|
-
instance.$el.remove(); // 移除 DOM 节点
|
|
46
|
-
instance = null;
|
|
63
|
+
destroyInstance(target);
|
|
47
64
|
if (loadingObj) {
|
|
48
65
|
setTimeout(function () {
|
|
49
66
|
loadingObj.close();
|