关于 vueuse-motion-skilld
@vueuse/motion 是基于 Popmotion 的 Vue 3 声明式动画库,可通过指令、组件或组合式函数控制动画。它还提供 Nuxt 集成、预设动画以及减少动态效果偏好支持。
主要功能
- 01指令、组件和组合式函数三种接口
- 02内置预设与自定义动画变体
- 03手势、视口与状态动画
- 04Nuxt 集成及 SSR 初始样式
- 05检测减少动态效果偏好
适用场景
- 01为模板元素添加进入或视口动画
- 02为 Markdown 内容配置 SSR 兼容动画
- 03通过组合式函数编排手势或程序化动画
- 04根据用户减少动态效果偏好调整动画
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ skilld-dev/ vue-ecosystem-skills --skill vueuse-motion-skilld安装后在 Claude Code 中输入/vueuse-motion-skilld确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/api.mdmigration.mdnuxt-ssr.mdvariants-transitions.md详细介绍
@vueuse/motion 3.0.3
基于 Popmotion(而非 WAAPI)构建的 Vue 3 声明式动画组合式 API。提供三种可互换的形式:v-motion 指令、<Motion>/<MotionGroup> 组件,以及 useMotion() 组合式 API。
环境限制
- 仅支持 Vue 3(peer 依赖
vue >=3.0.0,package.json:79-81)。 - 自 v3.0.0 起仅支持 ESM:不提供 CommonJS 构建(
"type": "module",仅导出.mjs,package.json:2,31-35;https://github.com/vueuse/motion/pull/254)。不支持require();CJS 项目必须迁移到 ESM,或使用动态import()。 - 依赖
@vueuse/core/@vueuse/sharedv13 和popmotion11(package.json:82-89)。 - Nuxt 集成需要
@nuxt/kit>=3.13(可选依赖,package.json:90-92)。 - 动画在
window上运行;SSR 仅将initial变体渲染为内联样式(参见 Nuxt 与 SSR)。
设置
Vue 应用入口(README.md:32-44):
import { createApp } from 'vue'
import { MotionPlugin } from '@vueuse/motion'
import App from './App.vue'
createApp(App).use(MotionPlugin).mount('#app')
MotionPlugin 会注册 v-motion 指令、30 个预设指令(v-motion-fade 等)、全局 Motion/MotionGroup 组件,以及通过选项配置的自定义指令(dist/index.mjs:1712-1736)。
app.use(MotionPlugin, {
directives: { 'pop-bottom': { initial: { scale: 0, y: 100 }, visible: { scale: 1, y: 0 } } },
excludePresets: true, // skip the 30 built-in preset directives
})
Nuxt:将 '@vueuse/motion/nuxt' 添加到 modules;插件、组件和组合式 API 自动导入会自动为你安装(dist/nuxt/module.mjs:13-24)。参见 Nuxt 与 SSR。
常见任务
指令(最常用)
<template>
<div
v-motion
:initial="{ opacity: 0, y: 100 }"
:enter="{ opacity: 1, y: 0 }"
/>
<div v-motion-slide-visible-left />
</template>
变体属性:initial、enter、leave、visible、visibleOnce(也接受连字符写法 visible-once,dist/index.mjs:1054-1057)、hovered、tapped、focused,以及用于自定义键的 :variants。简写 :delay / :duration(毫秒)适用于 enter/visible/visibleOnce 过渡(dist/index.mjs:1043-1051)。
组件(SSR/MDC 兼容性更好)
<Motion is="p" preset="slideVisibleLeft" :duration="600">Text in Motion!</Motion>
preset 接受驼峰命名的预设名称,包括插件 directives 中的名称(dist/index.mjs:1551-1562)。<MotionGroup> 将同一配置应用于所有子元素;除非指定 :is,否则不渲染包装元素。
组合式 API(程序化控制)
<script setup lang="ts">
import { ref } from 'vue'
import { useMotion } from '@vueuse/motion'
const target = ref<HTMLElement>()
const { variant, apply, stop } = useMotion(target, {
initial: { opacity: 0, y: 100 },
enter: { opacity: 1, y: 0 },
custom2: { scale: 1.2 },
})
// switch variant (triggers transition): variant.value = 'custom2'
// temporary animation, then revert: await apply({ scale: 2 }); await apply('enter')
</script>
实例成员:target、variant、variants、state、motionProperties、apply、set、stop、leave、isAnimating(dist/index.d.mts:535-576)。完整 API: API 参考。
从脚本访问模板动画
为指令指定字符串值,然后通过 useMotions() 读取:
<div v-motion="'hero'" :initial="{ opacity: 0 }" :enter="{ opacity: 1 }" />
const motions = useMotions()
const play = () => { motions.hero?.variant.value = 'custom' }
可避免错误的规则
- 时长、延迟和
repeatDelay的单位都是毫秒(delay: 1000= 1 秒)。dist/index.d.mts中的 JSDoc 写着“以秒为单位”(从 Framer Motion 类型复制而来),但这些值会直接以毫秒传给 Popmotion;官方文档和运行时默认值(300/800)也都是毫秒(dist/index.mjs:266-281,431-441;https://motion.vueuse.org/features/transition-properties.html)。 - 务必为之后要动画的每个键都声明
initial,这样元素就会从已知状态开始,并且leave/visible反转时有一个可返回的基准状态(https://motion.vueuse.org/features/variants.html)。 - 元素离开视口时,
visible会重新应用initial;visibleOnce只触发一次(dist/index.mjs:696-707)。 - 不要在 setup 顶层解构
useMotions()。 实例会在 setup 运行后注册;请保留对象,并在需要时再访问其属性(motions.hero?.apply('x'))。注册是全局的,并以传给v-motion的字符串值为键(dist/index.mjs:9,1065;https://github.com/vueuse/motion/issues/109)。 apply('unknown-key')会抛出错误The variant unknown-key does not exist.。若要设置一次性状态,请使用对象形式apply({ ... })(dist/index.mjs:534-537)。leave(done)需要一个leave变体,否则会回退到initial;可将它映射到<transition @leave="(el, done) => leave(done)">(dist/index.mjs:568-582)。- 默认过渡效果按属性选择:
x/y/z/rotate*/scale*使用弹簧效果,opacity/color/backgroundColor使用 300 毫秒线性补间,数组目标使用 800 毫秒关键帧(dist/index.mjs:266-290,443-446)。可通过变体的transition覆盖(https://motion.vueuse.org/features/transition-properties.html)。 - 事件变体(
hovered/tapped/focused)会按优先级叠加在当前变体上,优先级为 hovered < focused < tapped;只有已声明的变体才会注册监听器(dist/index.mjs:597-657;https://motion.vueuse.org/features/variants.html)。 v-motion预设指令使用 slug 化名称:v-motion-fade-visible-once、v-motion-roll-left、v-motion-slide-top等(驼峰式键 ->slugify,dist/index.mjs:1459-1464,1718)。变体与过渡 中列出了全部 30 个预设。
如何选择使用方式
- 仅在模板中使用的显示动画:使用指令或预设指令。
- SSR 占比较高或由 Markdown 渲染的内容(MDC):使用
<Motion>/<MotionGroup>;与指令相比,它们注入initial样式更可靠(dist/index.mjs:1662-1667;https://motion.vueuse.org/features/components.html)。 - 手势、序列动画或由模板外部驱动的值:使用
useMotion();若需要绕过变体系统,直接使用 Popmotion 级别的弹簧效果,则使用useSpring()+useMotionProperties()(dist/index.mjs:1747-1772)。 - 尊重用户偏好:使用
const reduced = useReducedMotion(),并在值为 true 时跳过或缩短动画(dist/index.mjs:1774-1777)。
参考资料
- API 参考:所有导出项、组合式函数签名、
MotionInstance/SpringControls成员和底层组合式函数。 - 变体与过渡:变体语义、可动画的 motion 属性、过渡选项和预设列表。
- Nuxt 与 SSR:模块设置、运行时配置指令、SSR 行为及注意事项。
- 迁移与版本:v2 -> v3 的变更、nightly 频道和包信息。