Element Plus 组件库实现:9. Switch组件

前言

Switch组件,顾名思义,就像现实生活中的开关一样,允许用户在两种状态之间切换。在数字界面中,这通常意味着一个按钮或滑块,用户可以通过点击或拖动来切换其状态。无论是在移动应用、网页还是桌面软件中,Switch组件都因其直观性和易用性而受到开发者和用户的青睐。本文将简单介绍Switch组件的实现。

组件分析

在原生HTML中,很难找到和Switch组件相似的标签,但是如果你去看过类似Element Plus等组件库的源码,你会发现Switch内部其实是由一个checkbox(复选框)实现的,checkbox允许用户选择多个选项,每个选项都是独立的,用户可以选择一个、多个或者都不选。而Switch组件设计的初衷也就是为了提供一个在两种状态之间简单切换的控件,这就与checkbox不谋而合了。

看到这里,你也许会问,为什么不适用radio(单选框)呢?相比于checkbox,radio用于在一组选择中选择一个,他要求的是用户从一组互斥的选项中做出选择,那么这样就与Switch组件的设计目的不相符了。对比之下,checkbox更适合作为Switch组件的内部实现。

需求分析

一个Switch组件需要的基本功能其实并不多:

  • 开/关两种状态
  • 不同状态对应的值以及文字描述
  • 样式实现

通过Switch组件的需求分析,我们不难想到,前两个需求是比较容易实现的,样式现在反而成了这个组件比较难的一块儿。

确定方案

  • 属性
ts 复制代码
export type SwitchValueType = boolean | number | string

export interface SwitchProps {
  // 实现v-model必备属性
  modelValue: SwitchValueType
  disabled?: boolean
  // 打开状态下的文字描述
  activeText?: string
  // 关闭状态下的文字描述
  inactiveText?: string
  // 打开状态下的值
  activeValue?: SwitchValueType
  // 关闭状态下的值
  inactiveValue?: SwitchValueType
  name?: string
  // input 的 id
  id?: string
  size?: 'small' | 'large'
}
  • 事件
ts 复制代码
export interface SwitchEmits {
   // 切换状态改变派发事件 
  (e: 'change', value: SwitchValueType): void
  // 结合modelValue实现v-model
  (e: 'update:modelValue', value: SwitchValueType): void
}
  • 组件
html 复制代码
<template>
    <div class="yv-switch">
        <input class="yv-switch__input" />
        <div class="yv-switch__core">
            <div class="yv-switch__core-inner">
                <span class="yv-switch__core-inner-text"></span>
            </div>
            <div class="yv-switch__core-action"></div>
        </div>
    </div>
</template>

代码实现

  • 开/关两种状态
ts 复制代码
const innerValue = ref(props.modelValue)
// 是否被选中
const checked = computed(() => innerValue.value === props.activeValue)
const switchValue = () => {
    if (props.disabled) return
    const newValue = checked.value ? props.inactiveValue : props.activeValue
    innerValue.value = newValue
    emits("update:modelValue", newValue)
    emits("change", newValue)
}
  • 不同状态对应的值以及文字描述
html 复制代码
<div class="yv-switch__core-inner">
    <span class="yv-switch__core-inner-text" v-if="activeText || inactiveText">
        {{ checked ? activeText : inactiveText }}
    </span>
</div>

不同状态对应不同的描述

  • 自定义开/关对应的值
ts 复制代码
const props = withDefaults(defineProps<SwitchProps>(), {
    activeValue: true,
    inactiveValue: false
})

默认为true和false,使用时可自定义,如: <Switch v-model="test" activeValue="right" inactiveValue="wrong"/>

总结

本文简单介绍了一个Switch组件的基本实现,剩下的就是样式实现,相比于之前的其他组件,Switch组件的样式反而比功能复杂一些,但样式不是本组件库的主要任务,这里不再一一赘述。

相关推荐
benbenAItalk3 小时前
数字人口播视频的批量生产实践:素材规范、任务编排与质量验收
java·前端·音视频
2601_962885724 小时前
如何用 Python 扫描 A 股跳空缺口并统计缺口回补概率?
java·前端·python
西瓜太郎12344 小时前
Claude Code、Codex CLI、Gemini CLI 能否共用一枚 Key?先看协议选择矩阵
前端·api 网关·claude code·gemini cli·codex cli
冬奇Lab6 小时前
一天一个开源项目(第216篇):OpenViking - 给 AI Agent 装上可自进化的上下文数据库
人工智能·开源·资讯
陈随易6 小时前
在Finch用了62亿词元,我认为这是新一代Agent工具之神
前端·人工智能·后端
水域安全老周6 小时前
水趣钓鱼救生衣专利拆解:两级锁紧如何解决落水人衣分离
java·前端·网络
传奇开心果编程7 小时前
【Xilem基础语法学与练】第7课:Xilem与Masonry底层构建技术解析
学习·rust·前端框架
计算机魔术师7 小时前
Anthropic CEO突然喊踩刹车,OpenAI罕见力挺:AI这辆车不能只踩油门了
前端
wing987 小时前
从codex转战workbuddy使用一周的感受
前端·人工智能·后端
EatFan7 小时前
Java接入支付宝 JSAPI 支付保姆教程(二):流程讲解与前后端代码讲解
前端·spring boot·后端·微信小程序·小程序·uni-app