kn-cli 1.0.134 → 1.0.136

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/build/package.json +2 -1
  2. package/build/vite.config.js +1 -0
  3. package/build/webpack.config.js +16 -2
  4. package/package.json +1 -1
  5. package/src/build.js +1 -1
  6. package/templates/template_admin_antd5/package.json +3 -3
  7. package/templates/template_admin_antd5/public/src/_antd.less +4 -4
  8. package/templates/template_admin_antd5/public/src/_reset.module.less +1 -1
  9. package/templates/template_admin_antd5/public/src/_variable.module.less +5 -5
  10. package/templates/template_admin_antd5/public/src/assets/images/expand-hover.png +0 -0
  11. package/templates/template_admin_antd5/public/src/assets/images/expand.png +0 -0
  12. package/templates/template_admin_antd5/public/src/assets/images/icon-add.png +0 -0
  13. package/templates/template_admin_antd5/public/src/assets/images/icon-full-size.png +0 -0
  14. package/templates/template_admin_antd5/public/src/assets/images/icon-resize.png +0 -0
  15. package/templates/template_admin_antd5/public/src/assets/images/icon-user.png +0 -0
  16. package/templates/template_admin_antd5/public/src/assets/images/login/bg.png +0 -0
  17. package/templates/template_admin_antd5/public/src/assets/images/login/logo.png +0 -0
  18. package/templates/template_admin_antd5/public/src/assets/images/nav/slogan.png +0 -0
  19. package/templates/template_admin_antd5/public/src/assets/images/unexpand-hover.png +0 -0
  20. package/templates/template_admin_antd5/public/src/assets/images/unexpand.png +0 -0
  21. package/templates/template_admin_antd5/public/src/components/antd/antProvider.jsx +16 -4
  22. package/templates/template_admin_antd5/public/src/components/antd/drawer/README.md +336 -0
  23. package/templates/template_admin_antd5/public/src/components/antd/drawer/index.jsx +264 -0
  24. package/templates/template_admin_antd5/public/src/components/antd/index.jsx +19 -7
  25. package/templates/template_admin_antd5/public/src/components/antd/index.module.less +26 -0
  26. package/templates/template_admin_antd5/public/src/components/antd/modal/README.md +324 -0
  27. package/templates/template_admin_antd5/public/src/components/antd/modal/index.jsx +185 -0
  28. package/templates/template_admin_antd5/public/src/components/antd/select/index.jsx +1 -1
  29. package/templates/template_admin_antd5/public/src/components/antd/spin/index.jsx +92 -0
  30. package/templates/template_admin_antd5/public/src/components/antd/spin/index.module.less +58 -0
  31. package/templates/template_admin_antd5/public/src/components/antd/theme.js +19 -8
  32. package/templates/template_admin_antd5/public/src/components/antd/tooltip/detail/index.jsx +19 -56
  33. package/templates/template_admin_antd5/public/src/components/debug/index.jsx +7 -2
  34. package/templates/template_admin_antd5/public/src/components/error/index.jsx +0 -5
  35. package/templates/template_admin_antd5/public/src/components/icon/expand/index.jsx +17 -0
  36. package/templates/template_admin_antd5/public/src/components/icon/expand/index.module.less +22 -0
  37. package/templates/template_admin_antd5/public/src/components/icon/fullSize/index.jsx +13 -0
  38. package/templates/template_admin_antd5/public/src/components/icon/fullSize/index.module.less +28 -0
  39. package/templates/template_admin_antd5/public/src/components/icon/index.jsx +7 -1
  40. package/templates/template_admin_antd5/public/src/components/image/preview.jsx +7 -10
  41. package/templates/template_admin_antd5/public/src/components/layout/basic/index.module.less +1 -1
  42. package/templates/template_admin_antd5/public/src/components/leftMenu/index.jsx +1 -2
  43. package/templates/template_admin_antd5/public/src/components/link/index.module.less +2 -2
  44. package/templates/template_admin_antd5/public/src/components/menuIcon/index.module.less +3 -3
  45. package/templates/template_admin_antd5/public/src/components/popup/index.jsx +91 -50
  46. package/templates/template_admin_antd5/public/src/components/popup/index.module.less +22 -15
  47. package/templates/template_admin_antd5/public/src/components/react/index.jsx +23 -9
  48. package/templates/template_admin_antd5/public/src/components/resizeBox/index.jsx +3 -3
  49. package/templates/template_admin_antd5/public/src/components/select/defaultServicesSelect/index.jsx +151 -40
  50. package/templates/template_admin_antd5/public/src/components/select/dictSelect/index.jsx +19 -3
  51. package/templates/template_admin_antd5/public/src/components/select/useSelectList.jsx +65 -65
  52. package/templates/template_admin_antd5/public/src/components/table/index.jsx +48 -327
  53. package/templates/template_admin_antd5/public/src/components/table/index.module.less +0 -110
  54. package/templates/template_admin_antd5/public/src/components/table/table/index.jsx +242 -0
  55. package/templates/template_admin_antd5/public/src/components/table/table/index.module.less +85 -0
  56. package/templates/template_admin_antd5/public/src/components/table/withPage.jsx +53 -0
  57. package/templates/template_admin_antd5/public/src/components/topMenu/index.jsx +46 -11
  58. package/templates/template_admin_antd5/public/src/components/topMenu/index.module.less +10 -7
  59. package/templates/template_admin_antd5/public/src/components/topMenu/popmenu/index.jsx +89 -0
  60. package/templates/template_admin_antd5/public/src/components/topMenu/popmenu/index.module.less +76 -0
  61. package/templates/template_admin_antd5/public/src/components/topMenu/topBar/index.module.less +4 -3
  62. package/templates/template_admin_antd5/public/src/components/video/index.jsx +1 -1
  63. package/templates/template_admin_antd5/public/src/components/video/preview.jsx +7 -10
  64. package/templates/template_admin_antd5/public/src/config.js +3 -0
  65. package/templates/template_admin_antd5/public/src/hooks/useLoading.jsx +2 -2
  66. package/templates/template_admin_antd5/public/src/index.jsx +7 -4
  67. package/templates/template_admin_antd5/public/src/mock/demo.js +3 -3
  68. package/templates/template_admin_antd5/public/src/pages/antdComponents/button/index.jsx +22 -0
  69. package/templates/template_admin_antd5/public/src/pages/antdComponents/check/index.jsx +12 -0
  70. package/templates/template_admin_antd5/public/src/pages/antdComponents/index.jsx +57 -114
  71. package/templates/template_admin_antd5/public/src/pages/antdComponents/index.module.less +5 -0
  72. package/templates/template_admin_antd5/public/src/pages/antdComponents/input/index.jsx +14 -0
  73. package/templates/template_admin_antd5/public/src/pages/antdComponents/loading/index.jsx +31 -0
  74. package/templates/template_admin_antd5/public/src/pages/antdComponents/message/index.jsx +102 -0
  75. package/templates/template_admin_antd5/public/src/pages/antdComponents/message/index.module.less +17 -0
  76. package/templates/template_admin_antd5/public/src/pages/antdComponents/radio/index.jsx +26 -0
  77. package/templates/template_admin_antd5/public/src/pages/antdComponents/select/index.jsx +13 -0
  78. package/templates/template_admin_antd5/public/src/pages/antdComponents/switch/index.jsx +12 -0
  79. package/templates/template_admin_antd5/public/src/pages/antdComponents/tableWithPage/index.jsx +70 -0
  80. package/templates/template_admin_antd5/public/src/pages/antdComponents/text/index.jsx +21 -0
  81. package/templates/template_admin_antd5/public/src/pages/auth/user/dialog/index.jsx +48 -75
  82. package/templates/template_admin_antd5/public/src/pages/auth/user/index.jsx +17 -23
  83. package/templates/template_admin_antd5/public/src/pages/lazyLoad/index.jsx +11 -0
  84. package/templates/template_admin_antd5/public/src/pages/login/index.jsx +8 -3
  85. package/templates/template_admin_antd5/public/src/pages/login/index.module.less +18 -10
  86. package/templates/template_admin_antd5/public/src/provider/menu.jsx +5 -0
  87. package/templates/template_admin_antd5/public/src/route.jsx +14 -9
  88. package/templates/template_admin_antd5/public/src/services/demo.js +38 -2
  89. package/templates/template_admin_antd5/public/src/services/interceptor/index.js +30 -3
  90. package/templates/template_admin_antd5/public/src/types/global.d.js +306 -0
  91. package/templates/template_admin_antd5/public/src/utils/format.js +1 -1
  92. package/templates/template_admin_antd5/public/src/utils/index.js +3 -3
  93. package/templates/template_admin_antd5/public/src/utils/moment.js +15 -0
  94. package/templates/template_admin_antd5/public/static/version.json +3 -0
  95. package/templates/template_admin_antd5/public/src/components/_table/column.jsx +0 -47
  96. package/templates/template_admin_antd5/public/src/components/_table/column.module.less +0 -12
  97. package/templates/template_admin_antd5/public/src/components/_table/index.jsx +0 -71
  98. package/templates/template_admin_antd5/public/src/components/_table/index.module.less +0 -15
  99. package/templates/template_admin_antd5/public/src/components/badge/index.jsx +0 -47
  100. package/templates/template_admin_antd5/public/src/components/badge/index.module.less +0 -44
  101. package/templates/template_admin_antd5/public/src/components/page/pageLoading/index.jsx +0 -51
  102. package/templates/template_admin_antd5/public/src/components/page/pageLoading/index.module.less +0 -29
  103. package/templates/template_admin_antd5/public/src/components/table/aliTable/index.jsx +0 -250
  104. package/templates/template_admin_antd5/public/src/components/table/aliTable/index.module.less +0 -105
  105. package/templates/template_admin_antd5/public/src/components/toast/index.jsx +0 -79
  106. package/templates/template_admin_antd5/public/src/components/toast/index.module.less +0 -43
  107. package/templates/template_admin_antd5/public/src/provider/loading.jsx +0 -47
  108. package/templates/template_admin_antd5/public/src/provider/menu.module.less +0 -35
  109. package/templates/template_admin_antd5/public/src/type.js +0 -67
  110. package/templates/template_admin_antd5/renamejstojsx.js +0 -45
  111. package/templates/template_admin_antd5/renameless.js +0 -53
  112. /package/templates/template_admin_antd5/public/src/components/{button → antd/button}/index.jsx +0 -0
  113. /package/templates/template_admin_antd5/public/src/components/resizeBox/{index.module.css → index.module.less} +0 -0
