创建一个 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 事件监听状态变更
相关推荐
gc_22996 小时前
Vue框架学习(1:环境搭建)
vue.js
原则猫7 小时前
UDP 到底怎么实现可靠的
前端
Java后端的Ai之路7 小时前
14、ReactJS - 路由(Router)
前端·react.js·状态模式
持敬chijing7 小时前
白盒测试与代码审计-js登录逆向实战
javascript·网络·安全·web安全·网络安全·网络攻击模型
优选资源分享8 小时前
PicGo v3.0.3 新版 | 开源免费图床工具
javascript·笔记·electron
裕晟资质规划8 小时前
三类涉密资质延续时限差异分析:军工60日与集成印制3个月的边界
java·服务器·前端·网络·安全
ShineWinsu8 小时前
对于JavaScript:JavaScript基础语法的解析
开发语言·前端·javascript·面试·web·基础语法·循环
月夏9 小时前
Vue3 转 React:18 项对照表 + 5 个必踩的坑(附 7 天上手路线)
前端
广州华水科技9 小时前
单北斗GNSS位移监测系统的应用与维护解析
前端
普通人69 小时前
php+html+canvas实现树状打开的结构
开发语言·javascript·html5·1024程序员节