fix: replaceable vnode caused memory leak

This commit is contained in:
07akioni 2024-12-19 17:30:29 +08:00
parent 36a311cf49
commit 5de9c45707
19 changed files with 160 additions and 54 deletions

View File

@ -1,8 +1,7 @@
import { h } from 'vue'
import { replaceable } from './replaceable'
export default replaceable(
'cancel',
export default replaceable('cancel', () => (
<svg viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g fill="currentColor" fill-rule="nonzero">
@ -10,4 +9,4 @@ export default replaceable(
</g>
</g>
</svg>
)
))

View File

@ -1,8 +1,7 @@
import { h } from 'vue'
import { replaceable } from './replaceable'
export default replaceable(
'clear',
export default replaceable('clear', () => (
<svg viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g fill="currentColor" fill-rule="nonzero">
@ -10,4 +9,4 @@ export default replaceable(
</g>
</g>
</svg>
)
))

View File

@ -1,8 +1,7 @@
import { h } from 'vue'
import { replaceable } from './replaceable'
export default replaceable(
'close',
export default replaceable('close', () => (
<svg
viewBox="0 0 12 12"
version="1.1"
@ -15,4 +14,4 @@ export default replaceable(
</g>
</g>
</svg>
)
))

View File

@ -1,8 +1,7 @@
import { h } from 'vue'
import { replaceable } from './replaceable'
export default replaceable(
'date',
export default replaceable('date', () => (
<svg
width="28px"
height="28px"
@ -16,4 +15,4 @@ export default replaceable(
</g>
</g>
</svg>
)
))

View File

@ -1,8 +1,7 @@
import { h } from 'vue'
import { replaceable } from './replaceable'
export default replaceable(
'download',
export default replaceable('download', () => (
<svg viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g fill="currentColor" fill-rule="nonzero">
@ -10,4 +9,4 @@ export default replaceable(
</g>
</g>
</svg>
)
))

View File

@ -1,8 +1,7 @@
import { h } from 'vue'
import { replaceable } from './replaceable'
export default replaceable(
'error',
export default replaceable('error', () => (
<svg viewBox="0 0 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg">
<g stroke="none" stroke-width="1" fill-rule="evenodd">
<g fill-rule="nonzero">
@ -10,4 +9,4 @@ export default replaceable(
</g>
</g>
</svg>
)
))

View File

@ -1,8 +1,7 @@
import { h } from 'vue'
import { replaceable } from './replaceable'
export default replaceable(
'info',
export default replaceable('info', () => (
<svg viewBox="0 0 28 28" version="1.1" xmlns="http://www.w3.org/2000/svg">
<g stroke="none" stroke-width="1" fill-rule="evenodd">
<g fill-rule="nonzero">
@ -10,4 +9,4 @@ export default replaceable(
</g>
</g>
</svg>
)
))

View File

@ -1,8 +1,7 @@
import { h } from 'vue'
import { replaceable } from './replaceable'
export default replaceable(
'retry',
export default replaceable('retry', () => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path
d="M320,146s24.36-12-64-12A160,160,0,1,0,416,294"
@ -13,4 +12,4 @@ export default replaceable(
style="fill: none; stroke: currentcolor; stroke-linecap: round; stroke-linejoin: round; stroke-width: 32px;"
/>
</svg>
)
))

View File

@ -1,8 +1,7 @@
import { h } from 'vue'
import { replaceable } from './replaceable'
export default replaceable(
'rotateClockwise',
export default replaceable('rotateClockwise', () => (
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M3 10C3 6.13401 6.13401 3 10 3C13.866 3 17 6.13401 17 10C17 12.7916 15.3658 15.2026 13 16.3265V14.5C13 14.2239 12.7761 14 12.5 14C12.2239 14 12 14.2239 12 14.5V17.5C12 17.7761 12.2239 18 12.5 18H15.5C15.7761 18 16 17.7761 16 17.5C16 17.2239 15.7761 17 15.5 17H13.8758C16.3346 15.6357 18 13.0128 18 10C18 5.58172 14.4183 2 10 2C5.58172 2 2 5.58172 2 10C2 10.2761 2.22386 10.5 2.5 10.5C2.77614 10.5 3 10.2761 3 10Z"
@ -15,4 +14,4 @@ export default replaceable(
>
</path>
</svg>
)
))

View File

@ -1,8 +1,7 @@
import { h } from 'vue'
import { replaceable } from './replaceable'
export default replaceable(
'rotateClockwise',
export default replaceable('rotateClockwise', () => (
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M17 10C17 6.13401 13.866 3 10 3C6.13401 3 3 6.13401 3 10C3 12.7916 4.63419 15.2026 7 16.3265V14.5C7 14.2239 7.22386 14 7.5 14C7.77614 14 8 14.2239 8 14.5V17.5C8 17.7761 7.77614 18 7.5 18H4.5C4.22386 18 4 17.7761 4 17.5C4 17.2239 4.22386 17 4.5 17H6.12422C3.66539 15.6357 2 13.0128 2 10C2 5.58172 5.58172 2 10 2C14.4183 2 18 5.58172 18 10C18 10.2761 17.7761 10.5 17.5 10.5C17.2239 10.5 17 10.2761 17 10Z"
@ -15,4 +14,4 @@ export default replaceable(
>
</path>
</svg>
)
))

View File

@ -1,8 +1,7 @@
import { h } from 'vue'
import { replaceable } from './replaceable'
export default replaceable(
'success',
export default replaceable('success', () => (
<svg viewBox="0 0 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg">
<g stroke="none" stroke-width="1" fill-rule="evenodd">
<g fill-rule="nonzero">
@ -10,4 +9,4 @@ export default replaceable(
</g>
</g>
</svg>
)
))

View File

@ -1,8 +1,7 @@
import { h } from 'vue'
import { replaceable } from './replaceable'
export default replaceable(
'time',
export default replaceable('time', () => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path
d="M256,64C150,64,64,150,64,256s86,192,192,192,192-86,192-192S362,64,256,64Z"
@ -24,4 +23,4 @@ export default replaceable(
"
/>
</svg>
)
))

View File

@ -1,8 +1,7 @@
import { h } from 'vue'
import { replaceable } from './replaceable'
export default replaceable(
'to',
export default replaceable('to', () => (
<svg viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g fill="currentColor" fill-rule="nonzero">
@ -10,4 +9,4 @@ export default replaceable(
</g>
</g>
</svg>
)
))

View File

@ -1,8 +1,7 @@
import { h } from 'vue'
import { replaceable } from './replaceable'
export default replaceable(
'trash',
export default replaceable('trash', () => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path
d="M432,144,403.33,419.74A32,32,0,0,1,371.55,448H140.46a32,32,0,0,1-31.78-28.26L80,144"
@ -36,4 +35,4 @@ export default replaceable(
>
</line>
</svg>
)
))

View File

@ -1,8 +1,7 @@
import { h } from 'vue'
import { replaceable } from './replaceable'
export default replaceable(
'warning',
export default replaceable('warning', () => (
<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg">
<g stroke="none" stroke-width="1" fill-rule="evenodd">
<g fill-rule="nonzero">
@ -10,4 +9,4 @@ export default replaceable(
</g>
</g>
</svg>
)
))

View File

@ -1,8 +1,7 @@
import { h } from 'vue'
import { replaceable } from './replaceable'
export default replaceable(
'zoomIn',
export default replaceable('zoomIn', () => (
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M11.5 8.5C11.5 8.22386 11.2761 8 11 8H9V6C9 5.72386 8.77614 5.5 8.5 5.5C8.22386 5.5 8 5.72386 8 6V8H6C5.72386 8 5.5 8.22386 5.5 8.5C5.5 8.77614 5.72386 9 6 9H8V11C8 11.2761 8.22386 11.5 8.5 11.5C8.77614 11.5 9 11.2761 9 11V9H11C11.2761 9 11.5 8.77614 11.5 8.5Z"
@ -15,4 +14,4 @@ export default replaceable(
>
</path>
</svg>
)
))

View File

@ -1,8 +1,7 @@
import { h } from 'vue'
import { replaceable } from './replaceable'
export default replaceable(
'zoomOut',
export default replaceable('zoomOut', () => (
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M11 8C11.2761 8 11.5 8.22386 11.5 8.5C11.5 8.77614 11.2761 9 11 9H6C5.72386 9 5.5 8.77614 5.5 8.5C5.5 8.22386 5.72386 8 6 8H11Z"
@ -15,4 +14,4 @@ export default replaceable(
>
</path>
</svg>
)
))

View File

@ -1,9 +1,15 @@
import type { VNode } from 'vue'
import type { GlobalIconConfig } from '../../config-provider/src/internal-interface'
import { upperFirst } from 'lodash-es'
import { defineComponent, inject } from 'vue'
import { defineComponent, h, inject } from 'vue'
import { configProviderInjectionKey } from '../../config-provider/src/context'
export function replaceable(name: keyof GlobalIconConfig, icon: JSX.Element) {
export function replaceable(name: keyof GlobalIconConfig, icon: () => VNode) {
const IconComponent = defineComponent({
render() {
return icon()
}
})
return defineComponent({
name: upperFirst(name),
setup() {
@ -13,7 +19,7 @@ export function replaceable(name: keyof GlobalIconConfig, icon: JSX.Element) {
)?.mergedIconsRef
return () => {
const iconOverride = mergedIconsRef?.value?.[name]
return iconOverride ? iconOverride() : icon
return iconOverride ? iconOverride() : <IconComponent />
}
}
})

117
test.html Normal file

File diff suppressed because one or more lines are too long