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.
- package/build/package.json +2 -1
- package/build/vite.config.js +1 -0
- package/build/webpack.config.js +16 -2
- package/package.json +1 -1
- package/src/build.js +1 -1
- package/templates/template_admin_antd5/package.json +3 -3
- package/templates/template_admin_antd5/public/src/_antd.less +4 -4
- package/templates/template_admin_antd5/public/src/_reset.module.less +1 -1
- package/templates/template_admin_antd5/public/src/_variable.module.less +5 -5
- package/templates/template_admin_antd5/public/src/assets/images/expand-hover.png +0 -0
- package/templates/template_admin_antd5/public/src/assets/images/expand.png +0 -0
- package/templates/template_admin_antd5/public/src/assets/images/icon-add.png +0 -0
- package/templates/template_admin_antd5/public/src/assets/images/icon-full-size.png +0 -0
- package/templates/template_admin_antd5/public/src/assets/images/icon-resize.png +0 -0
- package/templates/template_admin_antd5/public/src/assets/images/icon-user.png +0 -0
- package/templates/template_admin_antd5/public/src/assets/images/login/bg.png +0 -0
- package/templates/template_admin_antd5/public/src/assets/images/login/logo.png +0 -0
- package/templates/template_admin_antd5/public/src/assets/images/nav/slogan.png +0 -0
- package/templates/template_admin_antd5/public/src/assets/images/unexpand-hover.png +0 -0
- package/templates/template_admin_antd5/public/src/assets/images/unexpand.png +0 -0
- package/templates/template_admin_antd5/public/src/components/antd/antProvider.jsx +16 -4
- package/templates/template_admin_antd5/public/src/components/antd/drawer/README.md +336 -0
- package/templates/template_admin_antd5/public/src/components/antd/drawer/index.jsx +264 -0
- package/templates/template_admin_antd5/public/src/components/antd/index.jsx +19 -7
- package/templates/template_admin_antd5/public/src/components/antd/index.module.less +26 -0
- package/templates/template_admin_antd5/public/src/components/antd/modal/README.md +324 -0
- package/templates/template_admin_antd5/public/src/components/antd/modal/index.jsx +185 -0
- package/templates/template_admin_antd5/public/src/components/antd/select/index.jsx +1 -1
- package/templates/template_admin_antd5/public/src/components/antd/spin/index.jsx +92 -0
- package/templates/template_admin_antd5/public/src/components/antd/spin/index.module.less +58 -0
- package/templates/template_admin_antd5/public/src/components/antd/theme.js +19 -8
- package/templates/template_admin_antd5/public/src/components/antd/tooltip/detail/index.jsx +19 -56
- package/templates/template_admin_antd5/public/src/components/debug/index.jsx +7 -2
- package/templates/template_admin_antd5/public/src/components/error/index.jsx +0 -5
- package/templates/template_admin_antd5/public/src/components/icon/expand/index.jsx +17 -0
- package/templates/template_admin_antd5/public/src/components/icon/expand/index.module.less +22 -0
- package/templates/template_admin_antd5/public/src/components/icon/fullSize/index.jsx +13 -0
- package/templates/template_admin_antd5/public/src/components/icon/fullSize/index.module.less +28 -0
- package/templates/template_admin_antd5/public/src/components/icon/index.jsx +7 -1
- package/templates/template_admin_antd5/public/src/components/image/preview.jsx +7 -10
- package/templates/template_admin_antd5/public/src/components/layout/basic/index.module.less +1 -1
- package/templates/template_admin_antd5/public/src/components/leftMenu/index.jsx +1 -2
- package/templates/template_admin_antd5/public/src/components/link/index.module.less +2 -2
- package/templates/template_admin_antd5/public/src/components/menuIcon/index.module.less +3 -3
- package/templates/template_admin_antd5/public/src/components/popup/index.jsx +91 -50
- package/templates/template_admin_antd5/public/src/components/popup/index.module.less +22 -15
- package/templates/template_admin_antd5/public/src/components/react/index.jsx +23 -9
- package/templates/template_admin_antd5/public/src/components/resizeBox/index.jsx +3 -3
- package/templates/template_admin_antd5/public/src/components/select/defaultServicesSelect/index.jsx +151 -40
- package/templates/template_admin_antd5/public/src/components/select/dictSelect/index.jsx +19 -3
- package/templates/template_admin_antd5/public/src/components/select/useSelectList.jsx +65 -65
- package/templates/template_admin_antd5/public/src/components/table/index.jsx +48 -327
- package/templates/template_admin_antd5/public/src/components/table/index.module.less +0 -110
- package/templates/template_admin_antd5/public/src/components/table/table/index.jsx +242 -0
- package/templates/template_admin_antd5/public/src/components/table/table/index.module.less +85 -0
- package/templates/template_admin_antd5/public/src/components/table/withPage.jsx +53 -0
- package/templates/template_admin_antd5/public/src/components/topMenu/index.jsx +46 -11
- package/templates/template_admin_antd5/public/src/components/topMenu/index.module.less +10 -7
- package/templates/template_admin_antd5/public/src/components/topMenu/popmenu/index.jsx +89 -0
- package/templates/template_admin_antd5/public/src/components/topMenu/popmenu/index.module.less +76 -0
- package/templates/template_admin_antd5/public/src/components/topMenu/topBar/index.module.less +4 -3
- package/templates/template_admin_antd5/public/src/components/video/index.jsx +1 -1
- package/templates/template_admin_antd5/public/src/components/video/preview.jsx +7 -10
- package/templates/template_admin_antd5/public/src/config.js +3 -0
- package/templates/template_admin_antd5/public/src/hooks/useLoading.jsx +2 -2
- package/templates/template_admin_antd5/public/src/index.jsx +7 -4
- package/templates/template_admin_antd5/public/src/mock/demo.js +3 -3
- package/templates/template_admin_antd5/public/src/pages/antdComponents/button/index.jsx +22 -0
- package/templates/template_admin_antd5/public/src/pages/antdComponents/check/index.jsx +12 -0
- package/templates/template_admin_antd5/public/src/pages/antdComponents/index.jsx +57 -114
- package/templates/template_admin_antd5/public/src/pages/antdComponents/index.module.less +5 -0
- package/templates/template_admin_antd5/public/src/pages/antdComponents/input/index.jsx +14 -0
- package/templates/template_admin_antd5/public/src/pages/antdComponents/loading/index.jsx +31 -0
- package/templates/template_admin_antd5/public/src/pages/antdComponents/message/index.jsx +102 -0
- package/templates/template_admin_antd5/public/src/pages/antdComponents/message/index.module.less +17 -0
- package/templates/template_admin_antd5/public/src/pages/antdComponents/radio/index.jsx +26 -0
- package/templates/template_admin_antd5/public/src/pages/antdComponents/select/index.jsx +13 -0
- package/templates/template_admin_antd5/public/src/pages/antdComponents/switch/index.jsx +12 -0
- package/templates/template_admin_antd5/public/src/pages/antdComponents/tableWithPage/index.jsx +70 -0
- package/templates/template_admin_antd5/public/src/pages/antdComponents/text/index.jsx +21 -0
- package/templates/template_admin_antd5/public/src/pages/auth/user/dialog/index.jsx +48 -75
- package/templates/template_admin_antd5/public/src/pages/auth/user/index.jsx +17 -23
- package/templates/template_admin_antd5/public/src/pages/lazyLoad/index.jsx +11 -0
- package/templates/template_admin_antd5/public/src/pages/login/index.jsx +8 -3
- package/templates/template_admin_antd5/public/src/pages/login/index.module.less +18 -10
- package/templates/template_admin_antd5/public/src/provider/menu.jsx +5 -0
- package/templates/template_admin_antd5/public/src/route.jsx +14 -9
- package/templates/template_admin_antd5/public/src/services/demo.js +38 -2
- package/templates/template_admin_antd5/public/src/services/interceptor/index.js +30 -3
- package/templates/template_admin_antd5/public/src/types/global.d.js +306 -0
- package/templates/template_admin_antd5/public/src/utils/format.js +1 -1
- package/templates/template_admin_antd5/public/src/utils/index.js +3 -3
- package/templates/template_admin_antd5/public/src/utils/moment.js +15 -0
- package/templates/template_admin_antd5/public/static/version.json +3 -0
- package/templates/template_admin_antd5/public/src/components/_table/column.jsx +0 -47
- package/templates/template_admin_antd5/public/src/components/_table/column.module.less +0 -12
- package/templates/template_admin_antd5/public/src/components/_table/index.jsx +0 -71
- package/templates/template_admin_antd5/public/src/components/_table/index.module.less +0 -15
- package/templates/template_admin_antd5/public/src/components/badge/index.jsx +0 -47
- package/templates/template_admin_antd5/public/src/components/badge/index.module.less +0 -44
- package/templates/template_admin_antd5/public/src/components/page/pageLoading/index.jsx +0 -51
- package/templates/template_admin_antd5/public/src/components/page/pageLoading/index.module.less +0 -29
- package/templates/template_admin_antd5/public/src/components/table/aliTable/index.jsx +0 -250
- package/templates/template_admin_antd5/public/src/components/table/aliTable/index.module.less +0 -105
- package/templates/template_admin_antd5/public/src/components/toast/index.jsx +0 -79
- package/templates/template_admin_antd5/public/src/components/toast/index.module.less +0 -43
- package/templates/template_admin_antd5/public/src/provider/loading.jsx +0 -47
- package/templates/template_admin_antd5/public/src/provider/menu.module.less +0 -35
- package/templates/template_admin_antd5/public/src/type.js +0 -67
- package/templates/template_admin_antd5/renamejstojsx.js +0 -45
- package/templates/template_admin_antd5/renameless.js +0 -53
- /package/templates/template_admin_antd5/public/src/components/{button → antd/button}/index.jsx +0 -0
- /package/templates/template_admin_antd5/public/src/components/resizeBox/{index.module.css → index.module.less} +0 -0
package/build/package.json
CHANGED
|
@@ -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"
|
package/build/vite.config.js
CHANGED
|
@@ -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({
|
package/build/webpack.config.js
CHANGED
|
@@ -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
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.
|
|
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{
|
|
@@ -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;
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -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
|
-
|
|
23
|
+
prefixCls="ant5"
|
|
14
24
|
>
|
|
15
|
-
|
|
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
|