@@ -65,6 +65,7 @@ import {
65
65
computed ,
66
66
watch ,
67
67
onMounted ,
68
+ onBeforeUnmount ,
68
69
PropType
69
70
} from ' vue-demi'
70
71
import TreeStore , { TreeNode } from ' ../store'
@@ -80,8 +81,14 @@ import {
80
81
TREE_NODE_EVENTS
81
82
} from ' ../const'
82
83
import { TreeNodeKeyType , IgnoreType } from ' ../types'
84
+
83
85
type AnyPropsArrayType = Array <{ [key : string ]: any }>
84
86
type VModelType = TreeNodeKeyType | TreeNodeKeyType []
87
+ interface INonReactiveData {
88
+ store: TreeStore
89
+ blockNodes: TreeNode []
90
+ }
91
+
85
92
const storeEvents: Array <keyof IEventNames > = [
86
93
' expand' ,
87
94
' select' ,
@@ -360,7 +367,7 @@ export default defineComponent({
360
367
) as Ref <VModelType >
361
368
const debounceTimer = ref (undefined ) as Ref <number | undefined >
362
369
const scrollArea = ref ()
363
- const iframe = ref ()
370
+ const iframe = ref < HTMLIFrameElement | undefined > ()
364
371
// computed
365
372
const topSpaceStyles = computed (() => {
366
373
return {
@@ -407,19 +414,25 @@ export default defineComponent({
407
414
}
408
415
return prev
409
416
}, {} as Record <string , Function >)
410
- // watch
411
- const nonReactive = {
412
- store: new TreeStore ({
413
- keyField: props .keyField ,
414
- ignoreMode: props .ignoreMode ,
415
- filteredNodeCheckable: props .filteredNodeCheckable ,
416
- cascade: props .cascade ,
417
- defaultExpandAll: props .defaultExpandAll ,
418
- load: props .load ,
419
- expandOnFilter: props .expandOnFilter
420
- }),
421
- blockNodes: [] as TreeNode []
417
+
418
+ const getInitialNonReactiveValues = (): INonReactiveData => {
419
+ return {
420
+ store: new TreeStore ({
421
+ keyField: props .keyField ,
422
+ ignoreMode: props .ignoreMode ,
423
+ filteredNodeCheckable: props .filteredNodeCheckable ,
424
+ cascade: props .cascade ,
425
+ defaultExpandAll: props .defaultExpandAll ,
426
+ load: props .load ,
427
+ expandOnFilter: props .expandOnFilter
428
+ }),
429
+ blockNodes: [] as TreeNode []
430
+ }
422
431
}
432
+
433
+ // watch
434
+ let nonReactive = getInitialNonReactiveValues ()
435
+
423
436
watch (
424
437
() => props .modelValue ,
425
438
newVal => {
@@ -1039,12 +1052,24 @@ export default defineComponent({
1039
1052
}
1040
1053
loadRootNodes ()
1041
1054
}
1042
- const $iframe: any = iframe
1043
- if ($iframe .contentWindow ) {
1055
+ const $iframe = iframe . value
1056
+ if ($iframe ? .contentWindow ) {
1044
1057
$iframe .contentWindow .addEventListener (' resize' , updateRender )
1045
1058
}
1046
1059
})
1047
1060
1061
+ onBeforeUnmount (() => {
1062
+ const $iframe = iframe .value
1063
+ if ($iframe ?.contentWindow ) {
1064
+ $iframe .contentWindow .removeEventListener (' resize' , updateRender )
1065
+ }
1066
+ // 卸载组件之前重置 nonReactive 中的数据,缓解 Vue 切换组件可能导致的内存无法释放问题
1067
+ nonReactive .store .disposeListeners ()
1068
+ const newNonReactive = getInitialNonReactiveValues ()
1069
+ nonReactive .store = newNonReactive .store
1070
+ nonReactive .blockNodes = newNonReactive .blockNodes
1071
+ })
1072
+
1048
1073
attachStoreEvents ()
1049
1074
return {
1050
1075
nonReactive ,
0 commit comments