Installation
Install Motion for Vue in your Vue 3 project:
Motion for Vue requires Vue 3.0 or higher.
Your First Animation
Let’s create a simple fade-in animation:
<script setup>
import { motion } from "motion-v"
</script>
<template>
<motion.div
:initial="{ opacity: 0, y: 20 }"
:animate="{ opacity: 1, y: 0 }"
:transition="{ duration: 0.5 }"
>
Hello, Motion!
</motion.div>
</template>
Interactive Animation
Create an animation that responds to user interaction:
<script setup>
import { ref } from 'vue'
import { motion } from 'motion-v'
const isOpen = ref(false)
</script>
<template>
<div>
<button @click="isOpen = !isOpen">
Toggle
</button>
<motion.div
:animate="{
width: isOpen ? 300 : 100,
height: isOpen ? 200 : 100,
backgroundColor: isOpen ? '#3b82f6' : '#8b5cf6'
}"
:transition="{ type: 'spring', stiffness: 300, damping: 30 }"
style="border-radius: 20px"
/>
</div>
</template>
Hover and Tap Animations
Add interactive states with gesture props:
<script setup>
import { motion } from 'motion-v'
</script>
<template>
<motion.button
:whileHover="{ scale: 1.1 }"
:whileTap="{ scale: 0.95 }"
style="
padding: 16px 32px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
border-radius: 8px;
cursor: pointer;
"
>
Hover or Click Me
</motion.button>
</template>
Keyframe Animations
Animate through multiple values:
<script setup>
import { motion } from 'motion-v'
</script>
<template>
<motion.div
:animate="{
x: [0, 100, 0],
rotate: [0, 180, 360],
borderRadius: ['20%', '50%', '20%']
}"
:transition="{
duration: 2,
repeat: Infinity,
ease: 'easeInOut'
}"
style="
width: 100px;
height: 100px;
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
"
/>
</template>
Using Refs
Access the underlying DOM element:
<script setup>
import { ref, onMounted } from 'vue'
import { motion } from 'motion-v'
const elementRef = ref(null)
onMounted(() => {
console.log('Element:', elementRef.value)
})
</script>
<template>
<motion.div
ref="elementRef"
:animate="{ x: 100 }"
>
Element with ref
</motion.div>
</template>
Composables
Vue composables for advanced animation control:
<script setup>
import { ref } from 'vue'
import { motion, useMotionValue, useTransform } from 'motion-v'
const x = useMotionValue(0)
const opacity = useTransform(x, [0, 100], [0, 1])
const scale = useTransform(x, [0, 100], [0.8, 1])
</script>
<template>
<motion.div
:style="{ x, opacity, scale }"
drag="x"
:dragConstraints="{ left: 0, right: 100 }"
>
Drag me
</motion.div>
</template>
Component Structure
Best practices for organizing Motion components:
<script setup>
import { ref, computed } from 'vue'
import { motion } from 'motion-v'
const isActive = ref(false)
const variants = {
inactive: { scale: 1, opacity: 0.6 },
active: { scale: 1.2, opacity: 1 }
}
const currentVariant = computed(() =>
isActive.value ? 'active' : 'inactive'
)
</script>
<template>
<motion.div
:animate="currentVariant"
:variants="variants"
@click="isActive = !isActive"
style="
width: 100px;
height: 100px;
background: #10b981;
border-radius: 12px;
cursor: pointer;
"
/>
</template>
TypeScript Support
Motion for Vue has full TypeScript support:
<script setup lang="ts">
import { ref } from 'vue'
import { motion } from 'motion-v'
import type { MotionProps } from 'motion-v'
interface AnimationState {
x: number
y: number
rotate: number
}
const animate = ref<AnimationState>({
x: 100,
y: 50,
rotate: 45
})
</script>
<template>
<motion.div :animate="animate" />
</template>
Common Patterns
List Animations
<script setup>
import { ref } from 'vue'
import { motion } from 'motion-v'
const items = ref(['Item 1', 'Item 2', 'Item 3'])
</script>
<template>
<div>
<motion.div
v-for="(item, index) in items"
:key="item"
:initial="{ opacity: 0, x: -20 }"
:animate="{ opacity: 1, x: 0 }"
:transition="{ delay: index * 0.1 }"
>
{{ item }}
</motion.div>
</div>
</template>
Conditional Rendering
<script setup>
import { ref } from 'vue'
import { motion } from 'motion-v'
const show = ref(false)
</script>
<template>
<div>
<button @click="show = !show">Toggle</button>
<motion.div
v-if="show"
:initial="{ opacity: 0, scale: 0.8 }"
:animate="{ opacity: 1, scale: 1 }"
:exit="{ opacity: 0, scale: 0.8 }"
>
Conditional content
</motion.div>
</div>
</template>
Next Steps
Spring Animations
Master physics-based animations
Keyframe Animations
Create complex animation sequences
Drag Interactions
Implement drag gestures and constraints
Performance
Optimize for production