vue实现圆盘导航
Vue 实现圆盘导航
使用 CSS 和 Vue 动态计算位置
通过 Vue 的动态数据绑定和 CSS 的 transform 属性,可以实现圆盘导航的布局。核心思路是计算每个导航项在圆周上的位置。

<template>
<div class="circle-menu">
<div
v-for="(item, index) in items"
:key="index"
class="menu-item"
:style="getItemStyle(index)"
@click="handleClick(item)"
>
{{ item.label }}
</div>
</div>
</template>
<script>
export default {
data() {
return {
items: [
{ label: '首页', path: '/' },
{ label: '产品', path: '/products' },
{ label: '服务', path: '/services' },
{ label: '关于', path: '/about' },
{ label: '联系', path: '/contact' }
],
radius: 150 // 圆盘半径
}
},
methods: {
getItemStyle(index) {
const angle = (index * 360 / this.items.length) - 90; // 从顶部开始
const radian = angle * Math.PI / 180;
return {
left: `${this.radius + this.radius * Math.cos(radian)}px`,
top: `${this.radius + this.radius * Math.sin(radian)}px`
};
},
handleClick(item) {
// 处理点击事件,例如路由跳转
console.log('Navigating to:', item.path);
}
}
}
</script>
<style>
.circle-menu {
position: relative;
width: 300px;
height: 300px;
margin: 0 auto;
}
.menu-item {
position: absolute;
width: 60px;
height: 60px;
background: #42b983;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: white;
cursor: pointer;
transform: translate(-50%, -50%);
transition: all 0.3s ease;
}
.menu-item:hover {
background: #33a06f;
transform: translate(-50%, -50%) scale(1.1);
}
</style>
使用 SVG 实现圆盘导航
SVG 天然适合处理圆形布局,结合 Vue 可以动态生成导航项。

<template>
<svg width="300" height="300" viewBox="0 0 300 300">
<circle
cx="150"
cy="150"
r="120"
fill="none"
stroke="#42b983"
stroke-width="2"
/>
<g
v-for="(item, index) in items"
:key="index"
@click="handleClick(item)"
style="cursor: pointer"
>
<circle
:cx="getPosition(index).x"
:cy="getPosition(index).y"
r="20"
fill="#42b983"
/>
<text
:x="getPosition(index).x"
:y="getPosition(index).y + 5"
text-anchor="middle"
fill="white"
>
{{ item.label }}
</text>
</g>
</svg>
</template>
<script>
export default {
data() {
return {
items: [
{ label: '首页', path: '/' },
{ label: '产品', path: '/products' },
{ label: '服务', path: '/services' },
{ label: '关于', path: '/about' },
{ label: '联系', path: '/contact' }
],
radius: 120,
center: { x: 150, y: 150 }
}
},
methods: {
getPosition(index) {
const angle = (index * 360 / this.items.length) - 90;
const radian = angle * Math.PI / 180;
return {
x: this.center.x + this.radius * Math.cos(radian),
y: this.center.y + this.radius * Math.sin(radian)
};
},
handleClick(item) {
console.log('Navigating to:', item.path);
}
}
}
</script>
使用第三方库(如 TweenMax)添加动画
为圆盘导航添加更流畅的动画效果,可以使用 GSAP 动画库。
<template>
<div class="circle-menu">
<div
v-for="(item, index) in items"
:key="index"
class="menu-item"
ref="items"
@click="handleClick(item)"
>
{{ item.label }}
</div>
</div>
</template>
<script>
import { TweenMax } from 'gsap';
export default {
data() {
return {
items: [
{ label: '首页', path: '/' },
{ label: '产品', path: '/products' },
{ label: '服务', path: '/services' },
{ label: '关于', path: '/about' },
{ label: '联系', path: '/contact' }
],
radius: 150
}
},
mounted() {
this.arrangeItems();
},
methods: {
arrangeItems() {
this.$refs.items.forEach((item, index) => {
const angle = (index * 360 / this.items.length) - 90;
const radian = angle * Math.PI / 180;
TweenMax.to(item, 0.5, {
left: `${this.radius + this.radius * Math.cos(radian)}px`,
top: `${this.radius + this.radius * Math.sin(radian)}px`,
ease: 'back.out'
});
});
},
handleClick(item) {
console.log('Navigating to:', item.path);
}
}
}
</script>
响应式圆盘导航
通过监听窗口大小变化,调整圆盘导航的尺寸和位置。
// 在 Vue 组件中添加
mounted() {
window.addEventListener('resize', this.handleResize);
this.handleResize();
},
beforeDestroy() {
window.removeEventListener('resize', this.handleResize);
},
methods: {
handleResize() {
const size = Math.min(window.innerWidth, window.innerHeight) * 0.8;
this.radius = size / 2;
this.$el.style.width = `${size}px`;
this.$el.style.height = `${size}px`;
this.arrangeItems();
}
}
以上方法可以根据项目需求选择或组合使用,实现不同风格的圆盘导航效果。






