feat(transition): handle transition classes when patching classes
This commit is contained in:
parent
7859e4bce3
commit
be9b4b2527
@ -64,19 +64,19 @@ function resolveCSSTransitionData({
|
|||||||
...baseProps,
|
...baseProps,
|
||||||
onBeforeEnter(el) {
|
onBeforeEnter(el) {
|
||||||
onBeforeEnter && onBeforeEnter(el)
|
onBeforeEnter && onBeforeEnter(el)
|
||||||
el.classList.add(enterActiveClass)
|
addTransitionClass(el, enterActiveClass)
|
||||||
el.classList.add(enterFromClass)
|
addTransitionClass(el, enterFromClass)
|
||||||
},
|
},
|
||||||
onEnter(el, done) {
|
onEnter(el, done) {
|
||||||
nextFrame(() => {
|
nextFrame(() => {
|
||||||
const resolve = () => {
|
const resolve = () => {
|
||||||
el.classList.remove(enterToClass)
|
removeTransitionClass(el, enterToClass)
|
||||||
el.classList.remove(enterActiveClass)
|
removeTransitionClass(el, enterActiveClass)
|
||||||
done()
|
done()
|
||||||
}
|
}
|
||||||
onEnter && onEnter(el, resolve)
|
onEnter && onEnter(el, resolve)
|
||||||
el.classList.remove(enterFromClass)
|
removeTransitionClass(el, enterFromClass)
|
||||||
el.classList.add(enterToClass)
|
addTransitionClass(el, enterToClass)
|
||||||
if (!(onEnter && onEnter.length > 1)) {
|
if (!(onEnter && onEnter.length > 1)) {
|
||||||
if (enterDuration) {
|
if (enterDuration) {
|
||||||
setTimeout(resolve, enterDuration)
|
setTimeout(resolve, enterDuration)
|
||||||
@ -87,17 +87,17 @@ function resolveCSSTransitionData({
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
onLeave(el, done) {
|
onLeave(el, done) {
|
||||||
el.classList.add(leaveActiveClass)
|
addTransitionClass(el, leaveActiveClass)
|
||||||
el.classList.add(leaveFromClass)
|
addTransitionClass(el, leaveFromClass)
|
||||||
nextFrame(() => {
|
nextFrame(() => {
|
||||||
const resolve = () => {
|
const resolve = () => {
|
||||||
el.classList.remove(leaveToClass)
|
removeTransitionClass(el, leaveToClass)
|
||||||
el.classList.remove(leaveActiveClass)
|
removeTransitionClass(el, leaveActiveClass)
|
||||||
done()
|
done()
|
||||||
}
|
}
|
||||||
onLeave && onLeave(el, resolve)
|
onLeave && onLeave(el, resolve)
|
||||||
el.classList.remove(leaveFromClass)
|
removeTransitionClass(el, leaveFromClass)
|
||||||
el.classList.add(leaveToClass)
|
addTransitionClass(el, leaveToClass)
|
||||||
if (!(onLeave && onLeave.length > 1)) {
|
if (!(onLeave && onLeave.length > 1)) {
|
||||||
if (leaveDuration) {
|
if (leaveDuration) {
|
||||||
setTimeout(resolve, leaveDuration)
|
setTimeout(resolve, leaveDuration)
|
||||||
@ -143,6 +143,27 @@ function validateDuration(val: unknown) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ElementWithTransition extends Element {
|
||||||
|
// _vtc = Vue Transition Classes.
|
||||||
|
// Store the temporarily-added transition classes on the element
|
||||||
|
// so that we can avoid overwriting them if the element's class is patched
|
||||||
|
// during the transition.
|
||||||
|
_vtc?: Set<string>
|
||||||
|
}
|
||||||
|
|
||||||
|
function addTransitionClass(el: ElementWithTransition, cls: string) {
|
||||||
|
el.classList.add(cls)
|
||||||
|
;(el._vtc || (el._vtc = new Set())).add(cls)
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeTransitionClass(el: ElementWithTransition, cls: string) {
|
||||||
|
el.classList.remove(cls)
|
||||||
|
el._vtc!.delete(cls)
|
||||||
|
if (!el._vtc!.size) {
|
||||||
|
el._vtc = undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function nextFrame(cb: () => void) {
|
function nextFrame(cb: () => void) {
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
requestAnimationFrame(cb)
|
requestAnimationFrame(cb)
|
||||||
|
@ -1,7 +1,17 @@
|
|||||||
|
import { ElementWithTransition } from '../components/CSSTransition'
|
||||||
|
|
||||||
// compiler should normalize class + :class bindings on the same element
|
// compiler should normalize class + :class bindings on the same element
|
||||||
// into a single binding ['staticClass', dynamic]
|
// into a single binding ['staticClass', dynamic]
|
||||||
|
export function patchClass(
|
||||||
export function patchClass(el: Element, value: string, isSVG: boolean) {
|
el: ElementWithTransition,
|
||||||
|
value: string,
|
||||||
|
isSVG: boolean
|
||||||
|
) {
|
||||||
|
// if this is an element during a transition, take the temporary transition
|
||||||
|
// classes into account.
|
||||||
|
if (el._vtc) {
|
||||||
|
value = [value, ...el._vtc].join(' ')
|
||||||
|
}
|
||||||
// directly setting className should be faster than setAttribute in theory
|
// directly setting className should be faster than setAttribute in theory
|
||||||
if (isSVG) {
|
if (isSVG) {
|
||||||
el.setAttribute('class', value)
|
el.setAttribute('class', value)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user