@@ -45,7 +45,8 @@
45
45
  "webpack-cli": "~3.3.11",
46
46
  "webpack-dev-server": "~3.10.3",
47
47
  "@pmmmwh/react-refresh-webpack-plugin": "~0.4.3",
48
- "react-refresh": "~0.9.0"
48
+ "react-refresh": "~0.9.0",
49
+ "hard-source-webpack-plugin": "~0.13.1"
49
50
  },
50
51
  "overrides": {
51
52
  "@jridgewell/gen-mapping": "0.3.5"
@@ -76,6 +76,7 @@ warn(`build_env:${process.env.build_env}`);
76
76
  warn(`mock:${process.env.mock}`);
77
77
  warn(`noSkipNpmInstall:${process.env.noSkipNpmInstall}`);
78
78
  warn(`build_log_level:${process.env.build_log_level}`);
79
+ warn(`host:${host}`);
79
80
  warn(`=====================env end=========================`);
80
81
 
81
82
  export default defineConfig({
@@ -11,6 +11,7 @@ const TerserPlugin = require('terser-webpack-plugin');
11
11
  const CopyPlugin = require('copy-webpack-plugin');
12
12
  const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
13
13
  const NowDateTime = Date.now();
14
+ var HardSourceWebpackPlugin = require('hard-source-webpack-plugin');
14
15
 
15
16
  //////////// CONFIG ENV ///////////////
16
17
  const API_CONFIG = require('./webpack.api.js');
@@ -132,7 +133,8 @@ if(!hashMode){
132
133
 
133
134
  /////////////// RULES ////////////////
134
135
  const BABEL_PLUGINS=[
135
- ['@babel/plugin-transform-runtime', { corejs: 3 }],
136
+ ['@babel/plugin-transform-runtime', { corejs: 3}],
137
+ '@babel/plugin-transform-class-properties'
136
138
  ]
137
139
  const BABEL_PLUGINS_777=[
138
140
  ['@babel/plugin-transform-runtime', { corejs: 3 }],
@@ -148,6 +150,7 @@ const LOADER_JS=[
148
150
  {
149
151
  loader: 'babel-loader',
150
152
  options: {
153
+ // cacheDirectory: true, // 👈 必须开启!默认是 false
151
154
  presets: [
152
155
  '@babel/preset-react',
153
156
  [
@@ -396,6 +399,7 @@ if(devMode){
396
399
  overlay:false//关闭全局的错误提示
397
400
  }) ) // 添加 React Refresh 插件
398
401
  }
402
+
399
403
  plugins.push(new webpack.SourceMapDevToolPlugin({
400
404
  filename: 'sourcemap/[file].map',
401
405
  // filename: false, // 避免生成额外的 .map 文件,提高构建速度
@@ -476,6 +480,16 @@ if(cssSplitMode){
476
480
  )
477
481
  }
478
482
 
483
+ if(CLI_CONFIG?.hardSourceWebpackPlugin){
484
+ const cacheDir = path.resolve(dirname, '.webpack_cache/[confighash]')
485
+ warn(`hardSourceWebpackPlugin cacheDir:${cacheDir}`);
486
+ plugins.push(
487
+ new HardSourceWebpackPlugin({
488
+ cacheDirectory: cacheDir,
489
+ })
490
+ )
491
+ }
492
+
479
493
  //////////////// PLUGINS-END //////////////////
480
494
 
481
495
  ///////////// SPA-RENDER ///////////////
@@ -543,7 +557,7 @@ const config={
543
557
  optimization: optimization,
544
558
  plugins: plugins,
545
559
  // watchOptions: {
546
- // aggregateTimeout: 5000, // 文件变化后延迟 300 毫秒再重新构建
560
+ // // aggregateTimeout: 5000, // 文件变化后延迟 300 毫秒再重新构建
547
561
  // ignored: /node_modules/ // 忽略 node_modules 目录
548
562
  // }
549
563
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kn-cli",
3
- "version": "1.0.134",
3
+ "version": "1.0.136",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/src/build.js CHANGED
@@ -54,7 +54,7 @@ module.exports= async (options={})=> {
54
54
  // 构建模板
55
55
  const tempWebpackDir = path.resolve(tempProjectDir,"_webpack");
56
56
  const tempWebpackPackagePath = path.resolve(tempWebpackDir,'package.json');
57
- const tempWebpackBabelPackagePath = path.resolve(tempWebpackDir,'babel.package.json');
57
+ const tempWebpackBabelPackagePath = path.resolve(tempWebpackDir,cliConfig?.babelConfigName??'babel.package.json');
58
58
 
59
59
  const tempVitePackagePath = path.resolve(tempWebpackDir,'vite.package.json');
60
60
  const tempWebpackConfigPath = path.resolve(tempWebpackDir,'webpack.config.js');
@@ -7,15 +7,15 @@
7
7
  },
8
8
  "license": "MIT",
9
9
  "dependencies": {
10
+ "@ant-design/icons": "~5.6.1",
10
11
  "ali-oss": "~6.20.0",
11
- "antd": "~5.22.0",
12
+ "antd": "~5.29.0",
12
13
  "axios": "~1.1.3",
14
+ "dayjs": "~1.11.20",
13
15
  "jszip": "~3.10.1",
14
16
  "kn-hooks": "~1.0.2",
15
- "moment": "~2.29.4",
16
17
  "react": "~18.3.0",
17
18
  "react-dom": "~18.3.0",
18
- "react18-json-view": "~0.2.9",
19
19
  "react-router": "~6.3.0",
20
20
  "react-router-dom": "~6.3.0",
21
21
  "unstated-next": "~1.1.0",
@@ -3,10 +3,10 @@
3
3
 
4
4
 
5
5
  // 这里可以重写antd的主题样式变量,参考 https://4x.ant.design/docs/react/customize-theme-cn
6
- @primary-color:#0974F2;
7
- @table-header-bg:#F5F8FF;
8
- @btn-border-radius-base:4px;
9
- @modal-border-radius:8px;
6
+ // @primary-color:#0974F2;
7
+ // @table-header-bg:#F5F8FF;
8
+ // @btn-border-radius-base:4px;
9
+ // @modal-border-radius:8px;
10
10
 
11
11
  :global{
12
12
  .ant-form-inline{
@@ -48,7 +48,7 @@
48
48
  letter-spacing: inherit;
49
49
  }
50
50
  a{
51
- color: var(--color-primary);
51
+ color: var(--theme-color-primary);
52
52
  }
53
53
 
54
54
 
@@ -21,11 +21,11 @@
21
21
 
22
22
  --font-Regular:14px;
23
23
 
24
-
25
- --color-primary-dark:#001529;
26
- --color-primary-light:#F5F8FF;
27
- --color-primary:#0974F2;
28
- --color-primary-hover:#1565c0;
24
+ // 不用此变量,使用theme配置的主题相关颜色
25
+ // --color-primary-dark:#001529;
26
+ // --color-primary-light:#F5F8FF;
27
+ // --color-primary:#0974F2;
28
+ // --color-primary-hover:#1565c0;
29
29
 
30
30
  --color-font-bold:#141414;
31
31
  --color-font-gray:#8C8C8C;
@@ -1,18 +1,30 @@
1
- import React from 'react';
1
+ import React, { useEffect } from 'react';
2
2
 
3
- import { ConfigProvider } from 'antd';
3
+ import { ConfigProvider, App } from 'antd';
4
4
  import zhCN from 'antd/es/locale/zh_CN';
5
5
  import {antd5TableTheme} from './theme';
6
+ import styles from './index.module.less';
7
+ styles;
6
8
 
7
9
  const Antd5Provider=props=>{
8
10
  const {children} = props;
11
+
12
+ // 将主题色注入到 CSS 变量中
13
+ useEffect(() => {
14
+ const root = document.documentElement;
15
+ root.style.setProperty('--theme-color-primary', antd5TableTheme.token.colorPrimary);
16
+ root.style.setProperty('--theme-color-primary-hover', antd5TableTheme.token.colorPrimaryHover);
17
+ }, []);
18
+
9
19
  return (
10
20
  <ConfigProvider
11
21
  locale={zhCN}
12
22
  theme={antd5TableTheme}
13
- // prefixCls="ant5"
23
+ prefixCls="ant5"
14
24
  >
15
- {children}
25
+ <App>
26
+ {children}
27
+ </App>
16
28
  </ConfigProvider>
17
29
  )
18
30
  };
@@ -0,0 +1,336 @@
1
+ # Drawer 组件使用指南
2
+
3
+ ## 概述
4
+
5
+ 提供了两种方式来创建 Drawer(侧边弹窗):
6
+
7
+ 1. **showDrawer** - 函数式调用(推荐)
8
+ 2. **useDrawerHelper** - Hook 方式(在组件内使用)
9
+
10
+ 两种方式都自动继承 antd 5 的主题配置。
11
+
12
+ ---
13
+
14
+ ## 方式 1:showDrawer(推荐)
15
+
16
+ ### 特点
17
+ - ✅ 可以在任何地方调用(不限于组件内)
18
+ - ✅ 自动继承主题配置
19
+ - ✅ 支持异步操作
20
+ - ✅ 自动管理 loading 状态
21
+ - ✅ 错误时不关闭 Drawer
22
+
23
+ ### 基础用法
24
+
25
+ ```jsx
26
+ import { showDrawer } from '@/components/drawer';
27
+
28
+ // 简单的确认对话框
29
+ const result = await showDrawer({
30
+ title: '确认操作',
31
+ content: <div>确定要执行这个操作吗?</div>,
32
+ });
33
+
34
+ if (result) {
35
+ console.log('用户点击了确定');
36
+ } else {
37
+ console.log('用户点击了取消');
38
+ }
39
+ ```
40
+
41
+ ### 带表单的 Drawer
42
+
43
+ ```jsx
44
+ import { showDrawer } from '@/components/drawer';
45
+ import { Form, Input, message } from 'antd';
46
+
47
+ const handleEdit = async (id) => {
48
+ let formRef = null;
49
+
50
+ const result = await showDrawer({
51
+ title: '编辑用户',
52
+ width: 600,
53
+ content: (
54
+ <Form ref={(ref) => (formRef = ref)} layout="vertical">
55
+ <Form.Item label="姓名" name="name" rules={[{ required: true, message: '请输入姓名' }]}>
56
+ <Input />
57
+ </Form.Item>
58
+ <Form.Item label="邮箱" name="email" rules={[{ type: 'email', message: '请输入有效邮箱' }]}>
59
+ <Input />
60
+ </Form.Item>
61
+ </Form>
62
+ ),
63
+ onOk: async () => {
64
+ // 验证表单
65
+ const values = await formRef.validateFields();
66
+
67
+ // 提交数据
68
+ const res = await saveData(values);
69
+
70
+ if (res.code === 0) {
71
+ message.success('保存成功');
72
+ return; // 成功后关闭
73
+ } else {
74
+ throw new Error('保存失败'); // 抛出错误阻止关闭
75
+ }
76
+ },
77
+ });
78
+
79
+ return result;
80
+ };
81
+ ```
82
+
83
+ ### 从右侧滑出(默认)
84
+
85
+ ```jsx
86
+ showDrawer({
87
+ title: '详情',
88
+ placement: 'right', // 默认值,可省略
89
+ content: <DetailContent />,
90
+ });
91
+ ```
92
+
93
+ ### 从左侧滑出
94
+
95
+ ```jsx
96
+ showDrawer({
97
+ title: '导航菜单',
98
+ placement: 'left',
99
+ content: <NavigationMenu />,
100
+ });
101
+ ```
102
+
103
+ ### 从顶部滑出
104
+
105
+ ```jsx
106
+ showDrawer({
107
+ title: '通知',
108
+ placement: 'top',
109
+ height: 300, // 设置高度
110
+ content: <NotificationList />,
111
+ drawerProps: {
112
+ height: 300,
113
+ },
114
+ });
115
+ ```
116
+
117
+ ### 从底部滑出
118
+
119
+ ```jsx
120
+ showDrawer({
121
+ title: '操作面板',
122
+ placement: 'bottom',
123
+ content: <ActionSheet />,
124
+ drawerProps: {
125
+ height: 400,
126
+ },
127
+ });
128
+ ```
129
+
130
+ ### 隐藏底部按钮
131
+
132
+ ```jsx
133
+ showDrawer({
134
+ title: '纯展示内容',
135
+ footer: false, // 隐藏底部按钮
136
+ content: <SomeContent />,
137
+ });
138
+ ```
139
+
140
+ ### 完整配置项
141
+
142
+ ```jsx
143
+ showDrawer({
144
+ title: '标题', // Drawer 标题
145
+ content: <YourComponent />, // Drawer 内容(JSX)
146
+ width: 600, // 宽度(默认 480,placement 为 top/bottom 时忽略)
147
+ placement: 'right', // 弹出方向:'left' | 'right' | 'top' | 'bottom'(默认 'right')
148
+ maskClosable: true, // 点击遮罩是否关闭(默认 true)
149
+ closable: true, // 是否显示关闭按钮(默认 true)
150
+ okText: '确定', // 确定按钮文字
151
+ cancelText: '取消', // 取消按钮文字
152
+ footer: true, // 是否显示底部按钮(默认 true,设为 false 隐藏)
153
+ onOk: async () => { // 确定回调(支持异步)
154
+ // 返回 Promise 可以控制关闭
155
+ // 抛出错误会阻止关闭
156
+ },
157
+ onCancel: () => { // 取消回调
158
+ // 可选
159
+ },
160
+ drawerProps: { // 其他 antd Drawer 属性
161
+ // 例如:
162
+ // height: 300, // 当 placement 为 top/bottom 时设置高度
163
+ // destroyOnClose: true, // 关闭时销毁子元素
164
+ // zIndex: 1000, // 层级
165
+ // ...
166
+ }
167
+ });
168
+ ```
169
+
170
+ ---
171
+
172
+ ## 方式 2:useDrawerHelper(组件内使用)
173
+
174
+ ### 特点
175
+ - ✅ 在组件内使用,更集成
176
+ - ✅ 自动管理状态
177
+ - ✅ 自动继承主题
178
+ - ⚠️ 只能在组件内使用
179
+
180
+ ### 基础用法
181
+
182
+ ```jsx
183
+ import { useDrawerHelper } from '@/components/drawer';
184
+ import { Form, Input } from 'antd';
185
+
186
+ function MyComponent() {
187
+ const { openDrawer, DrawerComponent } = useDrawerHelper();
188
+ const [form] = Form.useForm();
189
+
190
+ const handleEdit = async () => {
191
+ let formRef = null;
192
+
193
+ const result = await openDrawer({
194
+ title: '编辑用户',
195
+ width: 600,
196
+ content: (
197
+ <Form ref={(ref) => (formRef = ref)} layout="vertical">
198
+ <Form.Item label="姓名" name="name" rules={[{ required: true }]}>
199
+ <Input />
200
+ </Form.Item>
201
+ </Form>
202
+ ),
203
+ onOk: async () => {
204
+ const values = await formRef.validateFields();
205
+ await saveData(values);
206
+ },
207
+ });
208
+
209
+ if (result) {
210
+ console.log('保存成功');
211
+ }
212
+ };
213
+
214
+ return (
215
+ <>
216
+ <button onClick={handleEdit}>编辑</button>
217
+ <DrawerComponent />
218
+ </>
219
+ );
220
+ }
221
+ ```
222
+
223
+ ---
224
+
225
+ ## 与 Modal 的区别
226
+
227
+ | 特性 | Modal | Drawer |
228
+ |------|-------|--------|
229
+ | 显示方式 | 居中弹窗 | 侧边滑出 |
230
+ | 默认宽度 | 520px | 480px |
231
+ | 遮罩关闭 | 默认 false | 默认 true |
232
+ | 适用场景 | 简短确认、表单编辑 | 复杂表单、详情展示、多步骤操作 |
233
+
234
+ ### 何时使用 Drawer
235
+
236
+ - 需要展示较多内容时
237
+ - 需要保持上下文可见(如列表页)
238
+ - 多步骤操作流程
239
+ - 详情查看页面
240
+ - 复杂表单编辑
241
+
242
+ ### 何时使用 Modal
243
+
244
+ - 简单的确认对话框
245
+ - 简短的表单输入
246
+ - 需要用户立即注意的重要信息
247
+
248
+ ---
249
+
250
+ ## 常见问题
251
+
252
+ ### Q1: 如何在 onOk 中阻止 Drawer 关闭?
253
+
254
+ **A:** 抛出错误即可:
255
+
256
+ ```jsx
257
+ onOk: async () => {
258
+ const values = await form.validateFields();
259
+ const res = await saveData(values);
260
+
261
+ if (res.code !== 0) {
262
+ throw new Error('保存失败'); // 抛出错误,Drawer 不会关闭
263
+ }
264
+ }
265
+ ```
266
+
267
+ ### Q2: 如何访问表单实例?
268
+
269
+ **A:** 使用 ref:
270
+
271
+ ```jsx
272
+ let formRef = null;
273
+
274
+ showDrawer({
275
+ content: <Form ref={(ref) => (formRef = ref)}>{/* ... */}</Form>,
276
+ onOk: async () => {
277
+ const values = await formRef.validateFields();
278
+ }
279
+ });
280
+ ```
281
+
282
+ ### Q3: 如何设置 Drawer 的高度?
283
+
284
+ **A:** 当 `placement` 为 `top` 或 `bottom` 时,通过 `drawerProps.height` 设置:
285
+
286
+ ```jsx
287
+ showDrawer({
288
+ title: '通知',
289
+ placement: 'top',
290
+ content: <NotificationList />,
291
+ drawerProps: {
292
+ height: 300,
293
+ },
294
+ });
295
+ ```
296
+
297
+ ### Q4: 如何自定义底部按钮?
298
+
299
+ **A:** 通过 `drawerProps.footer` 自定义:
300
+
301
+ ```jsx
302
+ showDrawer({
303
+ title: '自定义按钮',
304
+ content: <SomeContent />,
305
+ drawerProps: {
306
+ footer: (
307
+ <div style={{ display: 'flex', justifyContent: 'flex-end', gap: '8px' }}>
308
+ <Button onClick={handleCustomAction}>自定义操作</Button>
309
+ <Button type="primary">提交</Button>
310
+ </div>
311
+ ),
312
+ },
313
+ });
314
+ ```
315
+
316
+ ### Q5: 如何在关闭时销毁内容?
317
+
318
+ **A:** 使用 `destroyOnClose`:
319
+
320
+ ```jsx
321
+ showDrawer({
322
+ title: '详情',
323
+ content: <DetailContent />,
324
+ drawerProps: {
325
+ destroyOnClose: true,
326
+ },
327
+ });
328
+ ```
329
+
330
+ ---
331
+
332
+ ## 总结
333
+
334
+ - **推荐使用 showDrawer**:代码简洁,功能完整
335
+ - **自动继承主题**:无需额外配置
336
+ - **逐步使用**:根据场景选择 Modal 或 Drawer