创建一个 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 事件监听状态变更
相关推荐
2501_944525547 小时前
Flutter for OpenHarmony 个人理财管理App实战 - 预算详情页面
android·开发语言·前端·javascript·flutter·ecmascript
打小就很皮...7 小时前
《在 React/Vue 项目中引入 Supademo 实现交互式新手指引》
前端·supademo·新手指引
C澒7 小时前
系统初始化成功率下降排查实践
前端·安全·运维开发
摘星编程7 小时前
React Native + OpenHarmony:自定义useFormik表单处理
javascript·react native·react.js
C澒7 小时前
面单打印服务的监控检查事项
前端·后端·安全·运维开发·交通物流
pas1368 小时前
39-mini-vue 实现解析 text 功能
前端·javascript·vue.js
qq_532453538 小时前
使用 GaussianSplats3D 在 Vue 3 中构建交互式 3D 高斯点云查看器
前端·vue.js·3d
Swift社区8 小时前
Flutter 路由系统,对比 RN / Web / iOS 有什么本质不同?
前端·flutter·ios
2601_949833398 小时前
flutter_for_openharmony口腔护理app实战+我的实现
开发语言·javascript·flutter
雾眠气泡水@8 小时前
前端:解决同一张图片由于页面大小不统一导致图片模糊
前端