@@ -65,6 +65,7 @@ import {
6565 computed ,
6666 watch ,
6767 onMounted ,
68+ onBeforeUnmount ,
6869 PropType
6970} from ' vue-demi'
7071import TreeStore , { TreeNode } from ' ../store'
@@ -80,8 +81,14 @@ import {
8081 TREE_NODE_EVENTS
8182} from ' ../const'
8283import { TreeNodeKeyType , IgnoreType } from ' ../types'
84+
8385type AnyPropsArrayType = Array <{ [key : string ]: any }>
8486type VModelType = TreeNodeKeyType | TreeNodeKeyType []
87+ interface INonReactiveData {
88+ store: TreeStore
89+ blockNodes: TreeNode []
90+ }
91+
8592const storeEvents: Array <keyof IEventNames > = [
8693 ' expand' ,
8794 ' select' ,
@@ -360,7 +367,7 @@ export default defineComponent({
360367 ) as Ref <VModelType >
361368 const debounceTimer = ref (undefined ) as Ref <number | undefined >
362369 const scrollArea = ref ()
363- const iframe = ref ()
370+ const iframe = ref < HTMLIFrameElement | undefined > ()
364371 // computed
365372 const topSpaceStyles = computed (() => {
366373 return {
@@ -407,19 +414,25 @@ export default defineComponent({
407414 }
408415 return prev
409416 }, {} 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+ }
422431 }
432+
433+ // watch
434+ let nonReactive = getInitialNonReactiveValues ()
435+
423436 watch (
424437 () => props .modelValue ,
425438 newVal => {
@@ -1039,12 +1052,24 @@ export default defineComponent({
10391052 }
10401053 loadRootNodes ()
10411054 }
1042- const $iframe: any = iframe
1043- if ($iframe .contentWindow ) {
1055+ const $iframe = iframe . value
1056+ if ($iframe ? .contentWindow ) {
10441057 $iframe .contentWindow .addEventListener (' resize' , updateRender )
10451058 }
10461059 })
10471060
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+
10481073 attachStoreEvents ()
10491074 return {
10501075 nonReactive ,
0 commit comments