vue实现购物车动画
实现购物车动画的步骤
使用 Vue 的过渡系统
Vue 提供了 <transition> 和 <transition-group> 组件,可以方便地实现动画效果。购物车动画通常涉及商品添加到购物车时的飞入效果,或者删除时的淡出效果。
<transition-group name="cart-item" tag="ul">
<li v-for="item in cartItems" :key="item.id" class="cart-item">
{{ item.name }}
</li>
</transition-group>
.cart-item-enter-active, .cart-item-leave-active {
transition: all 0.5s ease;
}
.cart-item-enter, .cart-item-leave-to {
opacity: 0;
transform: translateY(30px);
}
使用第三方动画库
可以结合第三方动画库如 Animate.css 或 GSAP 来实现更复杂的动画效果。以 Animate.css 为例:
<transition-group
enter-active-class="animate__animated animate__bounceIn"
leave-active-class="animate__animated animate__bounceOut"
tag="ul"
>
<li v-for="item in cartItems" :key="item.id">
{{ item.name }}
</li>
</transition-group>
实现商品飞入购物车动画 在点击“加入购物车”按钮时,创建一个元素并让它从商品位置飞向购物车图标位置。
methods: {
addToCart(item) {
// 创建动画元素
const flyingItem = document.createElement('div');
flyingItem.style.position = 'fixed';
flyingItem.style.zIndex = '9999';
flyingItem.style.width = '20px';
flyingItem.style.height = '20px';
flyingItem.style.background = 'red';
flyingItem.style.borderRadius = '50%';
// 获取点击位置
const rect = event.target.getBoundingClientRect();
flyingItem.style.left = `${rect.left}px`;
flyingItem.style.top = `${rect.top}px`;
document.body.appendChild(flyingItem);
// 获取购物车位置
const cartRect = this.$refs.cartIcon.getBoundingClientRect();
// 执行动画
const animation = flyingItem.animate([
{
left: `${rect.left}px`,
top: `${rect.top}px`,
opacity: 1
},
{
left: `${cartRect.left}px`,
top: `${cartRect.top}px`,
opacity: 0
}
], {
duration: 800,
easing: 'cubic-bezier(0.4, 0, 0.2, 1)'
});
animation.onfinish = () => {
document.body.removeChild(flyingItem);
this.cartItems.push(item);
};
}
}
购物车数量变化动画 为购物车数量添加一个简单的放大缩小动画,当数量变化时给予视觉反馈。
.cart-count {
transition: all 0.3s ease;
}
.cart-count-change {
transform: scale(1.2);
color: #ff5722;
}
watch: {
cartItems: {
handler() {
this.$refs.cartCount.classList.add('cart-count-change');
setTimeout(() => {
this.$refs.cartCount.classList.remove('cart-count-change');
}, 300);
},
deep: true
}
}
使用 Vue 的 JavaScript 钩子 对于更复杂的动画,可以使用 Vue 过渡的 JavaScript 钩子。
<transition
@before-enter="beforeEnter"
@enter="enter"
@leave="leave"
>
<div v-if="showItem" class="item"></div>
</transition>
methods: {
beforeEnter(el) {
el.style.opacity = 0;
el.style.transform = 'translateY(60px)';
},
enter(el, done) {
anime({
targets: el,
opacity: 1,
translateY: 0,
duration: 600,
easing: 'easeOutExpo',
complete: done
});
},
leave(el, done) {
anime({
targets: el,
opacity: 0,
translateY: 60,
duration: 600,
easing: 'easeOutExpo',
complete: done
});
}
}
性能优化建议
使用 will-change 属性 对于需要频繁动画的元素,添加 will-change 属性可以提升性能。
.animated-item {
will-change: transform, opacity;
}
减少动画元素数量 对于购物车列表动画,可以考虑只对最新添加的项目进行动画,而不是所有项目。
使用 requestAnimationFrame 对于自定义 JavaScript 动画,使用 requestAnimationFrame 而不是 setTimeout 或 setInterval。
function animate(element) {
let start = null;
const duration = 1000;
function step(timestamp) {
if (!start) start = timestamp;
const progress = timestamp - start;
const percentage = Math.min(progress / duration, 1);
element.style.transform = `translateX(${percentage * 100}px)`;
if (percentage < 1) {
requestAnimationFrame(step);
}
}
requestAnimationFrame(step);
}






