diff --git a/src/dialog/__test__/__snapshots__/demo.test.jsx.snap b/src/dialog/__test__/__snapshots__/demo.test.jsx.snap
index 298d84ea2..858168621 100644
--- a/src/dialog/__test__/__snapshots__/demo.test.jsx.snap
+++ b/src/dialog/__test__/__snapshots__/demo.test.jsx.snap
@@ -38,11 +38,10 @@ exports[`Dialog > Dialog confirmVue demo works fine 1`] = `
-
-
-
+
+
@@ -61,15 +60,11 @@ exports[`Dialog > Dialog confirmVue demo works fine 1`] = `
-
-
+
@@ -142,15 +134,14 @@ exports[`Dialog > Dialog confirmVue demo works fine 1`] = `
-
-
-
+
+
-
+
@@ -161,15 +152,11 @@ exports[`Dialog > Dialog confirmVue demo works fine 1`] = `
-
-
+
@@ -248,11 +232,10 @@ exports[`Dialog > Dialog feedbackVue demo works fine 1`] = `
-
-
-
+
+
@@ -271,18 +254,12 @@ exports[`Dialog > Dialog feedbackVue demo works fine 1`] = `
-
-
+
@@ -339,15 +315,14 @@ exports[`Dialog > Dialog feedbackVue demo works fine 1`] = `
-
-
-
+
+
-
+
@@ -358,18 +333,12 @@ exports[`Dialog > Dialog feedbackVue demo works fine 1`] = `
-
-
+
@@ -426,11 +394,10 @@ exports[`Dialog > Dialog feedbackVue demo works fine 1`] = `
-
-
-
+
+
@@ -451,18 +418,12 @@ exports[`Dialog > Dialog feedbackVue demo works fine 1`] = `
-
-
+
@@ -527,7 +487,7 @@ exports[`Dialog > Dialog imageDialogVue demo works fine 1`] = `
Dialog imageDialogVue demo works fine 1`] = `
-
+
@@ -594,15 +554,11 @@ exports[`Dialog > Dialog imageDialogVue demo works fine 1`] = `
-
-
+
@@ -678,11 +631,10 @@ exports[`Dialog > Dialog imageDialogVue demo works fine 1`] = `
-
-
-
+
+
@@ -750,10 +702,7 @@ exports[`Dialog > Dialog imageDialogVue demo works fine 1`] = `
@@ -834,11 +780,10 @@ exports[`Dialog > Dialog inputVue demo works fine 1`] = `
-
-
-
+
+
@@ -893,15 +838,11 @@ exports[`Dialog > Dialog inputVue demo works fine 1`] = `
-
-
+
@@ -977,11 +915,10 @@ exports[`Dialog > Dialog inputVue demo works fine 1`] = `
-
-
-
+
+
@@ -1041,15 +978,11 @@ exports[`Dialog > Dialog inputVue demo works fine 1`] = `
-
-
+
@@ -1159,11 +1089,10 @@ exports[`Dialog > Dialog mobileVue demo works fine 1`] = `
-
-
-
+
+
@@ -1182,18 +1111,12 @@ exports[`Dialog > Dialog mobileVue demo works fine 1`] = `
-
-
+
@@ -1250,15 +1172,14 @@ exports[`Dialog > Dialog mobileVue demo works fine 1`] = `
-
-
-
+
+
-
+
@@ -1269,18 +1190,12 @@ exports[`Dialog > Dialog mobileVue demo works fine 1`] = `
-
-
+
@@ -1337,11 +1251,10 @@ exports[`Dialog > Dialog mobileVue demo works fine 1`] = `
-
-
-
+
+
@@ -1362,18 +1275,12 @@ exports[`Dialog > Dialog mobileVue demo works fine 1`] = `
-
-
+
@@ -1449,11 +1355,10 @@ exports[`Dialog > Dialog mobileVue demo works fine 1`] = `
-
-
-
+
+
@@ -1472,15 +1377,11 @@ exports[`Dialog > Dialog mobileVue demo works fine 1`] = `
-
-
+
@@ -1553,15 +1451,14 @@ exports[`Dialog > Dialog mobileVue demo works fine 1`] = `
-
-
-
+
+
-
+
@@ -1572,15 +1469,11 @@ exports[`Dialog > Dialog mobileVue demo works fine 1`] = `
-
-
+
@@ -1674,11 +1564,10 @@ exports[`Dialog > Dialog mobileVue demo works fine 1`] = `
-
-
-
+
+
@@ -1733,15 +1622,11 @@ exports[`Dialog > Dialog mobileVue demo works fine 1`] = `
-
-
+
@@ -1817,11 +1699,10 @@ exports[`Dialog > Dialog mobileVue demo works fine 1`] = `
-
-
-
+
+
@@ -1881,15 +1762,11 @@ exports[`Dialog > Dialog mobileVue demo works fine 1`] = `
-
-
+
@@ -1983,7 +1857,7 @@ exports[`Dialog > Dialog mobileVue demo works fine 1`] = `
Dialog mobileVue demo works fine 1`] = `
-
+
@@ -2050,15 +1924,11 @@ exports[`Dialog > Dialog mobileVue demo works fine 1`] = `
-
-
+
@@ -2134,11 +2001,10 @@ exports[`Dialog > Dialog mobileVue demo works fine 1`] = `
-
-
-
+
+
@@ -2206,10 +2072,7 @@ exports[`Dialog > Dialog mobileVue demo works fine 1`] = `
@@ -2305,11 +2165,10 @@ exports[`Dialog > Dialog mobileVue demo works fine 1`] = `
-
-
-
+
+
@@ -2328,15 +2187,11 @@ exports[`Dialog > Dialog mobileVue demo works fine 1`] = `
-
-
+
@@ -2409,11 +2261,10 @@ exports[`Dialog > Dialog mobileVue demo works fine 1`] = `
-
-
-
+
+
@@ -2432,15 +2283,11 @@ exports[`Dialog > Dialog mobileVue demo works fine 1`] = `
-
-
+
@@ -2513,11 +2357,10 @@ exports[`Dialog > Dialog mobileVue demo works fine 1`] = `
-
-
-
+
+
@@ -2536,15 +2379,11 @@ exports[`Dialog > Dialog mobileVue demo works fine 1`] = `
-
-
+
-
-
-
-
+
-
-
-
@@ -2617,11 +2453,10 @@ exports[`Dialog > Dialog mobileVue demo works fine 1`] = `
-
-
-
+
+
@@ -2640,13 +2475,11 @@ exports[`Dialog > Dialog mobileVue demo works fine 1`] = `
-
-
+
-
-
-
-
-
-
-
-
+
+
@@ -2738,10 +2566,9 @@ exports[`Dialog > Dialog mobileVue demo works fine 1`] = `
-
-
+
@@ -2776,15 +2603,11 @@ exports[`Dialog > Dialog mobileVue demo works fine 1`] = `
-
-
+
-
-
-
-
+
-
-
-
@@ -2904,11 +2724,10 @@ exports[`Dialog > Dialog multiStateVue demo works fine 1`] = `
-
-
-
+
+
@@ -2927,15 +2746,11 @@ exports[`Dialog > Dialog multiStateVue demo works fine 1`] = `
-
-
+
@@ -3008,11 +2820,10 @@ exports[`Dialog > Dialog multiStateVue demo works fine 1`] = `
-
-
-
+
+
@@ -3031,15 +2842,11 @@ exports[`Dialog > Dialog multiStateVue demo works fine 1`] = `
-
-
+
@@ -3112,11 +2916,10 @@ exports[`Dialog > Dialog multiStateVue demo works fine 1`] = `
-
-
-
+
+
@@ -3135,15 +2938,11 @@ exports[`Dialog > Dialog multiStateVue demo works fine 1`] = `
-
-
+
-
-
-
-
+
-
-
-
@@ -3216,11 +3012,10 @@ exports[`Dialog > Dialog multiStateVue demo works fine 1`] = `
-
-
-
+
+
@@ -3239,13 +3034,11 @@ exports[`Dialog > Dialog multiStateVue demo works fine 1`] = `
-
-
+
-
-
-
-
-
-
-
-
+
+
@@ -3337,10 +3125,9 @@ exports[`Dialog > Dialog multiStateVue demo works fine 1`] = `
-
-
+
@@ -3375,15 +3162,11 @@ exports[`Dialog > Dialog multiStateVue demo works fine 1`] = `
-
-
+
-
-
-
-
+
-
-
-
diff --git a/src/dialog/__test__/index.test.jsx b/src/dialog/__test__/index.test.jsx
index 862aba720..24c3ab9cf 100644
--- a/src/dialog/__test__/index.test.jsx
+++ b/src/dialog/__test__/index.test.jsx
@@ -1,6 +1,6 @@
import { config, mount } from '@vue/test-utils';
import { describe, it, expect, vi } from 'vitest';
-import Dialog from '../dialog.vue';
+import Dialog from '../dialog';
import Button from '../../button/button';
import { CloseIcon } from 'tdesign-icons-vue-next';
diff --git a/src/dialog/dialog.tsx b/src/dialog/dialog.tsx
new file mode 100644
index 000000000..a8dfad875
--- /dev/null
+++ b/src/dialog/dialog.tsx
@@ -0,0 +1,169 @@
+import { CloseIcon } from 'tdesign-icons-vue-next';
+import { computed, defineComponent } from 'vue';
+import get from 'lodash/get';
+import isString from 'lodash/isString';
+
+import TButton, { ButtonProps } from '../button';
+import TPopup from '../popup';
+import config from '../config';
+import props from './props';
+import { useTNodeJSX, useContent } from '../hooks/tnode';
+
+const { prefix } = config;
+const name = `${prefix}-dialog`;
+
+export default defineComponent({
+ name,
+ components: { TPopup, TButton, CloseIcon },
+ props,
+ emits: ['update:visible', 'confirm', 'overlay-click', 'cancel', 'close', 'closed'],
+ setup(props, context) {
+ const renderTNodeJSX = useTNodeJSX();
+ const renderContent = useContent();
+ const isTextStyleBtn = computed(() =>
+ [props?.confirmBtn, props?.cancelBtn, ...(props?.actions || [])].some((item) => get(item, 'variant') === 'text'),
+ );
+
+ const footerClass = computed(() => [
+ `${name}__footer`,
+ {
+ [`${name}__footer--column`]: props.buttonLayout === 'vertical',
+ [`${name}__footer--full`]: isTextStyleBtn.value && get(props.actions, 'length', 0) === 0,
+ },
+ ]);
+
+ const buttonClass = computed(() => [
+ `${name}__button`,
+ {
+ [`${name}__button--${props.buttonLayout}`]: !isTextStyleBtn.value,
+ [`${name}__button--text`]: isTextStyleBtn.value,
+ },
+ ]);
+
+ const rootStyles = computed(() => ({
+ width: isString(props.width) ? props.width : `${props.width}px`,
+ }));
+
+ const handleClose = (args: { e: MouseEvent }) => {
+ const { e } = args;
+ context.emit('update:visible', false);
+ context.emit('close', { e, trigger: 'close-btn' });
+ };
+
+ const handleClosed = () => {
+ context.emit('closed');
+ };
+
+ const handleConfirm = (e: MouseEvent) => {
+ context.emit('update:visible', false);
+ context.emit?.('confirm', { e });
+ };
+
+ const handleCancel = (e: MouseEvent) => {
+ context.emit('update:visible', false);
+ context.emit('close', { e, trigger: 'cancel' });
+ context.emit('cancel', { e });
+ };
+
+ const handleOverlayClick = (args: { e: MouseEvent }) => {
+ const { e } = args;
+ if (!props.closeOnOverlayClick) {
+ return;
+ }
+ context.emit('update:visible', false);
+ context.emit('close', { e, trigger: 'overlay' });
+ context.emit('overlay-click', { e });
+ };
+
+ const calcBtn = (btn: any) => (isString(btn) ? { content: btn } : btn);
+ const confirmBtnProps = computed(() => ({
+ theme: 'primary',
+ ...calcBtn(props.confirmBtn),
+ }));
+ const cancelBtnProps = computed(() => ({
+ theme: isTextStyleBtn.value ? 'default' : 'light',
+ ...calcBtn(props.cancelBtn),
+ }));
+ const actionsBtnProps = computed(() => props.actions?.map((item) => calcBtn(item)));
+
+ return () => {
+ const { visible, showOverlay, overlayProps, preventScrollThrough, destroyOnClose, zIndex, closeBtn, actions } =
+ props;
+ const renderTitleNode = () => {
+ const titleNode = renderTNodeJSX('title');
+ if (!titleNode) {
+ return null;
+ }
+
+ return ;
+ };
+ const renderContentNode = () => {
+ const contentNode = renderContent('default', 'content');
+ if (!contentNode) {
+ return null;
+ }
+ return (
+
+ );
+ };
+ const renderActionsNode = () => {
+ const actionsNode = renderTNodeJSX('actions');
+ if (actionsNode && actionsBtnProps.value) {
+ return actionsBtnProps.value.map((item, index) => (
+
+ ));
+ }
+ return null;
+ };
+ const renderCancelBtnNode = () => {
+ const cancelBtnNode = renderTNodeJSX('cancelBtn');
+ if (!actions && cancelBtnNode) {
+ return ;
+ }
+ return null;
+ };
+
+ const renderConfirmBntNode = () => {
+ const confirmBtnNode = renderTNodeJSX('confirmBtn');
+ if (!actions && confirmBtnNode) {
+ return ;
+ }
+ return null;
+ };
+ return (
+
+
+ {renderTNodeJSX('top')}
+ {closeBtn && (
+
+
+
+ )}
+
+ {renderTitleNode()}
+ {renderContentNode()}
+
+ {renderTNodeJSX('middle')}
+
+
+
+ );
+ };
+ },
+});
diff --git a/src/dialog/dialog.vue b/src/dialog/dialog.vue
deleted file mode 100644
index db85b56c6..000000000
--- a/src/dialog/dialog.vue
+++ /dev/null
@@ -1,164 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/dialog/index.ts b/src/dialog/index.ts
index 3230a30ef..cea2090c1 100644
--- a/src/dialog/index.ts
+++ b/src/dialog/index.ts
@@ -1,6 +1,6 @@
import { createApp, h, App, ref, nextTick, reactive } from 'vue';
-import Dialog from './dialog.vue';
+import Dialog from './dialog';
import { WithInstallType, isBrowser } from '../shared';
import { DialogCloseContext, TdDialogProps, DialogInstance } from './type';