创建一个 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 事件监听状态变更
相关推荐
我命由我123455 小时前
CesiumJS 笔记 - 获取容器中心点、Cartesian3 clone 方法、修改 Cartesian3 对象的高度
前端·javascript·css·前端框架·html·html5·js
Hopebearer_6 小时前
页面突然只剩 DOM?一次静态资源版本错配排查
前端·部署
抱抱宝6 小时前
Agent-study项目教程(03):手写 Mini-ReAct Agent(不依赖框架)
javascript·人工智能·gpt·react.js·prompt·agent
东风破_6 小时前
ESLint 是什么?为什么你的项目需要它?
前端·后端·代码规范
用户938515635077 小时前
Next.js 笔记系统(二):Redis 数据服务与侧边栏组件拆分实战
javascript·全栈
java1234_小锋8 小时前
Vue3专题 - 组件基础
vue.js·vite
圣殿骑士-Khtangc8 小时前
Go字符串高效拼接性能对比与底层原理分析
服务器·前端·golang
BigTopOne9 小时前
【ijkplayer】 硬解码流程
前端
kyriewen9 小时前
DeepSeek Harness开源第一天我就上手了——和Claude Code的差距比想象中大
前端·ai编程·deepseek
捡田螺的小男孩9 小时前
什么是 Skill?手把手带你写一个简单有用的 Skill!
前端·后端·程序员