diff --git a/src/button/README.md b/src/button/README.md
index 60b52beef..ace847b72 100644
--- a/src/button/README.md
+++ b/src/button/README.md
@@ -139,6 +139,7 @@ Vue.use(Button);
 | Name              | Description         |
 | ----------------- | ------------------- |
 | default           | Default slot        |
+| icon `v2.12.21`   | Custom icon         |
 | loading `v2.10.1` | Custom loading icon |
 
 ### Less Variables
diff --git a/src/button/README.zh-CN.md b/src/button/README.zh-CN.md
index daf9831d2..b6f57039f 100644
--- a/src/button/README.zh-CN.md
+++ b/src/button/README.zh-CN.md
@@ -166,6 +166,7 @@ Vue.use(Button);
 | 名称              | 说明           |
 | ----------------- | -------------- |
 | default           | 按钮内容       |
+| icon `v2.12.21`   | 自定义图标     |
 | loading `v2.10.1` | 自定义加载图标 |
 
 ### 样式变量
diff --git a/src/button/index.tsx b/src/button/index.tsx
index fc1c8f8e5..6dff5cc7b 100644
--- a/src/button/index.tsx
+++ b/src/button/index.tsx
@@ -43,6 +43,7 @@ export type ButtonEvents = {
 };
 
 export type ButtonSlots = DefaultSlots & {
+  icon?: ScopedSlot;
   loading?: ScopedSlot;
 };
 
@@ -130,6 +131,10 @@ function Button(
       );
     }
 
+    if (slots.icon) {
+      return <div class={bem('icon')}>{slots.icon()}</div>;
+    }
+
     if (icon) {
       return (
         <Icon name={icon} class={bem('icon')} classPrefix={props.iconPrefix} />