diff --git a/components/qrcode/QRCodeCanvas.tsx b/components/qrcode/QRCode.tsx
similarity index 77%
rename from components/qrcode/QRCodeCanvas.tsx
rename to components/qrcode/QRCode.tsx
index 787c89946..7e18176c0 100644
--- a/components/qrcode/QRCodeCanvas.tsx
+++ b/components/qrcode/QRCode.tsx
@@ -265,3 +265,85 @@ export const QRCodeCanvas = defineComponent({
};
},
});
+
+export const QRCodeSVG = defineComponent({
+ name: 'QRCodeSVG',
+ inheritAttrs: false,
+ props: {
+ ...qrProps(),
+ color: String,
+ level: String,
+ bgColor: String,
+ fgColor: String,
+ marginSize: Number,
+ title: String,
+ },
+ setup(props) {
+ let cells = null;
+ let margin = null;
+ let numCells = null;
+ let calculatedImageSettings = null;
+
+ let fgPath = null;
+ let image = null;
+
+ watchEffect(() => {
+ const {
+ value,
+ size = DEFAULT_SIZE,
+ level = DEFAULT_LEVEL,
+ includeMargin = DEFAULT_INCLUDEMARGIN,
+ marginSize,
+ imageSettings,
+ } = props;
+
+ cells = qrcodegen.QrCode.encodeText(value, ERROR_LEVEL_MAP[level]).getModules();
+
+ margin = getMarginSize(includeMargin, marginSize);
+ numCells = cells.length + margin * 2;
+ calculatedImageSettings = getImageSettings(cells, size, margin, imageSettings);
+
+ if (imageSettings != null && calculatedImageSettings != null) {
+ if (calculatedImageSettings.excavation != null) {
+ cells = excavateModules(cells, calculatedImageSettings.excavation);
+ }
+
+ image = (
+
+ );
+ }
+
+ // Drawing strategy: instead of a rect per module, we're going to create a
+ // single path for the dark modules and layer that on top of a light rect,
+ // for a total of 2 DOM nodes. We pay a bit more in string concat but that's
+ // way faster than DOM ops.
+ // For level 1, 441 nodes -> 2
+ // For level 40, 31329 -> 2
+ fgPath = generatePath(cells, margin);
+ });
+
+ return () => {
+ const bgColor = props.bgColor && DEFAULT_BGCOLOR;
+ const fgColor = props.fgColor && DEFAULT_FGCOLOR;
+ return (
+
+ );
+ };
+ },
+});
diff --git a/components/qrcode/__tests__/__snapshots__/demo.test.js.snap b/components/qrcode/__tests__/__snapshots__/demo.test.js.snap
index 6f5c081d6..e05657599 100644
--- a/components/qrcode/__tests__/__snapshots__/demo.test.js.snap
+++ b/components/qrcode/__tests__/__snapshots__/demo.test.js.snap
@@ -39,6 +39,29 @@ exports[`renders ./components/qrcode/demo/customSize.vue correctly 1`] = `
`;
+exports[`renders ./components/qrcode/demo/customType.vue correctly 1`] = `
+
+`;
+
exports[`renders ./components/qrcode/demo/download.vue correctly 1`] = `
diff --git a/components/qrcode/demo/base.vue b/components/qrcode/demo/base.vue
index 39bf6f438..6aa48c319 100644
--- a/components/qrcode/demo/base.vue
+++ b/components/qrcode/demo/base.vue
@@ -15,5 +15,14 @@ Basic Usage.
-
+
+
+
+
+
+
diff --git a/components/qrcode/demo/customColor.vue b/components/qrcode/demo/customColor.vue
index 00ba76498..8ce1bec3b 100644
--- a/components/qrcode/demo/customColor.vue
+++ b/components/qrcode/demo/customColor.vue
@@ -16,7 +16,18 @@ Custom Color.
-
-
+
+
+
+
diff --git a/components/qrcode/demo/customSize.vue b/components/qrcode/demo/customSize.vue
index bc3ddc1be..caf504b07 100644
--- a/components/qrcode/demo/customSize.vue
+++ b/components/qrcode/demo/customSize.vue
@@ -31,7 +31,7 @@ Custom Size.
:size="size"
:icon-size="size / 4"
error-level="H"
- value="https://www.antv.com"
+ value="https://www.antdv.com"
icon="https://www.antdv.com/assets/logo.1ef800a8.svg"
/>
diff --git a/components/qrcode/demo/customType.vue b/components/qrcode/demo/customType.vue
new file mode 100644
index 000000000..13fb7a0ac
--- /dev/null
+++ b/components/qrcode/demo/customType.vue
@@ -0,0 +1,22 @@
+
+---
+order: 4
+title:
+ zh-CN: 自定义渲染类型
+ en-US: Custom Render Type
+---
+
+## zh-CN
+
+通过设置 `type` 自定义渲染结果,提供 `canvas` 和 `svg` 两个选项。
+
+## en-US
+Customize the rendering results by `type`, provide options `canvas` and `svg`.
+
+
+
+
+
+
+
+
diff --git a/components/qrcode/demo/download.vue b/components/qrcode/demo/download.vue
index bb432b3ac..b82bfd8b8 100644
--- a/components/qrcode/demo/download.vue
+++ b/components/qrcode/demo/download.vue
@@ -15,7 +15,7 @@ A way to download QRCode.
-
+
Downlaod
diff --git a/components/qrcode/demo/icon.vue b/components/qrcode/demo/icon.vue
index 76451b54b..ca53db5f5 100644
--- a/components/qrcode/demo/icon.vue
+++ b/components/qrcode/demo/icon.vue
@@ -17,7 +17,7 @@ QRCode with Icon.
diff --git a/components/qrcode/demo/index.vue b/components/qrcode/demo/index.vue
index 41d7536ac..11f7d365c 100644
--- a/components/qrcode/demo/index.vue
+++ b/components/qrcode/demo/index.vue
@@ -3,6 +3,7 @@
+
@@ -23,9 +24,20 @@ import CustomColor from './customColor.vue';
import Download from './download.vue';
import ErrorLevel from './errorLevel.vue';
import Popover from './popover.vue';
+import CustomType from './customType.vue';
export default defineComponent({
- components: { Base, Icon, Status, CustomSize, CustomColor, Download, ErrorLevel, Popover },
+ components: {
+ Base,
+ Icon,
+ Status,
+ CustomSize,
+ CustomColor,
+ Download,
+ ErrorLevel,
+ Popover,
+ CustomType,
+ },
category: 'Components',
subtitle: '二维码',
type: 'Data Display',
diff --git a/components/qrcode/demo/popover.vue b/components/qrcode/demo/popover.vue
index 2f778e317..7a2cbe160 100644
--- a/components/qrcode/demo/popover.vue
+++ b/components/qrcode/demo/popover.vue
@@ -15,9 +15,9 @@ With Popover.
-
+
-
+
diff --git a/components/qrcode/demo/status.vue b/components/qrcode/demo/status.vue
index 058963d93..90d347202 100644
--- a/components/qrcode/demo/status.vue
+++ b/components/qrcode/demo/status.vue
@@ -16,11 +16,11 @@ The status can be controlled by the value `status`.
-
-
+
+ console.log('refresh')"
+ />
-
-
diff --git a/components/qrcode/index.en-US.md b/components/qrcode/index.en-US.md
index b631f509b..1545d4c1b 100644
--- a/components/qrcode/index.en-US.md
+++ b/components/qrcode/index.en-US.md
@@ -15,10 +15,12 @@ Used when the link needs to be converted into a QR Code.
| Property | Description | Type | Default |
| --- | --- | --- | --- |
| value | scanned link | string | - |
+| type | render type | `'canvas'` \| `'svg'` | `canvas` |
| icon | include image url (only image link are supported) | string | - |
| size | QRCode size | number | 128 |
| iconSize | include image size | number | 32 |
| color | QRCode Color | string | `#000` |
+| bgColor | QRCode Background Color | string | `transparent` |
| bordered | Whether has border style | boolean | `true` |
| errorLevel | Error Code Level | `'L'` \| `'M'` \| `'Q'` \| `'H'` | `'M'` |
| status | QRCode status | `active` \| `expired` \| `loading ` | `active` |
diff --git a/components/qrcode/index.tsx b/components/qrcode/index.tsx
index 16a14aacc..7a08d4bdb 100644
--- a/components/qrcode/index.tsx
+++ b/components/qrcode/index.tsx
@@ -8,7 +8,7 @@ import Spin from '../spin';
import Button from '../button';
import { ReloadOutlined } from '@ant-design/icons-vue';
import { useToken } from '../theme/internal';
-import { QRCodeCanvas } from './QRCodeCanvas';
+import { QRCodeCanvas, QRCodeSVG } from './QRCode';
import warning from '../_util/warning';
import { qrcodeProps } from './interface';
@@ -42,7 +42,8 @@ const QRCode = defineComponent({
icon = '',
size = 160,
iconSize = 40,
- color = '#000',
+ color = token.value.colorText,
+ bgColor = 'transparent',
errorLevel = 'M',
} = props;
const imageSettings: QRCodeProps['imageSettings'] = {
@@ -57,7 +58,7 @@ const QRCode = defineComponent({
value,
size: size - (token.value.paddingSM + token.value.lineWidth) * 2,
level: errorLevel,
- bgColor: 'transparent',
+ bgColor,
fgColor: color,
imageSettings: icon ? imageSettings : undefined,
};
@@ -69,13 +70,17 @@ const QRCode = defineComponent({
{...attrs}
style={[
attrs.style as CSSProperties,
- { width: props.size + 'px', height: props.size + 'px' },
+ {
+ width: `${props.size}px`,
+ height: `${props.size}px`,
+ backgroundColor: qrCodeProps.value.bgColor,
+ },
]}
class={[
hashId.value,
pre,
{
- [`${prefixCls}-borderless`]: !props.bordered,
+ [`${pre}-borderless`]: !props.bordered,
},
]}
>
@@ -96,7 +101,11 @@ const QRCode = defineComponent({
)}
)}
-
+ {props.type === 'canvas' ? (
+
+ ) : (
+
+ )}
,
);
};
diff --git a/components/qrcode/index.zh-CN.md b/components/qrcode/index.zh-CN.md
index 53d99a8d1..8d266d637 100644
--- a/components/qrcode/index.zh-CN.md
+++ b/components/qrcode/index.zh-CN.md
@@ -16,10 +16,12 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*M4PBTZ_n9OgAAA
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| value | 扫描后的地址 | string | - |
+| type | 渲染类型 | `'canvas'` \| `'svg'` | `canvas` |
| icon | 二维码中图片的地址(目前只支持图片地址) | string | - |
| size | 二维码大小 | number | 160 |
| iconSize | 二维码中图片的大小 | number | 40 |
| color | 二维码颜色 | string | `#000` |
+| bgColor | 二维码背景颜色 | string | `transparent` |
| bordered | 是否有边框 | boolean | `true` |
| errorLevel | 二维码纠错等级 | `'L'` \| `'M'` \| `'Q'` \| `'H'` | `'M'` |
| status | 二维码状态 | `active` \| `expired` \| `loading ` | `active` |
diff --git a/components/qrcode/interface.ts b/components/qrcode/interface.ts
index 01b6b996a..3875256bb 100644
--- a/components/qrcode/interface.ts
+++ b/components/qrcode/interface.ts
@@ -12,7 +12,9 @@ export const qrProps = () => {
return {
size: { type: Number, default: 160 },
value: { type: String, required: true },
+ type: stringType<'canvas' | 'svg'>('canvas'),
color: String,
+ bgColor: String,
includeMargin: Boolean,
imageSettings: objectType(),
};