Skip to content

Commit c53d343

Browse files
committed
feat: reset tree store before unmount
1 parent 451512d commit c53d343

File tree

2 files changed

+46
-15
lines changed

2 files changed

+46
-15
lines changed

src/components/Tree.vue

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ import {
6565
computed,
6666
watch,
6767
onMounted,
68+
onBeforeUnmount,
6869
PropType
6970
} from 'vue-demi'
7071
import TreeStore, { TreeNode } from '../store'
@@ -80,8 +81,14 @@ import {
8081
TREE_NODE_EVENTS
8182
} from '../const'
8283
import { TreeNodeKeyType, IgnoreType } from '../types'
84+
8385
type AnyPropsArrayType = Array<{ [key: string]: any }>
8486
type VModelType = TreeNodeKeyType | TreeNodeKeyType[]
87+
interface INonReactiveData {
88+
store: TreeStore
89+
blockNodes: TreeNode[]
90+
}
91+
8592
const 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,

src/store/tree-store.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,5 +1212,11 @@ export default class TreeStore {
12121212
this.listenersMap[eventName][i](...args)
12131213
}
12141214
}
1215+
1216+
disposeListeners(): void {
1217+
for (const eventName in this.listenersMap) {
1218+
this.listenersMap[eventName] = []
1219+
}
1220+
}
12151221
//#endregion Mini EventTarget
12161222
}

0 commit comments

Comments
 (0)