文档

文档

Vue

AnimatePresence

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 可以跟踪它们在树中的存在。

initialanimate 类似,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 树中)。因此,我们无法使用移除组件的相同渲染来更新其退出动画。

通过 AnimatePresencecustom 属性传递值,我们可以使用动态变体来更改 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 可以跟踪它们在树中的存在。

initialanimate 类似,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 树中)。因此,我们无法使用移除组件的相同渲染来更新其退出动画。

通过 AnimatePresencecustom 属性传递值,我们可以使用动态变体来更改 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 可以跟踪它们在树中的存在。

initialanimate 类似,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 树中)。因此,我们无法使用移除组件的相同渲染来更新其退出动画。

通过 AnimatePresencecustom 属性传递值,我们可以使用动态变体来更改 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+是一次性付费,终身会员资格。

除了高级 Motion 功能、抢先体验内容和私有 Discord 社区外,您还将解锁访问 90 多个高级示例的源代码的权限,这些示例将此页面上的 API 提升到一个新的水平。

加载中...
加载中...
保持关注

订阅以获取最新新闻和更新。

保持关注

订阅以获取最新新闻和更新。