xtf-switch
组件说明
xtf-switch 是开关组件,用于在两种状态间切换。支持原生 native 与自定义 filled / outline / soft 四种变体、sm / md / lg 三种尺寸、classic / material / minimal / semantic 四种预设风格、开关文字/图标内嵌或外置,以及 async 异步校验(beforeChange)能力,是表单中布尔值录入的核心组件。
基础用法
1. 最简示例
通过 v-model 双向绑定开关状态,theme 控制主题色:
vue
<template>
<view style="display: flex; flex-direction: column; gap: 32rpx; padding: 32rpx">
<xtf-switch v-model="value1" />
<xtf-text level="caption" color="secondary" :text="'当前值: ' + value1" />
</view>
</template>
<script>
export default {
data() {
return { value1: false }
}
}
</script>2. 自定义变体与颜色
通过 variant 切换 native / filled / outline / soft,通过 theme 或 active-color 自定义激活色:
vue
<template>
<view style="display: flex; flex-direction: column; gap: 32rpx; padding: 32rpx">
<view style="display: flex; gap: 32rpx; align-items: center">
<xtf-switch v-model="v1" variant="native" />
<xtf-text text="原生" level="caption" />
</view>
<view style="display: flex; gap: 32rpx; align-items: center">
<xtf-switch v-model="v2" variant="filled" theme="success" />
<xtf-text text="填充·成功" level="caption" />
</view>
<view style="display: flex; gap: 32rpx; align-items: center">
<xtf-switch v-model="v3" variant="outline" theme="warning" />
<xtf-text text="描边·警告" level="caption" />
</view>
<view style="display: flex; gap: 32rpx; align-items: center">
<xtf-switch v-model="v4" variant="soft" active-color="#8B5CF6" />
<xtf-text text="柔和·自定义紫" level="caption" />
</view>
</view>
</template>
<script>
export default {
data() {
return { v1: false, v2: true, v3: false, v4: true }
}
}
</script>3. 开关文字与图标
通过 active-text / inactive-text / active-icon / inactive-icon 在开关内部展示状态文案或图标:
vue
<template>
<view style="display: flex; flex-direction: column; gap: 32rpx; padding: 32rpx">
<xtf-switch v-model="open" variant="filled" active-text="开" inactive-text="关" />
<xtf-switch v-model="night" variant="soft" active-icon="dark_mode" inactive-icon="light_mode" />
<xtf-switch v-model="vip" variant="filled" active-text="已开通" inactive-text="未开通" />
</view>
</template>
<script>
export default {
data() {
return { open: true, night: false, vip: true }
}
}
</script>4. 标签外置
通过 label-placement 将开关文案放置于 outside-left / outside-right:
vue
<template>
<view style="display: flex; flex-direction: column; gap: 32rpx; padding: 32rpx">
<xtf-switch
v-model="notify"
variant="filled"
active-text="开启通知"
inactive-text="关闭通知"
label-placement="outside-left"
/>
<xtf-switch
v-model="sound"
variant="filled"
active-text="声音"
inactive-text="静音"
label-placement="outside-right"
/>
</view>
</template>
<script>
export default {
data() {
return { notify: true, sound: false }
}
}
</script>5. 加载与禁用
通过 loading 显示加载态,通过 disabled 禁用:
vue
<template>
<view style="display: flex; flex-direction: column; gap: 32rpx; padding: 32rpx">
<view style="display: flex; gap: 32rpx; align-items: center">
<xtf-switch v-model="v1" loading />
<xtf-text text="加载中" level="caption" />
</view>
<view style="display: flex; gap: 32rpx; align-items: center">
<xtf-switch v-model="v2" disabled />
<xtf-text text="禁用" level="caption" />
</view>
</view>
</template>
<script>
export default {
data() {
return { v1: false, v2: true }
}
}
</script>6. 异步校验(beforeChange)
通过 async + before-change 在切换前做异步校验,校验不通过时自动回滚状态:
vue
<template>
<view style="display: flex; flex-direction: column; gap: 32rpx; padding: 32rpx">
<xtf-text text="开启后模拟 1.5s 延迟" level="caption" color="secondary" />
<xtf-switch v-model="autoBackup" async :before-change="beforeBackup" @change="onChange" />
</view>
</template>
<script>
export default {
data() {
return { autoBackup: false }
},
methods: {
beforeBackup(nextChecked) {
// 返回 Promise<boolean>,true 允许切换,false 回滚
return new Promise((resolve) => {
uni.showLoading({ title: '校验中...' })
setTimeout(() => {
uni.hideLoading()
if (nextChecked) {
uni.showToast({ title: '校验通过', icon: 'success' })
resolve(true)
} else {
uni.showToast({ title: '校验失败,已回滚', icon: 'none' })
resolve(false)
}
}, 1500)
})
},
onChange(val) {
console.log('开关状态:', val)
}
}
}
</script>全部属性
| 属性 | 类型 | 默认值 | 作用描述 | 适用范围 |
|---|---|---|---|---|
value | Boolean | String | Number | false | 开关值(兼容 v-model,低版本 uni-app) | 双向绑定 |
modelValue | Boolean | String | Number | undefined | 开关值(v-model 推荐使用) | 双向绑定 |
activeValue | Boolean | String | Number | true | 开启时对应的值 | 自定义开启值 |
inactiveValue | Boolean | String | Number | false | 关闭时对应的值 | 自定义关闭值 |
theme | String | 'primary' | 主题色:'primary' / 'success' / 'warning' / 'danger' / 'info' | 切换激活色 |
preset | String | '' | 预设风格:'classic' / 'material' / 'minimal' / 'semantic' | 一键换风格 |
variant | String | 'native' | 变体:'native' / 'filled' / 'outline' / 'soft' | 切换视觉形态 |
motion | String | '' | 动效:'bounce'(弹性回弹) | 交互动效 |
activeColor | String | '' | 自定义激活色 | 精确控制颜色 |
color | String | '' | 自定义激活色(同 activeColor 别名) | 精确控制颜色 |
inactiveColor | String | '' | 自定义关闭色 | 精确控制颜色 |
type | String | 'switch' | 原生类型:'switch' / 'checkbox' | 原生形态 |
name | String | '' | 表单字段名 | 配合 xtf-form |
size | String | '' | 尺寸:'sm' / 'md' / 'lg',默认继承 form / configProvider | 控制大小 |
disabled | Boolean | false | 是否禁用 | 禁用交互 |
loading | Boolean | false | 是否加载中 | 异步操作 |
async | Boolean | false | 是否异步校验模式,配合 before-change | 校验拦截 |
beforeChange | Function | null | 切换前校验,返回 Promise<Boolean> | 异步拦截 |
activeText | String | '' | 开启时文案 | 状态文案 |
inactiveText | String | '' | 关闭时文案 | 状态文案 |
activeIcon | String | '' | 开启时图标名(xtf-icon) | 状态图标 |
inactiveIcon | String | '' | 关闭时图标名 | 状态图标 |
labelPlacement | String | 'auto' | 文案位置:'inside' / 'outside-left' / 'outside-right' / 'none' | 文案布局 |
overflowStrategy | String | 'auto-outside' | 文案溢出策略:'ellipsis' / 'inside-only' | 长文案处理 |
width | String | Number | '' | 自定义轨道宽度 | 精确尺寸 |
customClass | String | '' | 自定义类名 | 样式覆盖 |
customStyle | String | Object | '' | 自定义样式 | 动态样式覆盖 |
事件
| 事件名称 | 触发时机 | 回调参数 | 参数说明 |
|---|---|---|---|
change | 开关状态变化时触发(校验通过后) | (value: Boolean | String | Number) | 切换后的值 |
input | 兼容低版本 v-model,状态变化时触发 | (value: Boolean | String | Number) | 切换后的值 |
update:modelValue | v-model 同步 | (value: Boolean | String | Number) | 切换后的值 |
update:value | 兼容 :value 同步 | (value: Boolean | String | Number) | 切换后的值 |
事件使用示例
vue
<template>
<view style="display: flex; flex-direction: column; gap: 32rpx; padding: 32rpx">
<xtf-switch
v-model="wifi"
variant="filled"
active-text="WiFi 已开启"
inactive-text="WiFi 已关闭"
@change="onChange"
/>
<xtf-text level="caption" color="secondary" :text="'WiFi 状态: ' + (wifi ? '开' : '关')" />
</view>
</template>
<script>
export default {
data() {
return { wifi: false }
},
methods: {
onChange(val) {
console.log('开关切换,新值:', val)
uni.showToast({
title: val ? 'WiFi 已开启' : 'WiFi 已关闭',
icon: 'none'
})
}
}
}
</script>主题说明
- 激活色使用
var(--xtf-switch-active-color),柔和色使用var(--xtf-switch-soft-color),关闭色使用var(--xtf-switch-inactive-color) - 轨道尺寸使用
var(--xtf-switch-track-width)/var(--xtf-switch-track-height)/var(--xtf-switch-thumb-size)/var(--xtf-switch-padding)/var(--xtf-switch-thumb-shift) material预设使用--xtf-switch-material-*系列变量,minimal使用--xtf-switch-minimal-*,semantic使用--xtf-switch-semantic-*- 文案字号使用
var(--xtf-switch-font-size),加载点使用var(--xtf-switch-loading-dot-size)
如需全局调整主题,请在 xtf-config-provider 或主题配置中覆盖上述 CSS 变量。