当前位置:首页 > VUE

vue实现扇形菜单

2026-02-18 05:53:51VUE

Vue 实现扇形菜单

使用 CSS 和 Vue 动态计算位置

通过 Vue 的动态数据绑定和 CSS 的 transform 属性,可以实现扇形菜单的布局。核心是利用三角函数计算每个菜单项的位置。

<template>
  <div class="fan-menu">
    <div 
      v-for="(item, index) in items" 
      :key="index" 
      class="menu-item"
      :style="getItemStyle(index)"
    >
      {{ item.label }}
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      items: [
        { label: '选项1' },
        { label: '选项2' },
        { label: '选项3' },
        { label: '选项4' },
        { label: '选项5' },
      ],
      radius: 100, // 扇形半径
      angle: 60,   // 扇形展开角度
    };
  },
  methods: {
    getItemStyle(index) {
      const count = this.items.length;
      const startAngle = -this.angle / 2;
      const stepAngle = this.angle / (count - 1);
      const angle = startAngle + index * stepAngle;
      const radian = angle * Math.PI / 180;

      return {
        transform: `translate(
          ${this.radius * Math.cos(radian)}px,
          ${this.radius * Math.sin(radian)}px
        )`,
      };
    },
  },
};
</script>

<style>
.fan-menu {
  position: relative;
  width: 300px;
  height: 300px;
}
.menu-item {
  position: absolute;
  width: 50px;
  height: 50px;
  background: #42b983;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  left: 50%;
  top: 50%;
  transform-origin: 0 0;
}
</style>

添加动画效果

通过 Vue 的过渡效果或 CSS 动画,可以为扇形菜单添加展开和收起的动画。

vue实现扇形菜单

<template>
  <div class="fan-menu">
    <transition-group name="fan">
      <div 
        v-for="(item, index) in items" 
        v-show="isOpen"
        :key="index" 
        class="menu-item"
        :style="getItemStyle(index)"
      >
        {{ item.label }}
      </div>
    </transition-group>
    <button @click="isOpen = !isOpen">切换菜单</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isOpen: false,
      // 其他数据同上
    };
  },
  // 其他代码同上
};
</script>

<style>
.fan-enter-active, .fan-leave-active {
  transition: all 0.5s ease;
}
.fan-enter, .fan-leave-to {
  opacity: 0;
  transform: translate(0, 0) !important;
}
</style>

使用第三方库

如果需要更复杂的扇形菜单效果,可以借助第三方库如 vue-simple-context-menu 或手动集成 GSAP 动画库。

安装 GSAP:

vue实现扇形菜单

npm install gsap

示例代码:

<template>
  <div class="fan-menu">
    <div ref="items" v-for="(item, index) in items" :key="index" class="menu-item">
      {{ item.label }}
    </div>
    <button @click="toggleMenu">切换菜单</button>
  </div>
</template>

<script>
import { gsap } from 'gsap';
export default {
  data() {
    return {
      isOpen: false,
      items: [
        { label: '选项1' },
        { label: '选项2' },
        { label: '选项3' },
        { label: '选项4' },
        { label: '选项5' },
      ],
      radius: 100,
      angle: 60,
    };
  },
  methods: {
    toggleMenu() {
      this.isOpen = !this.isOpen;
      this.animateMenu();
    },
    animateMenu() {
      const items = this.$refs.items;
      const count = this.items.length;
      const startAngle = -this.angle / 2;
      const stepAngle = this.angle / (count - 1);

      items.forEach((item, index) => {
        const angle = startAngle + index * stepAngle;
        const radian = angle * Math.PI / 180;
        const x = this.radius * Math.cos(radian);
        const y = this.radius * Math.sin(radian);

        gsap.to(item, {
          x: this.isOpen ? x : 0,
          y: this.isOpen ? y : 0,
          duration: 0.5,
          ease: 'back.out',
        });
      });
    },
  },
};
</script>

响应式设计

通过监听窗口大小变化或使用 CSS 媒体查询,可以确保扇形菜单在不同设备上正常显示。

mounted() {
  window.addEventListener('resize', this.handleResize);
},
beforeDestroy() {
  window.removeEventListener('resize', this.handleResize);
},
methods: {
  handleResize() {
    this.radius = window.innerWidth < 768 ? 80 : 100;
  },
},

标签: 扇形菜单
分享给朋友:

相关文章

用css制作下拉菜单

用css制作下拉菜单

使用纯CSS制作下拉菜单 HTML结构 基础的下拉菜单需要嵌套的HTML结构,通常使用<ul>和<li>标签实现层级关系: <div class="dropdown"&…

css div 制作导航菜单

css div 制作导航菜单

使用 CSS 和 Div 制作导航菜单 导航菜单是网站的重要组成部分,以下是通过 CSS 和 div 元素制作导航菜单的方法。 基本 HTML 结构 创建一个简单的 div 结构作为导航菜单的基础:…

vue 底部菜单实现

vue 底部菜单实现

实现 Vue 底部菜单的方法 使用 v-if 或 v-show 控制显示 在 Vue 中可以通过条件渲染控制底部菜单的显示与隐藏。v-if 适合动态切换频率较低的场景,v-show 适合频繁切换的场景…

vue实现菜单切换

vue实现菜单切换

Vue 实现菜单切换的方法 在 Vue 中实现菜单切换通常涉及动态绑定类名、条件渲染或状态管理。以下是几种常见的方法: 动态绑定 class 实现高亮切换 通过 v-bind:class 动态绑定类…

vue实现级联菜单

vue实现级联菜单

实现级联菜单的基本思路 Vue中实现级联菜单通常需要以下关键点:数据结构的组织、组件间的通信、动态渲染子菜单。一般采用递归组件或逐层渲染的方式实现。 数据结构设计 级联菜单的数据通常为嵌套结构,例如…

vue 实现多级菜单

vue 实现多级菜单

Vue 实现多级菜单的方法 递归组件实现 递归组件是处理多级菜单的常见方式,通过组件调用自身实现无限层级嵌套。 <template> <ul> <li v-…