diff --git a/packages/vant/src/switch/README.md b/packages/vant/src/switch/README.md index 891f235f5..b4ade437a 100644 --- a/packages/vant/src/switch/README.md +++ b/packages/vant/src/switch/README.md @@ -59,6 +59,37 @@ export default { <van-switch v-model="checked" active-color="#ee0a24" inactive-color="#dcdee0" /> ``` +### Custom Node + +Using `node` slot to custom the content of the node. + +```html +<van-switch v-model="checked"> + <div class="icon-wrapper"> + <van-icon :name="checked ? 'success' : 'cross'" /> + </div> +</van-switch> + +<style> + .icon-wrapper { + display: flex; + width: 100%; + justify-content: center; + font-size: 18px; + } + + .icon-wrapper .van-icon-success { + line-height: 32px; + color: var(--van-blue); + } + + .icon-wrapper .van-icon-cross { + line-height: 32px; + color: var(--van-gray-5); + } +</style> +``` + ### Async Control ```html @@ -121,6 +152,12 @@ export default { | change | Emitted when check status changed | _value: any_ | | click | Emitted when component is clicked | _event: MouseEvent_ | +### Slots + +| Name | Description | SlotProps | +| ------------- | -------------------------- | --------- | +| node `v3.5.0` | Custom the content of node | - | + ### Types The component exports the following type definitions: diff --git a/packages/vant/src/switch/README.zh-CN.md b/packages/vant/src/switch/README.zh-CN.md index 1060bde00..371c5653e 100644 --- a/packages/vant/src/switch/README.zh-CN.md +++ b/packages/vant/src/switch/README.zh-CN.md @@ -69,6 +69,37 @@ export default { <van-switch v-model="checked" active-color="#ee0a24" inactive-color="#dcdee0" /> ``` +### 自定义按钮 + +通过 `node` 插槽自定义按钮的内容。 + +```html +<van-switch v-model="checked"> + <div class="icon-wrapper"> + <van-icon :name="checked ? 'success' : 'cross'" /> + </div> +</van-switch> + +<style> + .icon-wrapper { + display: flex; + width: 100%; + justify-content: center; + font-size: 18px; + } + + .icon-wrapper .van-icon-success { + line-height: 32px; + color: var(--van-blue); + } + + .icon-wrapper .van-icon-cross { + line-height: 32px; + color: var(--van-gray-5); + } +</style> +``` + ### 异步控制 需要异步控制开关时,可以使用 `modelValue` 属性和 `update:model-value` 事件代替 `v-model`,并在事件回调函数中手动处理开关状态。 @@ -133,6 +164,12 @@ export default { | change | 开关状态切换时触发 | _value: any_ | | click | 点击时触发 | _event: MouseEvent_ | +### Slots + +| 名称 | 说明 | 参数 | +| ------------- | ---------------- | ---- | +| node `v3.5.0` | 自定义按钮的内容 | - | + ### 类型定义 组件导出以下类型定义: diff --git a/packages/vant/src/switch/Switch.tsx b/packages/vant/src/switch/Switch.tsx index bfc337f80..73f18c997 100644 --- a/packages/vant/src/switch/Switch.tsx +++ b/packages/vant/src/switch/Switch.tsx @@ -31,7 +31,7 @@ export default defineComponent({ emits: ['change', 'update:modelValue'], - setup(props, { emit }) { + setup(props, { emit, slots }) { const isChecked = () => props.modelValue === props.activeValue; const onClick = () => { @@ -47,6 +47,9 @@ export default defineComponent({ const color = isChecked() ? props.activeColor : props.inactiveColor; return <Loading class={bem('loading')} color={color} />; } + if (slots.node) { + return slots.node(); + } }; useCustomFieldValue(() => props.modelValue); diff --git a/packages/vant/src/switch/demo/index.vue b/packages/vant/src/switch/demo/index.vue index d25649edc..9786a5e43 100644 --- a/packages/vant/src/switch/demo/index.vue +++ b/packages/vant/src/switch/demo/index.vue @@ -1,6 +1,7 @@ <script setup lang="ts"> import VanSwitch from '..'; import VanCell from '../../cell'; +import VanIcon from '../../icon'; import { ref } from 'vue'; import { useTranslate } from '../../../docs/site'; import { Dialog } from '../../dialog'; @@ -12,6 +13,7 @@ const t = useTranslate({ message: '是否切换开关?', withCell: '搭配单元格使用', customSize: '自定义大小', + customNode: '自定义按钮', customColor: '自定义颜色', asyncControl: '异步控制', }, @@ -21,6 +23,7 @@ const t = useTranslate({ message: 'Are you sure to toggle switch?', withCell: 'Inside a Cell', customSize: 'Custom Size', + customNode: 'Custom Node', customColor: 'Custom Color', asyncControl: 'Async Control', }, @@ -67,6 +70,16 @@ const onUpdateValue = (checked: boolean) => { /> </demo-block> + <demo-block :title="t('customNode')"> + <van-switch v-model="checked3"> + <template #node> + <div class="icon-wrapper"> + <van-icon :name="checked3 ? 'success' : 'cross'" /> + </div> + </template> + </van-switch> + </demo-block> + <demo-block :title="t('asyncControl')"> <van-switch :model-value="checked4" @update:model-value="onUpdateValue" /> </demo-block> @@ -85,5 +98,24 @@ const onUpdateValue = (checked: boolean) => { .van-switch { margin-left: var(--van-padding-md); } + + .icon-wrapper { + display: flex; + width: 100%; + justify-content: center; + font-size: 18px; + + .van-icon { + line-height: 32px; + } + + .van-icon-success { + color: var(--van-blue); + } + + .van-icon-cross { + color: var(--van-gray-5); + } + } } </style> diff --git a/packages/vant/src/switch/test/__snapshots__/demo.spec.ts.snap b/packages/vant/src/switch/test/__snapshots__/demo.spec.ts.snap index 9fb98aeb5..ff1c16bcc 100644 --- a/packages/vant/src/switch/test/__snapshots__/demo.spec.ts.snap +++ b/packages/vant/src/switch/test/__snapshots__/demo.spec.ts.snap @@ -69,6 +69,20 @@ exports[`should render demo and match snapshot 1`] = ` </div> </div> </div> +<div> + <div role="switch" + class="van-switch van-switch--on" + tabindex="0" + aria-checked="true" + > + <div class="van-switch__node"> + <div class="icon-wrapper"> + <i class="van-badge__wrapper van-icon van-icon-success"> + </i> + </div> + </div> + </div> +</div> <div> <div role="switch" class="van-switch van-switch--on"