vue水波球实现
Vue 水波球实现方法
水波球(Ripple Effect)是一种常见的交互效果,当用户点击或触摸元素时,会产生类似水波纹的扩散效果。以下是几种实现方式:
使用 CSS 和 Vue 事件
通过 Vue 的事件绑定和 CSS 动画实现基础水波效果:
<template>
<div class="ripple-container" @click="createRipple">
<slot></slot>
<span class="ripple" :style="rippleStyle"></span>
</div>
</template>
<script>
export default {
data() {
return {
rippleStyle: {}
}
},
methods: {
createRipple(e) {
const container = e.currentTarget
const circle = document.createElement('span')
const diameter = Math.max(container.clientWidth, container.clientHeight)
const radius = diameter / 2
this.rippleStyle = {
width: `${diameter}px`,
height: `${diameter}px`,
left: `${e.clientX - container.getBoundingClientRect().left - radius}px`,
top: `${e.clientY - container.getBoundingClientRect().top - radius}px`
}
setTimeout(() => {
this.rippleStyle = {}
}, 600)
}
}
}
</script>
<style>
.ripple-container {
position: relative;
overflow: hidden;
display: inline-block;
}
.ripple {
position: absolute;
border-radius: 50%;
transform: scale(0);
animation: ripple 600ms linear;
background-color: rgba(255, 255, 255, 0.7);
}
@keyframes ripple {
to {
transform: scale(4);
opacity: 0;
}
}
</style>
使用第三方库
对于更复杂的效果,可以考虑使用专门的水波效果库:

-
安装
vue-ripple-directive:npm install vue-ripple-directive -
在 Vue 项目中使用:

import Vue from 'vue' import Ripple from 'vue-ripple-directive'
Vue.directive('ripple', Ripple)
3. 在模板中应用:
```html
<button v-ripple>Click Me</button>
自定义指令实现
创建自定义 Vue 指令实现更灵活的控制:
Vue.directive('ripple', {
bind(el) {
el.style.position = 'relative'
el.style.overflow = 'hidden'
el.addEventListener('click', (e) => {
const circle = document.createElement('span')
const diameter = Math.max(el.clientWidth, el.clientHeight)
const radius = diameter / 2
circle.style.width = circle.style.height = `${diameter}px`
circle.style.left = `${e.clientX - el.getBoundingClientRect().left - radius}px`
circle.style.top = `${e.clientY - el.getBoundingClientRect().top - radius}px`
circle.classList.add('ripple-effect')
const existingRipple = el.querySelector('.ripple-effect')
if (existingRipple) {
existingRipple.remove()
}
el.appendChild(circle)
setTimeout(() => {
circle.remove()
}, 600)
})
}
})
配套 CSS:
.ripple-effect {
position: absolute;
border-radius: 50%;
background-color: rgba(255, 255, 255, 0.7);
transform: scale(0);
animation: ripple 0.6s linear;
pointer-events: none;
}
@keyframes ripple {
to {
transform: scale(4);
opacity: 0;
}
}
注意事项
- 性能优化:避免频繁创建和移除 DOM 元素,可以复用已有的波纹元素
- 移动端适配:考虑添加
touchstart事件支持移动设备 - 颜色自定义:通过 props 或 CSS 变量允许自定义波纹颜色
- 无障碍访问:确保效果不会干扰键盘导航和屏幕阅读器
以上方法提供了从简单到复杂的不同实现方案,可根据项目需求选择合适的实现方式。






