Skip to content

Commit cc7df9a

Browse files
committed
feat: use postFlush instead of promise
1 parent 2faa221 commit cc7df9a

File tree

2 files changed

+18
-13
lines changed

2 files changed

+18
-13
lines changed

packages/runtime-core/src/directives.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ export type DirectiveHook<T = any, Prev = VNode<any, T> | null, V = any> = (
4040
binding: DirectiveBinding<V>,
4141
vnode: VNode<any, T>,
4242
prevVNode: Prev,
43+
// register a callback witch will be called
44+
// after all dirHooks have been executed
45+
postFlushDirs?: (fn: () => void) => void,
4346
) => void
4447

4548
export type SSRDirectiveHook = (
@@ -129,6 +132,7 @@ export function invokeDirectiveHook(
129132
) {
130133
const bindings = vnode.dirs!
131134
const oldBindings = prevVNode && prevVNode.dirs!
135+
const postFlushDirsQueue: (() => void)[] = []
132136
for (let i = 0; i < bindings.length; i++) {
133137
const binding = bindings[i]
134138
if (oldBindings) {
@@ -147,8 +151,13 @@ export function invokeDirectiveHook(
147151
binding,
148152
vnode,
149153
prevVNode,
154+
(fn: () => void) => {
155+
postFlushDirsQueue.push(fn)
156+
},
150157
])
151158
resetTracking()
152159
}
153160
}
161+
postFlushDirsQueue.forEach(postDir => postDir())
162+
postFlushDirsQueue.length = 0
154163
}

packages/runtime-dom/src/directives/vShow.ts

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ interface VShowElement extends HTMLElement {
77
[vShowOriginalDisplay]: string
88
}
99

10-
const resolvedPromise = Promise.resolve()
11-
1210
export const vShow: ObjectDirective<VShowElement> & { name?: 'show' } = {
1311
beforeMount(el, { value }, { transition }) {
1412
el[vShowOriginalDisplay] =
@@ -24,17 +22,19 @@ export const vShow: ObjectDirective<VShowElement> & { name?: 'show' } = {
2422
transition.enter(el)
2523
}
2624
},
27-
updated(el, { value, oldValue }, { transition }) {
25+
updated(el, { value, oldValue }, { transition }, _, postFlush) {
2826
if (
2927
!value === !oldValue &&
3028
(el.style.display === el[vShowOriginalDisplay] || (!value && transition))
3129
)
3230
return
3331
if (transition) {
3432
if (value) {
35-
transition.beforeEnter(el)
36-
setDisplay(el, true)
37-
transition.enter(el)
33+
postFlush!(() => {
34+
transition.beforeEnter(el)
35+
setDisplay(el, true)
36+
transition.enter(el)
37+
})
3838
} else {
3939
transition.leave(el, () => {
4040
setDisplay(el, false)
@@ -44,7 +44,9 @@ export const vShow: ObjectDirective<VShowElement> & { name?: 'show' } = {
4444
// #10038
4545
// when multi vShow be applied to the same element
4646
// and the sync setDisplay will impact other vShow
47-
postSetDisplay(el, value)
47+
postFlush!(() => {
48+
setDisplay(el, value)
49+
})
4850
}
4951
},
5052
beforeUnmount(el, { value }) {
@@ -60,12 +62,6 @@ function setDisplay(el: VShowElement, value: unknown): void {
6062
el.style.display = value ? el[vShowOriginalDisplay] : 'none'
6163
}
6264

63-
function postSetDisplay(el: VShowElement, value: unknown): void {
64-
resolvedPromise.then(() => {
65-
setDisplay(el, value)
66-
})
67-
}
68-
6965
// SSR vnode transforms, only used when user includes client-oriented render
7066
// function in SSR
7167
export function initVShowForSSR() {

0 commit comments

Comments
 (0)