Skip to content

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,通过 themeactive-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>

全部属性

属性类型默认值作用描述适用范围
valueBoolean | String | Numberfalse开关值(兼容 v-model,低版本 uni-app)双向绑定
modelValueBoolean | String | Numberundefined开关值(v-model 推荐使用)双向绑定
activeValueBoolean | String | Numbertrue开启时对应的值自定义开启值
inactiveValueBoolean | String | Numberfalse关闭时对应的值自定义关闭值
themeString'primary'主题色:'primary' / 'success' / 'warning' / 'danger' / 'info'切换激活色
presetString''预设风格:'classic' / 'material' / 'minimal' / 'semantic'一键换风格
variantString'native'变体:'native' / 'filled' / 'outline' / 'soft'切换视觉形态
motionString''动效:'bounce'(弹性回弹)交互动效
activeColorString''自定义激活色精确控制颜色
colorString''自定义激活色(同 activeColor 别名)精确控制颜色
inactiveColorString''自定义关闭色精确控制颜色
typeString'switch'原生类型:'switch' / 'checkbox'原生形态
nameString''表单字段名配合 xtf-form
sizeString''尺寸:'sm' / 'md' / 'lg',默认继承 form / configProvider控制大小
disabledBooleanfalse是否禁用禁用交互
loadingBooleanfalse是否加载中异步操作
asyncBooleanfalse是否异步校验模式,配合 before-change校验拦截
beforeChangeFunctionnull切换前校验,返回 Promise<Boolean>异步拦截
activeTextString''开启时文案状态文案
inactiveTextString''关闭时文案状态文案
activeIconString''开启时图标名(xtf-icon状态图标
inactiveIconString''关闭时图标名状态图标
labelPlacementString'auto'文案位置:'inside' / 'outside-left' / 'outside-right' / 'none'文案布局
overflowStrategyString'auto-outside'文案溢出策略:'ellipsis' / 'inside-only'长文案处理
widthString | Number''自定义轨道宽度精确尺寸
customClassString''自定义类名样式覆盖
customStyleString | Object''自定义样式动态样式覆盖

事件

事件名称触发时机回调参数参数说明
change开关状态变化时触发(校验通过后)(value: Boolean | String | Number)切换后的值
input兼容低版本 v-model,状态变化时触发(value: Boolean | String | Number)切换后的值
update:modelValuev-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 变量。

MIT Licensed