AnimatePresence
AnimatePresence
让退出动画变得简单。通过包裹一个或多个 motion
组件使用 AnimatePresence
,我们可以访问 exit
动画属性。
<AnimatePresence> <motion.div v-if="show" key="modal" :exit="{ opacity: 0 }" />} </AnimatePresence>
用法
导入
import { AnimatePresence } from "motion-v"
退出动画
AnimatePresence
通过检测其 直接子元素 何时从 Vue 树中移除来工作。
这可能是由于组件的挂载/重新挂载
<AnimatePresence> <Modal v-if="show" key="modal" /> </AnimatePresence>
或使用 v-show
<AnimatePresence> <Modal v-show="show" key="modal" /> </AnimatePresence>
或其 key
更改
<AnimatePresence> <Slide :key="activeItem.id" /> </AnimatePresence>
或当列表中的子元素被添加/移除时
<AnimatePresence> <motion.li v-for="item in items" :key="item.id" :exit="{ opacity: 1 }" layout /> </AnimatePresence>
退出组件中的任何 motion
组件都将在组件从 DOM 中移除之前触发在其 exit
属性上定义的动画。
<template> <motion.div :exit="{ opacity: 0 }"> <img :src="img.src" /> <motion.p :exit="{ y: 10 }">{{description}}</motion.p> </motion.div> </template>
注意:直接子元素必须各自具有唯一的 key
属性,以便 AnimatePresence
可以跟踪它们在树中的存在。
与 initial
和 animate
类似,exit
可以定义为值对象或变体标签。
<script setup> const modalVariants = { visible: { opacity: 1, transition: { when: "beforeChildren" } }, hidden: { opacity: 0, transition: { when: "afterChildren" } } } </script> <template> <motion.div :variants="modalVariants" initial="hidden" animate="visible" exit="hidden" > {{children}} </motion.div> </template>
更改 key
更改 key
属性使 Vue 创建一个全新的组件。因此,通过更改 AnimatePresence
的单个子元素的 key
,我们可以轻松制作像幻灯片这样的组件。
<template> <AnimatePresence> <motion.img :key="image.src" :src="image.src" :initial="{ x: 300, opacity: 0 }" :animate="{ x: 0, opacity: 1 }" :exit="{ x: -300, opacity: 0 }" /> </AnimatePresence> </template>
属性
initial
通过传递 :initial="false"
,AnimatePresence
将禁用组件首次渲染时存在的子元素的任何初始动画。
<AnimatePresence :initial="false"> <Slide :key="activeItem.id" /> </AnimatePresence>
custom
当组件被移除时,不再有机会更新其属性(因为它不再在 Vue 树中)。因此,我们无法使用移除组件的相同渲染来更新其退出动画。
通过 AnimatePresence
的 custom
属性传递值,我们可以使用动态变体来更改 exit
动画。
<script setup> const variants = { hidden: (direction) => ({ opacity: 0, x: direction === 1 ? -300 : 300 }), visible: { opacity: 1, x: 0 } } </script> <template> <AnimatePresence :custom="direction"> <motion.img :key="image.src" :src="image.src" :variants="variants" initial="hidden" animate="visible" exit="hidden" /> </AnimatePresence> </template>
mode
默认值:"sync"
决定 AnimatePresence
如何处理进入和退出的子元素。
"sync"
:子元素在添加/移除后立即进行动画。"wait"
:进入的子元素将等待直到退出的子元素动画退出。注意:目前一次只渲染一个子元素。"popLayout"
:退出的子元素将从页面布局中“弹出”。这允许周围的元素立即移动到它们的新布局。
onExitComplete
当所有退出的节点完成动画退出时触发。
故障排除
退出动画不起作用
确保所有直接子元素都获得一个唯一的 key
属性,该属性对于每个渲染的组件保持不变。
例如,将 index
作为 key
是 不好的,因为如果项目重新排序,则 index
将不会与 item
匹配
<AnimatePresence> <Component v-for="(item,index) in items" :key="index" /> </AnimatePresence>
最好传递对该项目唯一的东西,例如 ID
<AnimatePresence> <Componen v-for="(item,index) in items" :key="item.id" /> </AnimatePresence>
还要确保 AnimatePresence
位于取消挂载元素的代码的外部。如果 AnimatePresence
自身被取消挂载,则它无法控制退出动画!
例如,这会 不起作用
<AnimatePresence v-if="isVisible"> <Component /> </AnimatePresence>
相反,条件应该位于 AnimatePresence
的根部
<AnimatePresence> <Component v-if="isVisible" /> </AnimatePresence>
布局动画在 mode="sync"
下不起作用
当混合布局和退出动画时,可能需要将组包裹在 LayoutGroup
中,以确保 AnimatePresence
外部的组件知道何时执行布局动画。
<LayoutGroup> <motion.ul layout> <AnimatePresence> <motion.li v-for="item in items" layout :key="item.id" /> </AnimatePresence> </motion.ul> </LayoutGroup>
布局动画在 mode="popLayout"
下不起作用
当任何 HTML 元素具有活动的 transform
时,它会暂时成为偏移父元素它的子元素。这可能会导致具有 position: "absolute"
的子元素不会出现在您期望的位置。mode="popLayout"
通过使用 position: "absolute"
工作。因此,为了确保布局动画期间的一致和预期的定位,请确保动画父元素具有除 "static"
之外的 position
。
<motion.ul layout :style="{ position: 'relative' }"> <AnimatePresence mode="popLayout"> <motion.li v-for="item in items" layout :key="item.id" /> </AnimatePresence> </motion.ul>
AnimatePresence
让退出动画变得简单。通过包裹一个或多个 motion
组件使用 AnimatePresence
,我们可以访问 exit
动画属性。
<AnimatePresence> <motion.div v-if="show" key="modal" :exit="{ opacity: 0 }" />} </AnimatePresence>
用法
导入
import { AnimatePresence } from "motion-v"
退出动画
AnimatePresence
通过检测其 直接子元素 何时从 Vue 树中移除来工作。
这可能是由于组件的挂载/重新挂载
<AnimatePresence> <Modal v-if="show" key="modal" /> </AnimatePresence>
或使用 v-show
<AnimatePresence> <Modal v-show="show" key="modal" /> </AnimatePresence>
或其 key
更改
<AnimatePresence> <Slide :key="activeItem.id" /> </AnimatePresence>
或当列表中的子元素被添加/移除时
<AnimatePresence> <motion.li v-for="item in items" :key="item.id" :exit="{ opacity: 1 }" layout /> </AnimatePresence>
退出组件中的任何 motion
组件都将在组件从 DOM 中移除之前触发在其 exit
属性上定义的动画。
<template> <motion.div :exit="{ opacity: 0 }"> <img :src="img.src" /> <motion.p :exit="{ y: 10 }">{{description}}</motion.p> </motion.div> </template>
注意:直接子元素必须各自具有唯一的 key
属性,以便 AnimatePresence
可以跟踪它们在树中的存在。
与 initial
和 animate
类似,exit
可以定义为值对象或变体标签。
<script setup> const modalVariants = { visible: { opacity: 1, transition: { when: "beforeChildren" } }, hidden: { opacity: 0, transition: { when: "afterChildren" } } } </script> <template> <motion.div :variants="modalVariants" initial="hidden" animate="visible" exit="hidden" > {{children}} </motion.div> </template>
更改 key
更改 key
属性使 Vue 创建一个全新的组件。因此,通过更改 AnimatePresence
的单个子元素的 key
,我们可以轻松制作像幻灯片这样的组件。
<template> <AnimatePresence> <motion.img :key="image.src" :src="image.src" :initial="{ x: 300, opacity: 0 }" :animate="{ x: 0, opacity: 1 }" :exit="{ x: -300, opacity: 0 }" /> </AnimatePresence> </template>
属性
initial
通过传递 :initial="false"
,AnimatePresence
将禁用组件首次渲染时存在的子元素的任何初始动画。
<AnimatePresence :initial="false"> <Slide :key="activeItem.id" /> </AnimatePresence>
custom
当组件被移除时,不再有机会更新其属性(因为它不再在 Vue 树中)。因此,我们无法使用移除组件的相同渲染来更新其退出动画。
通过 AnimatePresence
的 custom
属性传递值,我们可以使用动态变体来更改 exit
动画。
<script setup> const variants = { hidden: (direction) => ({ opacity: 0, x: direction === 1 ? -300 : 300 }), visible: { opacity: 1, x: 0 } } </script> <template> <AnimatePresence :custom="direction"> <motion.img :key="image.src" :src="image.src" :variants="variants" initial="hidden" animate="visible" exit="hidden" /> </AnimatePresence> </template>
mode
默认值:"sync"
决定 AnimatePresence
如何处理进入和退出的子元素。
"sync"
:子元素在添加/移除后立即进行动画。"wait"
:进入的子元素将等待直到退出的子元素动画退出。注意:目前一次只渲染一个子元素。"popLayout"
:退出的子元素将从页面布局中“弹出”。这允许周围的元素立即移动到它们的新布局。
onExitComplete
当所有退出的节点完成动画退出时触发。
故障排除
退出动画不起作用
确保所有直接子元素都获得一个唯一的 key
属性,该属性对于每个渲染的组件保持不变。
例如,将 index
作为 key
是 不好的,因为如果项目重新排序,则 index
将不会与 item
匹配
<AnimatePresence> <Component v-for="(item,index) in items" :key="index" /> </AnimatePresence>
最好传递对该项目唯一的东西,例如 ID
<AnimatePresence> <Componen v-for="(item,index) in items" :key="item.id" /> </AnimatePresence>
还要确保 AnimatePresence
位于取消挂载元素的代码的外部。如果 AnimatePresence
自身被取消挂载,则它无法控制退出动画!
例如,这会 不起作用
<AnimatePresence v-if="isVisible"> <Component /> </AnimatePresence>
相反,条件应该位于 AnimatePresence
的根部
<AnimatePresence> <Component v-if="isVisible" /> </AnimatePresence>
布局动画在 mode="sync"
下不起作用
当混合布局和退出动画时,可能需要将组包裹在 LayoutGroup
中,以确保 AnimatePresence
外部的组件知道何时执行布局动画。
<LayoutGroup> <motion.ul layout> <AnimatePresence> <motion.li v-for="item in items" layout :key="item.id" /> </AnimatePresence> </motion.ul> </LayoutGroup>
布局动画在 mode="popLayout"
下不起作用
当任何 HTML 元素具有活动的 transform
时,它会暂时成为偏移父元素它的子元素。这可能会导致具有 position: "absolute"
的子元素不会出现在您期望的位置。mode="popLayout"
通过使用 position: "absolute"
工作。因此,为了确保布局动画期间的一致和预期的定位,请确保动画父元素具有除 "static"
之外的 position
。
<motion.ul layout :style="{ position: 'relative' }"> <AnimatePresence mode="popLayout"> <motion.li v-for="item in items" layout :key="item.id" /> </AnimatePresence> </motion.ul>
AnimatePresence
让退出动画变得简单。通过包裹一个或多个 motion
组件使用 AnimatePresence
,我们可以访问 exit
动画属性。
<AnimatePresence> <motion.div v-if="show" key="modal" :exit="{ opacity: 0 }" />} </AnimatePresence>
用法
导入
import { AnimatePresence } from "motion-v"
退出动画
AnimatePresence
通过检测其 直接子元素 何时从 Vue 树中移除来工作。
这可能是由于组件的挂载/重新挂载
<AnimatePresence> <Modal v-if="show" key="modal" /> </AnimatePresence>
或使用 v-show
<AnimatePresence> <Modal v-show="show" key="modal" /> </AnimatePresence>
或其 key
更改
<AnimatePresence> <Slide :key="activeItem.id" /> </AnimatePresence>
或当列表中的子元素被添加/移除时
<AnimatePresence> <motion.li v-for="item in items" :key="item.id" :exit="{ opacity: 1 }" layout /> </AnimatePresence>
退出组件中的任何 motion
组件都将在组件从 DOM 中移除之前触发在其 exit
属性上定义的动画。
<template> <motion.div :exit="{ opacity: 0 }"> <img :src="img.src" /> <motion.p :exit="{ y: 10 }">{{description}}</motion.p> </motion.div> </template>
注意:直接子元素必须各自具有唯一的 key
属性,以便 AnimatePresence
可以跟踪它们在树中的存在。
与 initial
和 animate
类似,exit
可以定义为值对象或变体标签。
<script setup> const modalVariants = { visible: { opacity: 1, transition: { when: "beforeChildren" } }, hidden: { opacity: 0, transition: { when: "afterChildren" } } } </script> <template> <motion.div :variants="modalVariants" initial="hidden" animate="visible" exit="hidden" > {{children}} </motion.div> </template>
更改 key
更改 key
属性使 Vue 创建一个全新的组件。因此,通过更改 AnimatePresence
的单个子元素的 key
,我们可以轻松制作像幻灯片这样的组件。
<template> <AnimatePresence> <motion.img :key="image.src" :src="image.src" :initial="{ x: 300, opacity: 0 }" :animate="{ x: 0, opacity: 1 }" :exit="{ x: -300, opacity: 0 }" /> </AnimatePresence> </template>
属性
initial
通过传递 :initial="false"
,AnimatePresence
将禁用组件首次渲染时存在的子元素的任何初始动画。
<AnimatePresence :initial="false"> <Slide :key="activeItem.id" /> </AnimatePresence>
custom
当组件被移除时,不再有机会更新其属性(因为它不再在 Vue 树中)。因此,我们无法使用移除组件的相同渲染来更新其退出动画。
通过 AnimatePresence
的 custom
属性传递值,我们可以使用动态变体来更改 exit
动画。
<script setup> const variants = { hidden: (direction) => ({ opacity: 0, x: direction === 1 ? -300 : 300 }), visible: { opacity: 1, x: 0 } } </script> <template> <AnimatePresence :custom="direction"> <motion.img :key="image.src" :src="image.src" :variants="variants" initial="hidden" animate="visible" exit="hidden" /> </AnimatePresence> </template>
mode
默认值:"sync"
决定 AnimatePresence
如何处理进入和退出的子元素。
"sync"
:子元素在添加/移除后立即进行动画。"wait"
:进入的子元素将等待直到退出的子元素动画退出。注意:目前一次只渲染一个子元素。"popLayout"
:退出的子元素将从页面布局中“弹出”。这允许周围的元素立即移动到它们的新布局。
onExitComplete
当所有退出的节点完成动画退出时触发。
故障排除
退出动画不起作用
确保所有直接子元素都获得一个唯一的 key
属性,该属性对于每个渲染的组件保持不变。
例如,将 index
作为 key
是 不好的,因为如果项目重新排序,则 index
将不会与 item
匹配
<AnimatePresence> <Component v-for="(item,index) in items" :key="index" /> </AnimatePresence>
最好传递对该项目唯一的东西,例如 ID
<AnimatePresence> <Componen v-for="(item,index) in items" :key="item.id" /> </AnimatePresence>
还要确保 AnimatePresence
位于取消挂载元素的代码的外部。如果 AnimatePresence
自身被取消挂载,则它无法控制退出动画!
例如,这会 不起作用
<AnimatePresence v-if="isVisible"> <Component /> </AnimatePresence>
相反,条件应该位于 AnimatePresence
的根部
<AnimatePresence> <Component v-if="isVisible" /> </AnimatePresence>
布局动画在 mode="sync"
下不起作用
当混合布局和退出动画时,可能需要将组包裹在 LayoutGroup
中,以确保 AnimatePresence
外部的组件知道何时执行布局动画。
<LayoutGroup> <motion.ul layout> <AnimatePresence> <motion.li v-for="item in items" layout :key="item.id" /> </AnimatePresence> </motion.ul> </LayoutGroup>
布局动画在 mode="popLayout"
下不起作用
当任何 HTML 元素具有活动的 transform
时,它会暂时成为偏移父元素它的子元素。这可能会导致具有 position: "absolute"
的子元素不会出现在您期望的位置。mode="popLayout"
通过使用 position: "absolute"
工作。因此,为了确保布局动画期间的一致和预期的定位,请确保动画父元素具有除 "static"
之外的 position
。
<motion.ul layout :style="{ position: 'relative' }"> <AnimatePresence mode="popLayout"> <motion.li v-for="item in items" layout :key="item.id" /> </AnimatePresence> </motion.ul>