创建一个 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 事件监听状态变更