<script setup lang="ts">
import { ref } from 'vue'
import { Switch } from '@hina-ui/vue'
const autoplay = ref(true)
</script>
<template>
<Switch v-model="autoplay">自动播放下一话</Switch>
</template>
vue
用法
import { Switch } from '@hina-ui/vue'
ts
开关表示一个立即生效的设置,与需要提交的复选框不同。v-model 绑定布尔值,默认插槽是文字,点文字与点轨道都会切换。未声明的属性都会传给内部的轨道元素。
当前值:false
<script setup lang="ts">
import { ref } from 'vue'
import { Switch, Stack, Text } from '@hina-ui/vue'
const nsfw = ref(false)
</script>
<template>
<Stack gap="sm">
<Switch v-model="nsfw">显示限制级内容</Switch>
<Text size="sm" tone="muted">当前值:{{ nsfw }}</Text>
</Stack>
</template>
vue
示例
描述
description 在文字下方补一行说明,字号比文字小一档。
<script setup lang="ts">
import { ref } from 'vue'
import { Switch } from '@hina-ui/vue'
const sync = ref(true)
</script>
<template>
<Switch v-model="sync" description="在其他设备上打开同一部作品时,从上次的位置继续。">
同步阅读进度
</Switch>
</template>
vue
设置行
使用 control-placement="end" 将控件放到文案末端,配合 block 撑满容器宽度。说明始终位于标题下方;start 和 end 会跟随文字方向。
<script setup lang="ts">
import { ref } from 'vue'
import { Switch } from '@hina-ui/vue'
const sync = ref(true)
</script>
<template>
<Switch
v-model="sync"
control-placement="end"
block
description="在其他设备上打开同一部作品时,从上次的位置继续。"
>
同步阅读进度
</Switch>
</template>
vue
尺寸
size 有 sm、md、lg 三档,轨道高分别为 20、24、28 像素,文字随档位变化。
<script setup lang="ts">
import { Switch, Stack } from '@hina-ui/vue'
</script>
<template>
<Stack gap="sm">
<Switch size="sm" model-value>小号</Switch>
<Switch size="md" model-value>中号</Switch>
<Switch size="lg" model-value>大号</Switch>
</Stack>
</template>
vue
状态
invalid 给轨道加上警示色边框;disabled 禁用整个控件。
<script setup lang="ts">
import { Switch, Stack } from '@hina-ui/vue'
</script>
<template>
<Stack gap="sm">
<Switch invalid>必须开启才能继续</Switch>
<Switch disabled>已禁用</Switch>
<Switch disabled model-value>已禁用且开启</Switch>
</Stack>
</template>
vue
仅轨道
没有文字时只渲染轨道,此时必须用 aria-label 命名。
<script setup lang="ts">
import { ref } from 'vue'
import { Switch, Inline } from '@hina-ui/vue'
const dark = ref(false)
</script>
<template>
<Inline gap="sm">
<Switch v-model="dark" aria-label="深色模式" />
</Inline>
</template>
vue
在表单中
放进 FormField 后,错误信息由字段渲染并关联到开关;校验规则与提交交给 Form。开关自带文字,字段不必再写标签;它的值常常决定其他字段是否必填,这类规则写在对象层,再指定错误落在哪个字段。
<script setup lang="ts">
import { reactive, ref } from 'vue'
import * as v from 'valibot'
import { Button, Form, FormField, Input, Switch, Text } from '@hina-ui/vue'
const schema = v.pipe(
v.object({
isPublic: v.boolean(),
summary: v.string(),
}),
v.forward(
v.check(
input => !input.isPublic || input.summary.trim().length > 0,
'公开的作品需要填写简介',
),
['summary'],
),
)
const values = reactive({ isPublic: true, summary: '' })
const saved = ref('')
async function save(data: unknown) {
await new Promise(resolve => setTimeout(resolve, 600))
saved.value = JSON.stringify(data)
}
</script>
<template>
<Form v-slot="{ submitting }" :values="values" :rules="schema" class="w-80" @submit="save">
<FormField name="isPublic">
<Switch v-model="values.isPublic">公开显示</Switch>
</FormField>
<FormField name="summary" label="简介">
<Input v-model="values.summary" />
</FormField>
<Button type="submit" :loading="submitting" class="self-start">保存</Button>
<Text v-if="saved" tone="muted" size="sm">已保存:{{ saved }}</Text>
</Form>
</template>
vue
行为
- 点击文字或者轨道都会切换,拇指滑到另一侧,轨道同时换色。键盘 Tab 落在轨道上,空格切换。
- 悬停整个控件时轨道落墨,按下时加深。
无障碍
- 轨道是
role="switch"的按钮,带aria-checked。根元素是label,文字即名称。 - 没有文字时通过
aria-label或者aria-labelledby命名。 invalid会同时设置aria-invalid。
API
Props
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
modelValue | boolean | false | 是否开启 |
size | 'sm' | 'md' | 'lg' | 'md' | 尺寸 |
description | string | — | 文字下方的说明 |
controlPlacement | 'start' | 'end' | 'start' | 控件相对于文案的位置 |
block | boolean | false | 整行撑满容器宽度 |
disabled | boolean | false | 是否禁用 |
invalid | boolean | false | 是否处于校验未通过状态 |
class | string | — | 追加至根元素的类名 |
插槽
| 插槽 | 参数 | 说明 |
|---|---|---|
default | — | 文字 |
事件
| 事件 | 参数 | 说明 |
|---|---|---|
update:modelValue | value: boolean | 值变化时 |