创建一个 Vue 2 三开关组件 ThreeStateSwitch

创建一个 Vue 2 三开关组件 ThreeStateSwitch,它支持:

  • 三个状态:关闭(off)、慢速(slow)、快速(fast)
  • 动画过渡:使用 CSS transition 和 cubic-bezier 实现平滑滑块移动
  • 交互行为:点击切换状态,并触发 input 和 change 事件
  • 禁用状态:可通过 disabled 属性控制是否可交互

效果展示:

ThreeStateSwitch组件

javascript 复制代码
// ThreeStateSwitch.vue
<template>
  <div class="three-state-switch" :class="{ 'is-disabled': disabled }">
    <div class="switch-track" >
      <div class="switch-thumb" :style="{ transform: thumbTransform }"></div>
      <div class="switch-labels">
        <span :class="{ active: value === 'off' }"  @click="toggle('off')">关闭</span>
        <span :class="{ active: value === 'slow' }"  @click="toggle('slow')">慢速</span>
        <span :class="{ active: value === 'fast' }"  @click="toggle('fast')">快速</span>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'ThreeStateSwitch',
  props: {
    value: {
      type: String,
      default: 'off',
      validator: (val) => ['off', 'slow', 'fast'].includes(val)
    },
    disabled: {
      type: Boolean,
      default: false
    }
  },
  computed: {
    thumbTransform() {
      let index = 0;
      if (this.value === 'slow') index = 1;
      if (this.value === 'fast') index = 2;
      // Calculate translateX for smooth transition
      const positions = ['15%', '145%', '275%'];
      return `translateX(${positions[index]})`;
    }
  },
  methods: {
    toggle(status) {
      if (this.disabled) return;
      const states = ['off', 'slow', 'fast'];
      const currentIndex = states.indexOf(status);
      const newValue = states[currentIndex];
      this.$emit('input', newValue);
      this.$emit('change', newValue);
    }
  }
};
</script>

<style scoped>
.three-state-switch {
  display: inline-block;
  position: relative;
}

.switch-track {
  width: 100px;
  height: 30px;
  background-color: #dcdfe6;
  border-radius: 15px;
  position: relative;
  cursor: pointer;
  transition: background-color 0.3s;
  box-sizing: border-box;
}

.switch-track:hover:not(.is-disabled) {
  background-color: #bcbcbc;
}

.is-disabled .switch-track {
  opacity: 0.6;
  cursor: not-allowed;
}

.switch-thumb {
  width: 26px;
  height: 26px;
  background-color: white;
  border-radius: 50%;
  position: absolute;
  top: 2px;
  transition: transform 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55); /* Smooth easing */
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12);
}

.switch-labels {
  position: absolute;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: space-around;
  align-items: center;
  color: #edf0f6;
  font-size: 12px;
  
}

.switch-labels span {
  transition: color 0.3s;
  z-index: 1;
}

.switch-labels span.active {
  color:#159a8d;
  font-weight: bold;
}

/* Active track background */
.three-state-switch .switch-track {
  background-color:#159a8d;
}

.three-state-switch .switch-track:hover:not(.is-disabled) {
  background-color: #29c3b4;
}
</style>

使用方法示例

javascript 复制代码
<template>
  <div>
    <ThreeStateSwitch v-model="mode" />
    <p>当前状态: {{ mode }}</p>
  </div>
</template>

<script>
import ThreeStateSwitch from './components/ThreeStateSwitch.vue';

export default {
  components: { ThreeStateSwitch },
  data() {
    return {
      mode: 'off' // 初始状态
    };
  }
};
</script>

特性说明:

  • 滑块在三个位置之间平滑移动(关闭、慢速、快速)
  • 标签颜色随当前状态高亮显示
  • 背景色根据激活状态变化(蓝色背景)
  • 支持 v-model 双向绑定
  • 支持 disabled 属性禁用交互
  • 支持 @change 事件监听状态变更
相关推荐
啾咪orJIUMI2 小时前
Vue 3 + 高德地图封装实战:点位、区域、Loca 流光与 Vue 信息窗体
前端·vue.js
掘金者阿豪2 小时前
AI数据库不只是向量检索:从数据语义到库内智能计算的技术演进
前端
梦里寻码2 小时前
我用 NestJS + Vue3 写了一套完整的研发管理系统(58 表 / 229 API / 130 项断言,全开源
前端·后端·算法
FRing032 小时前
vue2干货总结8(路由模块封装、router-link、声明式导航、路由重定向、编程式导航)
开发语言·前端·vue.js·vue2
SameX2 小时前
HarmonyOS ArkUI Dialog 复用 用 @CustomDialog + enum type 做多类型统一管理的做法
前端
AiMan2 小时前
豆包爱学还是不可以导出左侧所有对话,只能单容导出,方法不对吗
前端
无懈可击3 小时前
Vue 可视化AI表单设计器 FcDesigner v3.6 版本发布,支持导出 SQL功能!
vue.js·开源·ai编程
AiMan3 小时前
Grok生成的内容能否下载吗?
前端
徐小夕3 小时前
JitArchives,一款基于JitWord协同AI文档打造的企业级电子档案系统
前端·vue.js·github
陈随易3 小时前
Node.js 2026上半年都有哪些性能提升?
前端·后端·程序员