Skip to content

Switch 开关 ​

用于表达启用/停用、打开/关闭这类二元状态。

基础用法 ​

已关闭
vue
<template>
  <x-switch v-model="enabled" />
</template>

<script setup lang="ts">
import { ref } from 'vue';

const enabled = ref(false);
</script>

文案和自定义值 ​

enabled
vue
<template>
  <x-switch
    v-model="status"
    checked-value="enabled"
    unchecked-value="disabled"
    checked-text="开"
    unchecked-text="关"
  />
  <span>{{ status }}</span>
</template>

<script setup lang="ts">
import { ref } from 'vue';

const status = ref<'enabled' | 'disabled'>('enabled');
</script>

类型 ​

vue
<template>
  <x-switch v-model="enabled" type="circle" />
  <x-switch v-model="enabled" type="round" />
  <x-switch v-model="enabled" type="line" />
</template>

<script setup lang="ts">
import { ref } from 'vue';
const enabled = ref(false);
</script>

尺寸 ​

四档尺寸的高度依次为 16 / 16 / 24 / 28px;mini 与 small 目前共用同一档视觉规格。

vue
<template>
  <x-switch v-model="enabled" size="mini" />
  <x-switch v-model="enabled" size="small" />
  <x-switch v-model="enabled" size="medium" checked-text="开" unchecked-text="关" />
  <x-switch v-model="enabled" size="large" checked-text="开" unchecked-text="关" />
</template>

<script setup lang="ts">
import { ref } from 'vue';
const enabled = ref(false);
</script>

禁用 ​

vue
<template>
  <x-switch disabled />
  <x-switch :model-value="true" disabled />
</template>

加载中 ​

vue
<template>
  <x-switch loading />
  <x-switch :model-value="true" loading />
</template>

自定义颜色 ​

vue
<template>
  <x-switch
    v-model="enabled"
    checked-color="#0f766e"
    unchecked-color="#94a3b8"
    checked-text="启用"
    unchecked-text="停用"
  />
  <x-switch
    v-model="enabled"
    type="line"
    checked-color="#0f766e"
    unchecked-color="#94a3b8"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue';
const enabled = ref(false);
</script>

切换前校验 ​

异步校验期间会自动显示 loading,只允许切换到开启
vue
<template>
  <x-switch v-model="enabled" :before-change="beforeChange" />
</template>

<script setup lang="ts">
import { ref } from 'vue';

const enabled = ref(false);
const beforeChange = async (nextValue: boolean | string | number) => {
  await new Promise((resolve) => window.setTimeout(resolve, 600));
  return nextValue === true;
};
</script>

自定义图标 ​

vue
<template>
  <x-switch v-model="enabled">
    <template #checked-icon>✓</template>
    <template #unchecked-icon>×</template>
  </x-switch>
</template>

<script setup lang="ts">
import { ref } from 'vue';
const enabled = ref(false);
</script>

事件回调 ​

等待操作
vue
<template>
  <x-switch v-model="enabled" @change="handleChange" @click="handleClick" />
  <span>{{ eventLog }}</span>
</template>

<script setup lang="ts">
import { ref } from 'vue';

const enabled = ref(false);
const eventLog = ref('等待操作');
const clickCount = ref(0);
const handleChange = (value: boolean | string | number) => {
  eventLog.value = `当前值:${value}`;
};
const handleClick = (value: boolean | string | number) => {
  clickCount.value += 1;
  eventLog.value = `点击第 ${clickCount.value} 次,目标值:${value}`;
};
</script>

原生属性 ​

支持 id、name、tabindex、aria-* 等原生 button 属性透传
vue
<template>
  <x-switch
    id="notification-switch"
    name="notification"
    autofocus
    aria-label="通知开关"
  />
</template>

方法 ​

vue
<template>
  <x-switch ref="switchRef" v-model="enabled" />
  <x-button @click="switchRef?.focus()">聚焦</x-button>
  <x-button @click="switchRef?.blur()">失焦</x-button>
</template>

<script setup lang="ts">
import { ref } from 'vue';

const enabled = ref(false);
const switchRef = ref();
</script>

在 Form 中校验 ​

组件放进 x-form-item 后会自动继承 Form 的尺寸与禁用状态,并按 FormItem 的校验规则展示错误。默认 validateTrigger 为 change,即值变化时触发校验。

vue
<template>
  <x-form ref="formRef" :model="formState" :rules="formRules">
    <x-form-item field="enabled" label="启用通知">
      <x-switch v-model="formState.enabled" />
    </x-form-item>
    <x-form-item>
      <x-space>
        <x-button type="primary" @click="handleValidate">校验</x-button>
        <x-button @click="handleReset">重置</x-button>
      </x-space>
    </x-form-item>
  </x-form>
  <p role="status">{{ validateResult }}</p>
</template>

<script setup lang="ts">
import { reactive, ref } from 'vue';
import type { FormInstance, FieldRule } from 'x-next';

const formState = reactive({ enabled: false });
const formRules: Record<string, FieldRule[]> = {
  enabled: [{ type: 'boolean', true: true, message: '需要启用通知' }],
};
const formRef = ref<FormInstance>();
const validateResult = ref('');

const handleValidate = async () => {
  const errors = await formRef.value!.validate();
  validateResult.value = errors
    ? `校验失败:${Object.values(errors).map((error) => error.message).join(';')}`
    : '校验通过';
};
const handleReset = () => {
  formRef.value!.resetFields();
  validateResult.value = '已重置';
};
</script>

按需导入 ​

ts
import { Switch } from 'x-next';

样式按需引入(base.css 为共享基础层,多个组件只需引入一次):

ts
import 'x-next/style/base.css';
import 'x-next/style/form-switch.css';

Props ​

参数说明类型默认值
modelValue绑定值string | number | booleanundefined
defaultChecked默认选中状态,非受控模式booleanfalse
disabled是否禁用booleanfalse
loading是否加载中booleanfalse
autofocus是否自动获取焦点booleanfalse
type开关类型'circle' | 'round' | 'line''circle'
size开关尺寸'mini' | 'small' | 'medium' | 'large'跟随全局配置
checkedValue选中时的值string | number | booleantrue
uncheckedValue未选中时的值string | number | booleanfalse
checkedColor选中时颜色string-
uncheckedColor未选中时颜色string-
beforeChange切换前钩子,返回 false 或 Promise reject 时阻止切换(value) => boolean | void | Promise<boolean | void>-
checkedText选中时文案,type="line" 时不显示string-
uncheckedText未选中时文案,type="line" 时不显示string-

Events ​

事件名说明回调参数
update:modelValue值更新时触发value
change值变化时触发value, event
click点击时触发,返回本次尝试切换的目标值value, event
focus获取焦点时触发event
blur失去焦点时触发event

Slots ​

插槽名说明
checked选中时文案
unchecked未选中时文案
checked-icon选中时按钮图标
unchecked-icon未选中时按钮图标

Methods ​

方法名说明
focus()聚焦开关
blur()取消聚焦