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"