mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-08-25 16:16:20 +08:00
Compare commits
163 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
2aa5e5da76 | ||
![]() |
44b21bfc6c | ||
![]() |
2820d5a627 | ||
![]() |
9640484895 | ||
![]() |
f87b0f2f5e | ||
![]() |
656ee4e5c9 | ||
![]() |
7593ef6a4f | ||
![]() |
b3307fe283 | ||
![]() |
73dc492b2a | ||
![]() |
0bb9c035f7 | ||
![]() |
9e9ea3f43d | ||
![]() |
996f2f3c22 | ||
![]() |
b90a9557a3 | ||
![]() |
7df9b51344 | ||
![]() |
c753d945e0 | ||
![]() |
83c1683bfd | ||
![]() |
044e2e4e86 | ||
![]() |
59a9087728 | ||
![]() |
3b6b4f7303 | ||
![]() |
5fa730c49a | ||
![]() |
6cadcf087d | ||
![]() |
95aca2ab8d | ||
![]() |
e00578c40a | ||
![]() |
6717fe654e | ||
![]() |
ee7c31db44 | ||
![]() |
a36825a6d4 | ||
![]() |
628e820684 | ||
![]() |
0f5ddbf1ec | ||
![]() |
1ddfc31c3c | ||
![]() |
d27633fb31 | ||
![]() |
30fa4cfa2a | ||
![]() |
6e7f6f82ed | ||
![]() |
466d4edcd0 | ||
![]() |
0b0a7ceef9 | ||
![]() |
99daecdb60 | ||
![]() |
c8017b1365 | ||
![]() |
d8362f084f | ||
![]() |
9f6822991c | ||
![]() |
56a966cfbf | ||
![]() |
2884e863ce | ||
![]() |
1235978ab2 | ||
![]() |
9dd9fcd334 | ||
![]() |
a426b9027e | ||
![]() |
455d109f71 | ||
![]() |
6e85795737 | ||
![]() |
d1f59b493d | ||
![]() |
edc3096565 | ||
![]() |
3a5d1a5757 | ||
![]() |
2c867b3d63 | ||
![]() |
fb43fad555 | ||
![]() |
8e01377481 | ||
![]() |
e7c96363a1 | ||
![]() |
93812f734e | ||
![]() |
e15b4f14db | ||
![]() |
a5ff59237f | ||
![]() |
65735926d4 | ||
![]() |
47a448b8ae | ||
![]() |
5138e447e7 | ||
![]() |
837a365885 | ||
![]() |
43658e2fb3 | ||
![]() |
8fa6015b1a | ||
![]() |
91cbe0a03b | ||
![]() |
72634ffe6e | ||
![]() |
c420174c1d | ||
![]() |
b7487675ce | ||
![]() |
1b577922e7 | ||
![]() |
3ba8a67647 | ||
![]() |
beb4ae92c1 | ||
![]() |
cc46935a82 | ||
![]() |
53e79a2d94 | ||
![]() |
8ff5c03d53 | ||
![]() |
c69996d073 | ||
![]() |
b07003e184 | ||
![]() |
45a8eb974a | ||
![]() |
2dd3d85448 | ||
![]() |
da12da9d8c | ||
![]() |
30c5fc63c8 | ||
![]() |
7971896383 | ||
![]() |
a8b18c2697 | ||
![]() |
5ae894a5c7 | ||
![]() |
bcfa338227 | ||
![]() |
b1f31762e3 | ||
![]() |
93f9a19aa1 | ||
![]() |
61d853e6a5 | ||
![]() |
1f55c4180f | ||
![]() |
4b6025cb9a | ||
![]() |
2f6d133b96 | ||
![]() |
9035fd191e | ||
![]() |
bb89c5059c | ||
![]() |
66feb779a8 | ||
![]() |
948219c576 | ||
![]() |
60577d6720 | ||
![]() |
953bfc6f1a | ||
![]() |
2052eb5a65 | ||
![]() |
019555be0c | ||
![]() |
33a335a3f5 | ||
![]() |
9d2231b1cd | ||
![]() |
6d5388aaf1 | ||
![]() |
b2d49cbbf8 | ||
![]() |
1bb5156923 | ||
![]() |
62f8468775 | ||
![]() |
8e5740e715 | ||
![]() |
f3cf162af1 | ||
![]() |
381943078f | ||
![]() |
26f251e1ed | ||
![]() |
1214b7c32c | ||
![]() |
c82040425d | ||
![]() |
5e17cc8802 | ||
![]() |
02e7756062 | ||
![]() |
72f953c8d3 | ||
![]() |
d76cfd7f80 | ||
![]() |
2fd0fd281e | ||
![]() |
be2d11d5d3 | ||
![]() |
88451565db | ||
![]() |
26d9476caf | ||
![]() |
ddd1893b11 | ||
![]() |
e8eefd1bca | ||
![]() |
8879ae8d77 | ||
![]() |
f2b8bb43a0 | ||
![]() |
d2c361803b | ||
![]() |
e2664f6002 | ||
![]() |
225bd4c39d | ||
![]() |
7e6a89ffeb | ||
![]() |
189bc6feb3 | ||
![]() |
a544dd3e58 | ||
![]() |
0065ab0b2d | ||
![]() |
e32789373e | ||
![]() |
c375e32305 | ||
![]() |
4c9e8564bd | ||
![]() |
bdf0be81b0 | ||
![]() |
e23bd2696d | ||
![]() |
98749ec6fe | ||
![]() |
98c206d9c9 | ||
![]() |
fe4eae3714 | ||
![]() |
14fb21d0b7 | ||
![]() |
dce3fb0f20 | ||
![]() |
a5a9b3fb34 | ||
![]() |
a07ab6d7aa | ||
![]() |
9b8f165a36 | ||
![]() |
e1c47233ed | ||
![]() |
956ed2e3f7 | ||
![]() |
8702965057 | ||
![]() |
cebc6a590e | ||
![]() |
525484e7a4 | ||
![]() |
350c85accf | ||
![]() |
202aa42b8d | ||
![]() |
8d185bb584 | ||
![]() |
27207a78ca | ||
![]() |
d1e0e8bcea | ||
![]() |
d3f08e37c5 | ||
![]() |
ee44d99c74 | ||
![]() |
9c4889f085 | ||
![]() |
59cf860564 | ||
![]() |
662b576ac2 | ||
![]() |
42812162c4 | ||
![]() |
9b7ede09b9 | ||
![]() |
8cf004a5f5 | ||
![]() |
32d64dbe81 | ||
![]() |
8b4b767f4c | ||
![]() |
341bd633d8 | ||
![]() |
571f28138f | ||
![]() |
4bb506fb1f | ||
![]() |
c734f6858d |
@@ -25,6 +25,7 @@ module.exports = defineConfig({
|
||||
'plugin:jest/recommended',
|
||||
],
|
||||
rules: {
|
||||
'vue/script-setup-uses-vars': 'error',
|
||||
'@typescript-eslint/ban-ts-ignore': 'off',
|
||||
'@typescript-eslint/explicit-function-return-type': 'off',
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
@@ -61,7 +62,6 @@ module.exports = defineConfig({
|
||||
'vue/singleline-html-element-content-newline': 'off',
|
||||
'vue/attribute-hyphenation': 'off',
|
||||
'vue/require-default-prop': 'off',
|
||||
'vue/script-setup-uses-vars': 'off',
|
||||
'vue/html-self-closing': [
|
||||
'error',
|
||||
{
|
||||
|
28
.github/ISSUE_TEMPLATE/3-bug-cn.md
vendored
Normal file
28
.github/ISSUE_TEMPLATE/3-bug-cn.md
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
---
|
||||
name: 🐛 Bug 报告
|
||||
about: 向我们报告一个Bug以帮助我们改进
|
||||
title: ''
|
||||
labels: 'bug: pending triage'
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
**⚠️ 重要 ⚠️ 在进一步操作之前,请检查下列选项。如果您忽视此模板或者没有提供关键信息,您的 Issue 将直接被关闭**
|
||||
|
||||
- [ ] 已阅读 [文档](https://anncwb.github.io/vue-vben-admin-doc/).
|
||||
- [ ] 确保您的代码已是最新或者所报告的 Bug 在最新版本中可以重现. (部分 Bug 可能已经在最近的代码中修复)
|
||||
- [ ] 已在 Issues 中搜索了相关的关键词
|
||||
- [ ] 不是 ant design vue 组件库的 Bug
|
||||
|
||||
### 描述 Bug
|
||||
|
||||
请清晰地描述此 Bug 的具体表现。
|
||||
|
||||
### 复现 Bug
|
||||
|
||||
请描述在演示页面中复现 Bug 的详细步骤,以确保我们可以理解并定位问题。部分 Bug 如果未在 Demo 中涉及,请务必提供关键代码
|
||||
|
||||
## 系统信息
|
||||
|
||||
- 操作系统:
|
||||
- Node 版本:
|
||||
- 包管理器 (npm/yarn/pnpm) 及其版本:
|
4
.github/workflows/deploy.yml
vendored
4
.github/workflows/deploy.yml
vendored
@@ -68,10 +68,10 @@ jobs:
|
||||
sed -i "s#VITE_BUILD_COMPRESS\s*=.*#VITE_BUILD_COMPRESS = 'gzip'#g" ./.env.production
|
||||
cat ./.env.production
|
||||
|
||||
- name: use Node.js 14
|
||||
- name: use Node.js 16
|
||||
uses: actions/setup-node@v2.1.2
|
||||
with:
|
||||
node-version: '14.x'
|
||||
node-version: '16.x'
|
||||
|
||||
- name: Get yarn cache
|
||||
id: yarn-cache
|
||||
|
4
.github/workflows/ftp-schedule.yml
vendored
4
.github/workflows/ftp-schedule.yml
vendored
@@ -21,10 +21,10 @@ jobs:
|
||||
sed -i "s#VITE_DROP_CONSOLE\s*=.*#VITE_DROP_CONSOLE = true#g" ./.env.production
|
||||
cat ./.env.production
|
||||
|
||||
- name: use Node.js 15
|
||||
- name: use Node.js 16
|
||||
uses: actions/setup-node@v2.1.2
|
||||
with:
|
||||
node-version: '15.x'
|
||||
node-version: '16.x'
|
||||
|
||||
- name: Get yarn cache
|
||||
id: yarn-cache
|
||||
|
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@@ -8,6 +8,6 @@
|
||||
"url": "http://localhost:3100",
|
||||
"webRoot": "${workspaceFolder}/src",
|
||||
"sourceMaps": true
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
|
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
@@ -117,6 +117,7 @@
|
||||
"i18n-ally.pathMatcher": "{locale}/{namespaces}.{ext}",
|
||||
"i18n-ally.enabledParsers": ["ts"],
|
||||
"i18n-ally.sourceLanguage": "en",
|
||||
"i18n-ally.displayLanguage": "zh-CN",
|
||||
"i18n-ally.enabledFrameworks": ["vue", "react"],
|
||||
"cSpell.words": [
|
||||
"vben",
|
||||
@@ -147,6 +148,8 @@
|
||||
"vueuse",
|
||||
"zxcvbn",
|
||||
"lintstagedrc",
|
||||
"brotli"
|
||||
"brotli",
|
||||
"tailwindcss",
|
||||
"sider"
|
||||
]
|
||||
}
|
||||
|
@@ -1,3 +1,88 @@
|
||||
## 2.7.2(2021-09-14)
|
||||
|
||||
### ✨ Features
|
||||
|
||||
- **BasicForm** New `Divider` in the form component for dividing the area of longer forms
|
||||
- **BasicTable**
|
||||
- Cell editor adds submit callback, which will decide whether to submit data to the form based on the result returned by the callback function
|
||||
- Add check method for row editing, allowing only check but not submit value, so asynchronously save data successfully before submit to table
|
||||
- Fix the problem that the `rowClassName` property cannot be used at the same time as `striped`.
|
||||
- New component **MarkdownViewer** for displaying rich text in Markdown format
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- **CodeEditor** Fix JSON editor throwing exception when formatting invalid JSON text
|
||||
- **Tinymce** fixes an issue where inline mode throws an exception in some scenarios
|
||||
- **BasicTable**
|
||||
- Repair the problem that the editing icon is not displayed when the content of editable cell is empty
|
||||
- Repair the problem that the total row at the end of the table sometimes fails to align with the columns in the main part of the table.
|
||||
- **MarkDown** Repair the problem that the value of initial value property does not work.
|
||||
- **BasicUpload** Repair the problem that `accept` property does not support `MIME` and suffix name starting with dot.
|
||||
- **ApiSelect** Fix the problem of type definition of `value` property.
|
||||
- **Other**
|
||||
- Repair the problem that some wrapper components give error when using slots.
|
||||
- Repair the problem that `theme` parameter of `useECharts` does not work.
|
||||
- Repair the problem that when `Token` is invalid, pressing F5 to refresh the page may cause abnormal page loading.
|
||||
- Repair the problem that the improper call of `useRedo` may lead to `path` redirection abnormality.
|
||||
- Repair the problem that `vite` custom mode name does not support underscore.
|
||||
|
||||
## 2.7.1(2021-08-16)
|
||||
|
||||
- Upgrade vue 3.2, if the operation fails, delete node_modules and reinstall it
|
||||
|
||||
### ✨ Features
|
||||
|
||||
- **BasicTree** Add search function related properties and methods
|
||||
- **BasicForm** added `alwaysShowLines` to set the number of lines kept displayed when folding
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- **Cropper** Fix the problem of failure to destroy in time
|
||||
- **BasicTable**
|
||||
- Fix the problem that `CellFormat` cannot use `Map` type data
|
||||
- Fixed an issue where the editable cell failed to display the `0` value correctly
|
||||
- Fixed the issue that selection-change event failed to trigger correctly when unchecked
|
||||
- Fix the problem that the background color of the full screen state under the light theme is incorrect
|
||||
- Fix the problem of obtaining complete data when `getSelectRows` does not support remote data cross-page selection
|
||||
- Fix the issue that the `size` property provided for editing components in `editComponentProps` is invalid
|
||||
- **Qrcode** Fixed the problem that the QR code component could not be drawn in time when it was created
|
||||
- **BasicModal** Fix the problem that the `helpMessage` property does not work
|
||||
- **BasicButton** Fix the problem that the button style performance is inconsistent with the official antd
|
||||
- **Others** Fix the problem that `useRedo` (reload the current route) will lose route `params` data
|
||||
|
||||
## 2.7.0(2021-08-03)
|
||||
|
||||
## (Breaking changes) Breaking changes
|
||||
|
||||
- Restore the project `tailwindcss` back to `windicss`, tried `tailwindcss`, there may be a lot of problems, first switch back to `windicss` to improve development efficiency and lower switching costs.
|
||||
- There are currently incompatible areas of the project
|
||||
- The wording of `xl:!m-4` needs to be changed to `!xl:m-4`, note that only `!` is incompatible. If you don’t use it, you don’t need to change it.
|
||||
- The memory overflow problem may still exist (low frequency, just restart, restart vite faster)
|
||||
|
||||
### ✨ Features
|
||||
|
||||
- **Preview** Add new properties and events
|
||||
- **Dark Theme** added support for tailwindcss night mode
|
||||
- **Others** add setTip method for useLoading
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- **ApiTreeSelect** Fixed the problem of failing to monitor `params` changes correctly
|
||||
- **ImgRotateDragVerify** Fix the problem that the component `resume` method cannot be called
|
||||
- **TableAction** Fix the problem that the stopButtonPropagation property does not work in some cases
|
||||
- **PageWrapper** Fix the problem of invalid `class` attribute
|
||||
- **BasicTree** Fix the problem that the `checkAll` method will affect the `disabled` state node
|
||||
- **BasicTable**
|
||||
- Fix the issue that editable cells do not support `ellipsis` configuration
|
||||
- Fixed the problem that the pop-up layer of sub-components (popconfirm and edit components such as select and treeSelect) cannot be seen in full-screen mode
|
||||
- Fixed an issue where when `expandRowByClick` is enabled, clicking non-expandable rows may cause style errors
|
||||
- Fix the problem that the dynamic change of `pagination` property does not take effect
|
||||
- Fix the problem that `getSelectRows` does not support the child data of the tree table -**Dark Theme** Fix the color matching problem under the dark theme
|
||||
- Fix the background color of the selected node of the `Tree` component
|
||||
- Fix the color configuration of the `Alert` component
|
||||
- Fix the problem of the button color of `link` type in the disabled state
|
||||
- Fix the style problem of checked checkboxes in `Tree` -**Others** Fix the problem that useScript failed to automatically remove the script node
|
||||
|
||||
## 2.6.1(2021-07-19)
|
||||
|
||||
### ✨ Features
|
||||
|
319
CHANGELOG.md
319
CHANGELOG.md
@@ -1,3 +1,322 @@
|
||||
## [2.7.2](https://github.com/anncwb/vue-vben-admin/compare/v2.7.1...v2.7.2) (2021-09-13)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- fixed token clear error ([9640484](https://github.com/anncwb/vue-vben-admin/commit/96404848955f84d57b88dd240ab3a57b7017103c))
|
||||
- improve type introduction, fix [#1196](https://github.com/anncwb/vue-vben-admin/issues/1196) ([2820d5a](https://github.com/anncwb/vue-vben-admin/commit/2820d5a627260bb8eddfcd25df1cd7d1196932e8))
|
||||
- **api-select:** fixed `value` prop define ([f87b0f2](https://github.com/anncwb/vue-vben-admin/commit/f87b0f2f5efe4e9977c4cc0742dbcaefbad2ca02)), closes [#1175](https://github.com/anncwb/vue-vben-admin/issues/1175)
|
||||
- **card-list:** fixed build error ([628e820](https://github.com/anncwb/vue-vben-admin/commit/628e820684ce5d81f130548505efe83e8d516131))
|
||||
- **code-editor:** fixed formatting error ([e7c9636](https://github.com/anncwb/vue-vben-admin/commit/e7c96363a1963b7733a9ee498403eb6a062160e6))
|
||||
- **echarts:** theme setting supported ([93812f7](https://github.com/anncwb/vue-vben-admin/commit/93812f734ec85529aa27fc3100a2eaef8c7a6df5)), closes [#1095](https://github.com/anncwb/vue-vben-admin/issues/1095)
|
||||
- **markdown:** the hierarchy of markDown components after full screen ([c8017b1](https://github.com/anncwb/vue-vben-admin/commit/c8017b1365ea49f95a26148a539f8c30d8a8631f))
|
||||
- **markdown:** `value` not worked on init ([0bb9c03](https://github.com/anncwb/vue-vben-admin/commit/0bb9c035f77588c58d36b3fd45d89b9730cd70d7))
|
||||
- **modal:** avoid style pollution to the whole world ([#1128](https://github.com/anncwb/vue-vben-admin/issues/1128)) ([6e7f6f8](https://github.com/anncwb/vue-vben-admin/commit/6e7f6f82ed2819e02e2b3114884e665d0762d7e9))
|
||||
- **table:** `rowClassName` not worked with `striped` ([044e2e4](https://github.com/anncwb/vue-vben-admin/commit/044e2e4e866dd5b120daab03c47aba1ca1f9140a)), closes [#1167](https://github.com/anncwb/vue-vben-admin/issues/1167)
|
||||
- **table:** 修复表格背景颜色再深色模式下会被穿透问题 ([#1133](https://github.com/anncwb/vue-vben-admin/issues/1133)) ([30fa4cf](https://github.com/anncwb/vue-vben-admin/commit/30fa4cfa2ab6229efc67224fd082e32da0a95d49))
|
||||
- **table:** editable icon not show with empty cell ([edc3096](https://github.com/anncwb/vue-vben-admin/commit/edc30965653831b4572c5d5e067f556f4757ce75)), closes [#1103](https://github.com/anncwb/vue-vben-admin/issues/1103)
|
||||
- **table:** fix table footer style ([a426b90](https://github.com/anncwb/vue-vben-admin/commit/a426b9027ef524f9033d510d0c74cd17b2ad5bcf)), closes [#1112](https://github.com/anncwb/vue-vben-admin/issues/1112)
|
||||
- **table:** Solve the bug of setting ifshow to false in table column ([#1166](https://github.com/anncwb/vue-vben-admin/issues/1166)) ([5fa730c](https://github.com/anncwb/vue-vben-admin/commit/5fa730c49ae46fa448d49d597dc7b2b6a019b268))
|
||||
- **table-action:** `divider` not work as expected ([7593ef6](https://github.com/anncwb/vue-vben-admin/commit/7593ef6a4f081ed800658b70316ab2f1e3ee631d))
|
||||
- **tinymce:** fixed `inline` mode ([8e01377](https://github.com/anncwb/vue-vben-admin/commit/8e01377481a34cda221de6bbb01fc7d5b2824c82)), closes [#1092](https://github.com/anncwb/vue-vben-admin/issues/1092)
|
||||
- **upload:** `accept` not work as expected ([656ee4e](https://github.com/anncwb/vue-vben-admin/commit/656ee4e5c9b363b6ab59aa071915414e5ee95de4))
|
||||
- `getUserinfo` is compatible with empty roles data ([1ddfc31](https://github.com/anncwb/vue-vben-admin/commit/1ddfc31c3c4c792c5f741f6d0f0754ffc9a6613c))
|
||||
- `slots` worked in `basicTable` and `basicModal` ([5138e44](https://github.com/anncwb/vue-vben-admin/commit/5138e447e74ef01309457d22f44129c8b1b2f815))
|
||||
- `useRedo` called duplicate may cause exception ([1235978](https://github.com/anncwb/vue-vben-admin/commit/1235978ab23740dfb11e3de7ac26a7d10a4899dc)), closes [#1121](https://github.com/anncwb/vue-vben-admin/issues/1121)
|
||||
- 修复 `apiSelect` 绑定值 `attrs` 的问题 ([#1172](https://github.com/anncwb/vue-vben-admin/issues/1172)) ([c753d94](https://github.com/anncwb/vue-vben-admin/commit/c753d945e08f72cab5bc8a585601cab6a0523fca))
|
||||
- 修复弹窗全屏按钮异常关闭的问题([#1177](https://github.com/anncwb/vue-vben-admin/issues/1177)) ([#1182](https://github.com/anncwb/vue-vben-admin/issues/1182)) ([9e9ea3f](https://github.com/anncwb/vue-vben-admin/commit/9e9ea3f43d8c4b88649c1998bf89186b5f7ee6a2))
|
||||
- 修改 axios 中 urlPrefix 字段不生效问题 ([#1170](https://github.com/anncwb/vue-vben-admin/issues/1170)) ([7df9b51](https://github.com/anncwb/vue-vben-admin/commit/7df9b513447d8deab2fd8e86fa23c807adb6d440))
|
||||
- add loss action for userStore ([a36825a](https://github.com/anncwb/vue-vben-admin/commit/a36825a6d423aae9aaf1936ce55947ba8c2104b0))
|
||||
- fix all types of errors, compatible with volar plugin ([e15b4f1](https://github.com/anncwb/vue-vben-admin/commit/e15b4f14db51812effd55670b3d2da7b082e00a7))
|
||||
- fixed build warning for style of `intro.js` ([d27633f](https://github.com/anncwb/vue-vben-admin/commit/d27633fb31824e92cbeb24f8d626d8e33ce7179e)), closes [#1130](https://github.com/anncwb/vue-vben-admin/issues/1130)
|
||||
- Improve content height calculation ([#1136](https://github.com/anncwb/vue-vben-admin/issues/1136)) ([6717fe6](https://github.com/anncwb/vue-vben-admin/commit/6717fe654e88e6a939a16c523832870388ec1886))
|
||||
- name of vite `mode` support more characters ([9f68229](https://github.com/anncwb/vue-vben-admin/commit/9f6822991c4b2da78e0a5d0c7d6e0288f0d9d1cb)), closes [#1115](https://github.com/anncwb/vue-vben-admin/issues/1115)
|
||||
- refresh failed while token invalid ([3a5d1a5](https://github.com/anncwb/vue-vben-admin/commit/3a5d1a5757c0a2be17e6dd370cbb023ddbb30d5e)), closes [#1101](https://github.com/anncwb/vue-vben-admin/issues/1101)
|
||||
- warning in logout action ([b3307fe](https://github.com/anncwb/vue-vben-admin/commit/b3307fe2836fb6f9806d602d5bdb7e540c49f1b0))
|
||||
- **tinymce:** fixed `tinymce` destory method ([fb43fad](https://github.com/anncwb/vue-vben-admin/commit/fb43fad555b093af23194bdb3670bc1347c0010f))
|
||||
|
||||
### Features
|
||||
|
||||
- **demo:** add `JsonPreview` demo ([83c1683](https://github.com/anncwb/vue-vben-admin/commit/83c1683bfdcf4ea33de771895b46e41f276969e8)), closes [#1146](https://github.com/anncwb/vue-vben-admin/issues/1146)
|
||||
- **form:** add `Divider` for schema component type ([47a448b](https://github.com/anncwb/vue-vben-admin/commit/47a448b8aea572e54dac97dc4f9fb6c1c005685a))
|
||||
- **form:** component `Divider` support `helpMessage` ([a5ff592](https://github.com/anncwb/vue-vben-admin/commit/a5ff59237f2eb6ea4c1770acc594c75bf1f6e95f))
|
||||
- **markdown-viewer:** add new component ([73dc492](https://github.com/anncwb/vue-vben-admin/commit/73dc492b2a49793d945ccdae7f5c429c874f298c)), closes [#1181](https://github.com/anncwb/vue-vben-admin/issues/1181)
|
||||
- **table:** 添加和支持动态删除和插入数据 ([#1152](https://github.com/anncwb/vue-vben-admin/issues/1152)) ([59a9087](https://github.com/anncwb/vue-vben-admin/commit/59a90877287a289f746eec97d12c2d3a1d5476b0))
|
||||
- **table:** add `beforeEditSubmit` for editable cell ([2c867b3](https://github.com/anncwb/vue-vben-admin/commit/2c867b3d636d57cdc526a4ca600af7d747b7d833))
|
||||
- **table:** add `onValid` for editRow ([ee7c31d](https://github.com/anncwb/vue-vben-admin/commit/ee7c31db44fd8f99f0d26da368e1d82b5630f309))
|
||||
- **tree:** 1. 添加自定义数据过滤判断方法 2. 添加搜索完成自动展开结果选项 3. 添加搜索完成自动选中结果选项 4. 树节点数据变化时强制搜索(同步 searchData 避免展示错误) ([#1132](https://github.com/anncwb/vue-vben-admin/issues/1132)) ([e00578c](https://github.com/anncwb/vue-vben-admin/commit/e00578c40a585a4a35f235c0228aebaf62cea1ba))
|
||||
- add CardList component ([0f5ddbf](https://github.com/anncwb/vue-vben-admin/commit/0f5ddbf1ec777fc238a94bd037d37ea787316757))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
- **tree:** 优化 Tree 搜索功能,添加搜索高亮功能,优化样式表现 ([#1153](https://github.com/anncwb/vue-vben-admin/issues/1153)) ([3b6b4f7](https://github.com/anncwb/vue-vben-admin/commit/3b6b4f73033e8757fd3a032f0910dfcc30dee151))
|
||||
- not waiting for router.isReady ([2884e86](https://github.com/anncwb/vue-vben-admin/commit/2884e863ce826cd92cd782f40cdee31588bc6d32))
|
||||
- optimize css volume ([466d4ed](https://github.com/anncwb/vue-vben-admin/commit/466d4edcd02fc91e2b4cdbbc3c501bfd2fde7a3d))
|
||||
|
||||
## [2.7.1](https://github.com/anncwb/vue-vben-admin/compare/v2.6.1...v2.7.1) (2021-08-16)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- `slots` working in components ([b1f3176](https://github.com/anncwb/vue-vben-admin/commit/b1f31762e3c86a432a8d559ab957444eaf5525ad))
|
||||
- add axios error info from response ([#1083](https://github.com/anncwb/vue-vben-admin/issues/1083)) ([72634ff](https://github.com/anncwb/vue-vben-admin/commit/72634ffe6e6649d36ee41f7633c8ee2ab80cf25e))
|
||||
- auto remove script dom in `useScript` ([a544dd3](https://github.com/anncwb/vue-vben-admin/commit/a544dd3e589329339177dad3d5c1f75dd6e6f0ca))
|
||||
- fixed `useRedo` may loss route params ([2dd3d85](https://github.com/anncwb/vue-vben-admin/commit/2dd3d8544866231895d23dba63785b683ae0062e)), closes [#1079](https://github.com/anncwb/vue-vben-admin/issues/1079)
|
||||
- fixed basicButton ghost style ([3ba8a67](https://github.com/anncwb/vue-vben-admin/commit/3ba8a67647d35fb9639a5af66f33d43eff493d15))
|
||||
- fixed basicButton primary style ([1b57792](https://github.com/anncwb/vue-vben-admin/commit/1b577922e752c02fe7c033c53be37ef81e4e9b8e))
|
||||
- fixed basicButton style ([beb4ae9](https://github.com/anncwb/vue-vben-admin/commit/beb4ae92c190780bbd3bc6bc7547d52e2ccf8cf1))
|
||||
- **cropper:** cropper not destroy in time ([3819430](https://github.com/anncwb/vue-vben-admin/commit/381943078fd55123fde3d5555e04f279d7f1c407)), closes [#1027](https://github.com/anncwb/vue-vben-admin/issues/1027)
|
||||
- **demo:** fix form style in modal ([30c5fc6](https://github.com/anncwb/vue-vben-admin/commit/30c5fc63c8600cfb03f917d79e56c0a7e7ff64e0)), closes [#1076](https://github.com/anncwb/vue-vben-admin/issues/1076)
|
||||
- **i18n:** add i18n translate data ([1f55c41](https://github.com/anncwb/vue-vben-admin/commit/1f55c4180f9c0cf48e3796a77d6f0bfd46107272))
|
||||
- **locales:** fix that vscode extension i18n-Ally detect zh-CN as zh ([#1044](https://github.com/anncwb/vue-vben-admin/issues/1044)) ([b2d49cb](https://github.com/anncwb/vue-vben-admin/commit/b2d49cbbf81cb15e75905deb95bdf7ac4af4e599))
|
||||
- **modal:** `helpMessage` doesn't work ([953bfc6](https://github.com/anncwb/vue-vben-admin/commit/953bfc6f1a559309ea2b1114b8ede911a3751cc7))
|
||||
- **page-wrapper:** fix `class` not working ([8879ae8](https://github.com/anncwb/vue-vben-admin/commit/8879ae8d773e8dc4c252c4234eefeab9bc135a30))
|
||||
- **qrcode:** qrcode not displayed properly ([26f251e](https://github.com/anncwb/vue-vben-admin/commit/26f251e1ed5bfd79c8615fb552ca302f917cc588)), closes [#1026](https://github.com/anncwb/vue-vben-admin/issues/1026)
|
||||
- **route:** the whitelist should include basicRoutes ([#1048](https://github.com/anncwb/vue-vben-admin/issues/1048)) ([1bb5156](https://github.com/anncwb/vue-vben-admin/commit/1bb51569236fd9bcc55dd9f237f51f218956b258))
|
||||
- **table:** `0` is not shown in editable cell ([33a335a](https://github.com/anncwb/vue-vben-admin/commit/33a335a3f52aead522b3fbee0d558e2e797580ff)), closes [#1039](https://github.com/anncwb/vue-vben-admin/issues/1039)
|
||||
- **table:** `cellFormat` support `Map` ([1214b7c](https://github.com/anncwb/vue-vben-admin/commit/1214b7c32c425750a4d0202a9b235eb9e45a6f47)), closes [#1031](https://github.com/anncwb/vue-vben-admin/issues/1031)
|
||||
- **table:** `getSelectRows` support multi-page ([4b6025c](https://github.com/anncwb/vue-vben-admin/commit/4b6025cb9a3ef067680201ec3052bc651e0a0c1b)), closes [#914](https://github.com/anncwb/vue-vben-admin/issues/914)
|
||||
- **table:** `selection-change` not triggered in unchecking ([019555b](https://github.com/anncwb/vue-vben-admin/commit/019555be0c88edc673cae382023d647e78959b30)), closes [#1053](https://github.com/anncwb/vue-vben-admin/issues/1053)
|
||||
- **table:** `size` not worked in `editComponentProps` ([7971896](https://github.com/anncwb/vue-vben-admin/commit/7971896383296c155b7ab16b5beb3544f34ee525)), closes [#1074](https://github.com/anncwb/vue-vben-admin/issues/1074)
|
||||
- **table:** fix `getSelectRows` for treeTable ([f2b8bb4](https://github.com/anncwb/vue-vben-admin/commit/f2b8bb43a0b9172b9ef9ced8e83bf91143a091d9)), closes [#1003](https://github.com/anncwb/vue-vben-admin/issues/1003)
|
||||
- **table:** fix `injection not found` warning ([53e79a2](https://github.com/anncwb/vue-vben-admin/commit/53e79a2d94df19c0e1aa7399d5ce4c27834e0350))
|
||||
- **types:** fix some type errors ([9035fd1](https://github.com/anncwb/vue-vben-admin/commit/9035fd191e4e8d954f42b3a4cd1e80ec70b7cbb6))
|
||||
- The Style of tableTitle slot ([#1023](https://github.com/anncwb/vue-vben-admin/issues/1023)) ([02e7756](https://github.com/anncwb/vue-vben-admin/commit/02e77560624cc4a95a5a20ffd5e0601f1f88c6f4))
|
||||
- fix build handler & misc ([#1060](https://github.com/anncwb/vue-vben-admin/issues/1060)) ([66feb77](https://github.com/anncwb/vue-vben-admin/commit/66feb779a8645a93760c784c510512118c4c6efa))
|
||||
- **table:** recursive updateTableDataRecord ([#1024](https://github.com/anncwb/vue-vben-admin/issues/1024)) ([72f953c](https://github.com/anncwb/vue-vben-admin/commit/72f953c8d3413a7f5482793258503017a81cc759))
|
||||
- **table:** wrong bg-color in fullscreen mode ([2052eb5](https://github.com/anncwb/vue-vben-admin/commit/2052eb5a65be38c44165efecdb15266de4638667))
|
||||
- **type:** fix ant-design-vue -> ([#1043](https://github.com/anncwb/vue-vben-admin/issues/1043)) ([6d5388a](https://github.com/anncwb/vue-vben-admin/commit/6d5388aaf143ac76bac0b68d56a3ab6b5993e807))
|
||||
- fix iframe heigth error ([#1012](https://github.com/anncwb/vue-vben-admin/issues/1012)) ([d76cfd7](https://github.com/anncwb/vue-vben-admin/commit/d76cfd7f809ba48880c950a64cb43a5c9c44176c))
|
||||
- Fix the invalid hot update of BasicButton when changing style outside ([#1016](https://github.com/anncwb/vue-vben-admin/issues/1016)) ([be2d11d](https://github.com/anncwb/vue-vben-admin/commit/be2d11d5d344a508e94abe3534726c80e1f1f271))
|
||||
- the position of tinymce upload image is wrong ([#1015](https://github.com/anncwb/vue-vben-admin/issues/1015)) ([2fd0fd2](https://github.com/anncwb/vue-vben-admin/commit/2fd0fd281e65d6d2551478c5f19250347dc14062))
|
||||
- **tree:** fix `checkAll` effects `disabled` node ([ddd1893](https://github.com/anncwb/vue-vben-admin/commit/ddd1893b113e13786037522341abb2e75f8f9d5b))
|
||||
- style property of actionColOpt is invalid ([#997](https://github.com/anncwb/vue-vben-admin/issues/997)) ([225bd4c](https://github.com/anncwb/vue-vben-admin/commit/225bd4c39de377d93c605f33bfdf3d8fd565f12b))
|
||||
- typo ([#980](https://github.com/anncwb/vue-vben-admin/issues/980)) ([7e6a89f](https://github.com/anncwb/vue-vben-admin/commit/7e6a89ffeb8c63467908d5807d3d7c4761620ee3))
|
||||
- **api-tree-select:** auto reload while `params` changed ([c734f68](https://github.com/anncwb/vue-vben-admin/commit/c734f6858daea6d11cd517463b06fcce58744947))
|
||||
- **dark-theme:** alert color in dark-theme ([9b7ede0](https://github.com/anncwb/vue-vben-admin/commit/9b7ede09b9efe4d5a15ab0cdeadac480a29c0f62))
|
||||
- **dark-theme:** bgcolor of `selected tree node` in dark theme ([8cf004a](https://github.com/anncwb/vue-vben-admin/commit/8cf004a5f59895e2487c3a350c83000e585b897e)), closes [#949](https://github.com/anncwb/vue-vben-admin/issues/949)
|
||||
- **dark-theme:** disabled link `button` color ([4281216](https://github.com/anncwb/vue-vben-admin/commit/42812162c46832ce4d3e332bd579c042309115bc))
|
||||
- **dark-theme:** fixed `TreeSelect` & `DatePicker` theme ([d1e0e8b](https://github.com/anncwb/vue-vben-admin/commit/d1e0e8bcea1c168631222989969e14f7d0d1b6a4)), closes [#955](https://github.com/anncwb/vue-vben-admin/issues/955)
|
||||
- **dark-theme:** style for checked tree nodes ([662b576](https://github.com/anncwb/vue-vben-admin/commit/662b576ac2088247cb58e295378f228462508a37))
|
||||
- **demo:** account page form validation ([8702965](https://github.com/anncwb/vue-vben-admin/commit/87029650570e470431fb94d35a273c5d07a73135))
|
||||
- **demo:** fix roles mock data ([c375e32](https://github.com/anncwb/vue-vben-admin/commit/c375e32305eae5128e09ad1bda39ce0cc6afd790))
|
||||
- **form:** remove console error for `setFieldsValue` ([8d185bb](https://github.com/anncwb/vue-vben-admin/commit/8d185bb5841c83eb49c78e8342e65067aa6f9b80)), closes [#952](https://github.com/anncwb/vue-vben-admin/issues/952)
|
||||
- **table:** fix `pagination` props working ([e327893](https://github.com/anncwb/vue-vben-admin/commit/e32789373eb5b1b531572b59692bf552dac365dc))
|
||||
- expandIcon slot of BasicTable component is invalid ([#975](https://github.com/anncwb/vue-vben-admin/issues/975)) ([98c206d](https://github.com/anncwb/vue-vben-admin/commit/98c206d9c9661a18dde4ec7782cbe1eb6e62ebeb))
|
||||
- **demo:** menu `error-log` link to 404 page ([341bd63](https://github.com/anncwb/vue-vben-admin/commit/341bd633d8ed38a5a357db8f97166c2eba2895d3))
|
||||
- **demo:** multi-modal used with dynamic component ([e1c4723](https://github.com/anncwb/vue-vben-admin/commit/e1c47233edf7675aede6d5f023726945a510ddf7))
|
||||
- **echarts:** fix graphic config cannot be used in echarts options ([#959](https://github.com/anncwb/vue-vben-admin/issues/959)) ([525484e](https://github.com/anncwb/vue-vben-admin/commit/525484e7a409b032d22231f90a92e700ef4290ae))
|
||||
- **form:** fix `validate` promise catch ([571f281](https://github.com/anncwb/vue-vben-admin/commit/571f28138f782553eb39cda2d632e5ac1aa1e145))
|
||||
- **img-rotate-drag-verify:** fix `resume` method support ([32d64db](https://github.com/anncwb/vue-vben-admin/commit/32d64dbe816a0afda6ee9e91863199afb3e7b48e)), closes [#946](https://github.com/anncwb/vue-vben-admin/issues/946)
|
||||
- **login:** fix `auto fill` style in dark-theme ([cebc6a5](https://github.com/anncwb/vue-vben-admin/commit/cebc6a590e1a19af7380a55aed43b23af274df0a))
|
||||
- **perm-guard:** Fix the problem that the routing query is lost after refreshing the page ([#941](https://github.com/anncwb/vue-vben-admin/issues/941)) ([9c4889f](https://github.com/anncwb/vue-vben-admin/commit/9c4889f0859bc60decf0ef40c383c1946de1d68a))
|
||||
- **qrcode:** Fix the problem that the QR code cannot be dynamically generated ([#974](https://github.com/anncwb/vue-vben-admin/issues/974)) ([fe4eae3](https://github.com/anncwb/vue-vben-admin/commit/fe4eae37146068f01ba08f033e0c2e8bd03e48b5))
|
||||
- **style:** fix checkbox-checked css in dark mode ([d3f08e3](https://github.com/anncwb/vue-vben-admin/commit/d3f08e37c5b6e46f33d525e9ef4b4c235d77a192))
|
||||
- **table:** component shown in `fullscreen` mode ([a07ab6d](https://github.com/anncwb/vue-vben-admin/commit/a07ab6d7aa1060f856649a9bdbec9dfa50b14f26))
|
||||
- **table:** editable cell display with validation ([202aa42](https://github.com/anncwb/vue-vben-admin/commit/202aa42b8d5a94e84ad386bcf7feab96926c70dd)), closes [#953](https://github.com/anncwb/vue-vben-admin/issues/953)
|
||||
- **table:** fix `dataPicker` show in `fullscreen` mode ([a5a9b3f](https://github.com/anncwb/vue-vben-admin/commit/a5a9b3fb34c64b6ea9c9ab3d58045f6e5963952b))
|
||||
- **table:** fix expand style ([14fb21d](https://github.com/anncwb/vue-vben-admin/commit/14fb21d0b7b9ac69c7b3c463de6d709bd5713d14)), closes [#969](https://github.com/anncwb/vue-vben-admin/issues/969)
|
||||
- **table:** fix tableSettings popup in fullscreen mode ([dce3fb0](https://github.com/anncwb/vue-vben-admin/commit/dce3fb0f20516aaf4817281f5d08109e53a73ecb))
|
||||
- **table-action:** stopButtonPropagation not working ([9b8f165](https://github.com/anncwb/vue-vben-admin/commit/9b8f165a365758d001e6d86ae7afe4ae3316d485))
|
||||
- Fix vite profile hot update error reporting ([#968](https://github.com/anncwb/vue-vben-admin/issues/968)) ([956ed2e](https://github.com/anncwb/vue-vben-admin/commit/956ed2e3f770cc9cf822ce80f71b1e7f179792fb))
|
||||
- **utils:** The date function gets a non-date when the parameter is null ([#954](https://github.com/anncwb/vue-vben-admin/issues/954)) ([350c85a](https://github.com/anncwb/vue-vben-admin/commit/350c85accf5033cc5a21b71bc36d5b7a74eb2573))
|
||||
- fixed moment locale config ([27207a7](https://github.com/anncwb/vue-vben-admin/commit/27207a78caccb04372e0275c5cee526ec460de0e))
|
||||
- typo for utils/env ([#1004](https://github.com/anncwb/vue-vben-admin/issues/1004)) ([e8eefd1](https://github.com/anncwb/vue-vben-admin/commit/e8eefd1bca41c181ec6395bf1d087d2018e2b1f1))
|
||||
- **table:** fix editable cell not support `ellipsis` ([4bb506f](https://github.com/anncwb/vue-vben-admin/commit/4bb506fb1f6ac7d246f8792d29f337ec003ff426)), closes [#944](https://github.com/anncwb/vue-vben-admin/issues/944)
|
||||
|
||||
### Features
|
||||
|
||||
- add `updatePath` for `useTabs` ([bcfa338](https://github.com/anncwb/vue-vben-admin/commit/bcfa33822736b761757a2673d977f752cb5c4f7c)), closes [#1068](https://github.com/anncwb/vue-vben-admin/issues/1068)
|
||||
- always refresh userinfo when page reload ([cc46935](https://github.com/anncwb/vue-vben-admin/commit/cc46935a8296dae62ecfc753a956338ba433927e))
|
||||
- **demo:** add `async-validator` demo ([8b4b767](https://github.com/anncwb/vue-vben-admin/commit/8b4b767f4ca78f7c6f7586d8ba662552c2b7bb51))
|
||||
- **form:** add `alwaysShowLines` prop ([93f9a19](https://github.com/anncwb/vue-vben-admin/commit/93f9a19aa16a3e9cb95338417c52d9a398e3f70b)), closes [#1051](https://github.com/anncwb/vue-vben-admin/issues/1051)
|
||||
- **preview:** add more features ([e23bd26](https://github.com/anncwb/vue-vben-admin/commit/e23bd2696da945291a9b652f1af39ad1936f376b))
|
||||
- **table:** add getRawDataSource() function ([#1029](https://github.com/anncwb/vue-vben-admin/issues/1029)) ([f3cf162](https://github.com/anncwb/vue-vben-admin/commit/f3cf162af1fa5634d4e562fa5239939af6f26093))
|
||||
- **tree:** add searchable function ([60577d6](https://github.com/anncwb/vue-vben-admin/commit/60577d6720fd3f8d4d1a88b20ab902d6161a0eec)), closes [#1057](https://github.com/anncwb/vue-vben-admin/issues/1057)
|
||||
- **use-loading:** add `setTip` method ([26d9476](https://github.com/anncwb/vue-vben-admin/commit/26d9476caff41cc355190604af42e0bd2ef0a353))
|
||||
- Added support for tailwindcss night mode mechanism ([#998](https://github.com/anncwb/vue-vben-admin/issues/998)) ([189bc6f](https://github.com/anncwb/vue-vben-admin/commit/189bc6feb3f2860be8c531dd1ca996f3a2cff018))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
- **table:** fixed code style ([da12da9](https://github.com/anncwb/vue-vben-admin/commit/da12da9d8caeba0e7732551cfbad9b0da3baaac4)), closes [#1070](https://github.com/anncwb/vue-vben-admin/issues/1070)
|
||||
- improve legacy compatibility ([e2664f6](https://github.com/anncwb/vue-vben-admin/commit/e2664f60029f03642f8b1a6afa9b1998705fce37))
|
||||
|
||||
# [2.7.0](https://github.com/anncwb/vue-vben-admin/compare/v2.5.9...v2.7.0) (2021-08-03)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- The Style of tableTitle slot ([#1023](https://github.com/anncwb/vue-vben-admin/issues/1023)) ([02e7756](https://github.com/anncwb/vue-vben-admin/commit/02e77560624cc4a95a5a20ffd5e0601f1f88c6f4))
|
||||
- **api-select:** ensure that the onchange function parameters are correct ([fa64fc8](https://github.com/anncwb/vue-vben-admin/commit/fa64fc8a622832b87fdf672965d55d543b5929a2))
|
||||
- **app-search:** exclude hidden items ([faf5c9f](https://github.com/anncwb/vue-vben-admin/commit/faf5c9fd7ea40c407419a5a5c473f9b0c32c2a53))
|
||||
- **app-search:** exclude items by `hideChildrenInMenu` ([02d3dca](https://github.com/anncwb/vue-vben-admin/commit/02d3dca57efedc1322ae38e3f432cf1f6c2cf839))
|
||||
- **axios:** option `withToken` not work ([d509e89](https://github.com/anncwb/vue-vben-admin/commit/d509e897be5753c852e912112e70dac6247ba467))
|
||||
- **breadcrumb:** `redirect` not worked ([f5e31fe](https://github.com/anncwb/vue-vben-admin/commit/f5e31febbd18372a34166cac390b1d9b914fe80e))
|
||||
- **comp-tree:** support comp-tree-foreach stop,add insertNodesByKey ([#818](https://github.com/anncwb/vue-vben-admin/issues/818)) ([d97aa92](https://github.com/anncwb/vue-vben-admin/commit/d97aa927417bf45a7c127ecfa9b8e835b6b68855))
|
||||
- **CountTo:** Fix displaying empty string when the value is 0 ([#864](https://github.com/anncwb/vue-vben-admin/issues/864)) ([82eb72b](https://github.com/anncwb/vue-vben-admin/commit/82eb72bbced931ba7f50069211f9511035ad09f4))
|
||||
- **demo:** `setup` page route config ([d5d5c4b](https://github.com/anncwb/vue-vben-admin/commit/d5d5c4b4bfb3e3a5e54f9993966adc46a09a8b90))
|
||||
- **demo:** account list fetch loss param ([424b171](https://github.com/anncwb/vue-vben-admin/commit/424b171e0db727f5e0157cbcfd5460f15f8ea609)), closes [#830](https://github.com/anncwb/vue-vben-admin/issues/830)
|
||||
- **demo:** add mock data `account detail` route ([993e19d](https://github.com/anncwb/vue-vben-admin/commit/993e19dcc319e2b4c68df2ab76174b7b4d7b0428)), closes [#858](https://github.com/anncwb/vue-vben-admin/issues/858)
|
||||
- **demo:** fix async tree demo, fixed: [#823](https://github.com/anncwb/vue-vben-admin/issues/823) ([5637588](https://github.com/anncwb/vue-vben-admin/commit/5637588fce880b01137191cc82c73e0fce621e8c))
|
||||
- **demo:** form pages support `keepAlive` ([9228282](https://github.com/anncwb/vue-vben-admin/commit/9228282ae27daaa246f42e441e27b1b05eb30464))
|
||||
- **demo:** resolve `key not exist` warnings ([45a94e4](https://github.com/anncwb/vue-vben-admin/commit/45a94e41c1397b84d08373f84f766204d2488714))
|
||||
- **demo:** style error,fix [#806](https://github.com/anncwb/vue-vben-admin/issues/806) ([a2d8be3](https://github.com/anncwb/vue-vben-admin/commit/a2d8be3ab29da88126f3ba971f6893cb12327759))
|
||||
- **demo-form:** add fieldMapToTime example,fix [#807](https://github.com/anncwb/vue-vben-admin/issues/807) ([a2a75a0](https://github.com/anncwb/vue-vben-admin/commit/a2a75a097ff6c9df12471eff0d62d44d2b88cfff))
|
||||
- **design:** correct tailwind configuration,fix [#800](https://github.com/anncwb/vue-vben-admin/issues/800) ([aec230c](https://github.com/anncwb/vue-vben-admin/commit/aec230ca19d541079b64c54ba00596ef9cd92ca0))
|
||||
- **drawer:** openDrawer is not normal in some cases ([941ad59](https://github.com/anncwb/vue-vben-admin/commit/941ad59759cbd5a5e39bcdf29783d8eea85caf72))
|
||||
- **dropdown:** icon and trigger work unexpected ([60b80c9](https://github.com/anncwb/vue-vben-admin/commit/60b80c96e82da9101d56b2e195e9e7571de11f0a)), closes [#796](https://github.com/anncwb/vue-vben-admin/issues/796) [#787](https://github.com/anncwb/vue-vben-admin/issues/787)
|
||||
- **form:** fix `suffix` slot style ([a9bbed1](https://github.com/anncwb/vue-vben-admin/commit/a9bbed19739376ab2bf67a14b04e872f14ca84cc))
|
||||
- **form:** fix some prop declaration ([b5046f0](https://github.com/anncwb/vue-vben-admin/commit/b5046f07a27e8ca7fc8b961b74fa5e1b0d715149))
|
||||
- **lock-screen:** ensure lock info is saved ([d38ff66](https://github.com/anncwb/vue-vben-admin/commit/d38ff6670a37478b31447f8058e786c4b044e218))
|
||||
- **lock-screen:** fix lock-screen can skip on new window ([d7b84c7](https://github.com/anncwb/vue-vben-admin/commit/d7b84c78744f7d0077a779b232e1358040b50383))
|
||||
- **markdown:** resolving markdown exceptions ([d95815b](https://github.com/anncwb/vue-vben-admin/commit/d95815b5031984e224140eb1b1d46e2dbf80abc1))
|
||||
- **markdown:** set `value` error ([35e1347](https://github.com/anncwb/vue-vben-admin/commit/35e1347029e29a83a9648b6b398e6863cc40fca9))
|
||||
- **menu:** display error when contains hidden items ([5ceeefd](https://github.com/anncwb/vue-vben-admin/commit/5ceeefd17d9ddc0e8844b900069b100f24d9c00e))
|
||||
- **menu:** fix mix-menu incorrect jumping in `hover` mode ([cad021c](https://github.com/anncwb/vue-vben-admin/commit/cad021c34b71fa109640af75a0c2b72179e9e257))
|
||||
- **menu:** make sure the menu is activated correctly ([cdb10cc](https://github.com/anncwb/vue-vben-admin/commit/cdb10cc4ac5e5e8f9cce3ff18d8fbd29ef10c86f))
|
||||
- **mix-sider:** fix mix-sider hover logic ([0595a72](https://github.com/anncwb/vue-vben-admin/commit/0595a72da9c666af81a0916663e8e6a014e6fa69))
|
||||
- **modal:** `setModalProps` support `defaultFullscreen` ([c7de65e](https://github.com/anncwb/vue-vben-admin/commit/c7de65ebba53941771153f18b184d3d4d31c0dbf))
|
||||
- **modal:** maskClosable not work ([f750ff4](https://github.com/anncwb/vue-vben-admin/commit/f750ff435fee06acee78d6b9633e6e18d91685f8))
|
||||
- **modal:** remove console log ([3dbbde2](https://github.com/anncwb/vue-vben-admin/commit/3dbbde2662352780377a9b216598d9348522f6ba))
|
||||
- **pop-confirm:** fix event working unexpected ([a6ef771](https://github.com/anncwb/vue-vben-admin/commit/a6ef771fcce14c3644c965afaa69b3a17d0a7087))
|
||||
- **popconfirm-button:** remove button excess `title` ([73654b7](https://github.com/anncwb/vue-vben-admin/commit/73654b7862c59d623d6d5dc7dcf6ff2704564d9a))
|
||||
- **sider:** bottom trigger not work ([1bde404](https://github.com/anncwb/vue-vben-admin/commit/1bde4041211229d5d9d01ce0ca806fa99356b6de)), closes [#820](https://github.com/anncwb/vue-vben-admin/issues/820)
|
||||
- **sider:** custom trigger does not take effect ([5005e6e](https://github.com/anncwb/vue-vben-admin/commit/5005e6e56b1cc7763a1cc23e1162dfb49452013b))
|
||||
- **svg-icon:** fix SvgIcon style ([99829c7](https://github.com/anncwb/vue-vben-admin/commit/99829c79ab41a2319f40c5595a7d82d9e406ba18))
|
||||
- **table:** fix index column style ([c7c0a7e](https://github.com/anncwb/vue-vben-admin/commit/c7c0a7e4c88a895000b1621981e4d4b2020c64b1))
|
||||
- **table:** auto hide unnecessary scrollbar ([735028c](https://github.com/anncwb/vue-vben-admin/commit/735028c43055e8e80ebc7344af0cd0f51c744f98))
|
||||
- **table:** editComponentProps support onChange ([829b366](https://github.com/anncwb/vue-vben-admin/commit/829b366cb2abf27e69d9665e5be022b3d3f15655))
|
||||
- **table:** event editCancel loss params ([8d22231](https://github.com/anncwb/vue-vben-admin/commit/8d22231a5fa4afed19201a4a4e5c29d674498516))
|
||||
- **table:** fix rowSelection.onChange not work ([df0f000](https://github.com/anncwb/vue-vben-admin/commit/df0f00085c1113eddd7a15954818ccece3538068)), closes [#825](https://github.com/anncwb/vue-vben-admin/issues/825)
|
||||
- **table:** fix table jitter problem ([8eba7fb](https://github.com/anncwb/vue-vben-admin/commit/8eba7fb52786d1977e4cb7b67673d74c91c5c827))
|
||||
- **table:** fix tree node align ([1e61da6](https://github.com/anncwb/vue-vben-admin/commit/1e61da644f65a79ce10fde98ee017aba7d36be10)), closes [#829](https://github.com/anncwb/vue-vben-admin/issues/829)
|
||||
- **table:** getDataSource not worked on empty data ([e78af6f](https://github.com/anncwb/vue-vben-admin/commit/e78af6f228e25f052dc4c5a1859a6db50e0b112e)), closes [#752](https://github.com/anncwb/vue-vben-admin/issues/752)
|
||||
- **table:** global configuration accidentally modified ([b4a3f93](https://github.com/anncwb/vue-vben-admin/commit/b4a3f936cd19bf1fff3a331bacad60e79d2d6c22))
|
||||
- **table:** param of `handleSearchInfoFn` ([791b323](https://github.com/anncwb/vue-vben-admin/commit/791b323dbd30acd7fabfe9c3fb6e528916311ffd))
|
||||
- **table:** recursive updateTableDataRecord ([#1024](https://github.com/anncwb/vue-vben-admin/issues/1024)) ([72f953c](https://github.com/anncwb/vue-vben-admin/commit/72f953c8d3413a7f5482793258503017a81cc759))
|
||||
- auto remove script dom in `useScript` ([a544dd3](https://github.com/anncwb/vue-vben-admin/commit/a544dd3e589329339177dad3d5c1f75dd6e6f0ca))
|
||||
- fix iframe heigth error ([#1012](https://github.com/anncwb/vue-vben-admin/issues/1012)) ([d76cfd7](https://github.com/anncwb/vue-vben-admin/commit/d76cfd7f809ba48880c950a64cb43a5c9c44176c))
|
||||
- Fix the invalid hot update of BasicButton when changing style outside ([#1016](https://github.com/anncwb/vue-vben-admin/issues/1016)) ([be2d11d](https://github.com/anncwb/vue-vben-admin/commit/be2d11d5d344a508e94abe3534726c80e1f1f271))
|
||||
- style property of actionColOpt is invalid ([#997](https://github.com/anncwb/vue-vben-admin/issues/997)) ([225bd4c](https://github.com/anncwb/vue-vben-admin/commit/225bd4c39de377d93c605f33bfdf3d8fd565f12b))
|
||||
- the position of tinymce upload image is wrong ([#1015](https://github.com/anncwb/vue-vben-admin/issues/1015)) ([2fd0fd2](https://github.com/anncwb/vue-vben-admin/commit/2fd0fd281e65d6d2551478c5f19250347dc14062))
|
||||
- **api-select:** fix `options-change` event data ([897bed9](https://github.com/anncwb/vue-vben-admin/commit/897bed97295a0b9101d33102340749689a4368de))
|
||||
- **api-tree-select:** auto load data if necessary ([1b3058f](https://github.com/anncwb/vue-vben-admin/commit/1b3058f8253effe974feaf08a12250a111ab58c0))
|
||||
- **api-tree-select:** auto reload while `params` changed ([c734f68](https://github.com/anncwb/vue-vben-admin/commit/c734f6858daea6d11cd517463b06fcce58744947))
|
||||
- **api-tree-select:** fix `event` checked in form ([d9d0071](https://github.com/anncwb/vue-vben-admin/commit/d9d00714011fa7914c61f990ce1159351ee21a1a))
|
||||
- **basic-tree:** `checkedKeys` not worked with `search` ([b06a7ab](https://github.com/anncwb/vue-vben-admin/commit/b06a7ab77b99abee63dd55770ffd55b594ee42f9)), closes [#915](https://github.com/anncwb/vue-vben-admin/issues/915)
|
||||
- **code-editor:** `value` not support use as `v-model` ([8832a07](https://github.com/anncwb/vue-vben-admin/commit/8832a074dceb44f057c87289d3a99feef58c08fd)), closes [#933](https://github.com/anncwb/vue-vben-admin/issues/933)
|
||||
- **countdown-input:** add `slots` support ([a764a95](https://github.com/anncwb/vue-vben-admin/commit/a764a95ae9a6cff831f75aa97b00724cadc48e92))
|
||||
- **dark-theme:** alert color in dark-theme ([9b7ede0](https://github.com/anncwb/vue-vben-admin/commit/9b7ede09b9efe4d5a15ab0cdeadac480a29c0f62))
|
||||
- **dark-theme:** bgcolor of `selected tree node` in dark theme ([8cf004a](https://github.com/anncwb/vue-vben-admin/commit/8cf004a5f59895e2487c3a350c83000e585b897e)), closes [#949](https://github.com/anncwb/vue-vben-admin/issues/949)
|
||||
- **dark-theme:** disabled link `button` color ([4281216](https://github.com/anncwb/vue-vben-admin/commit/42812162c46832ce4d3e332bd579c042309115bc))
|
||||
- **dark-theme:** fixed `TreeSelect` & `DatePicker` theme ([d1e0e8b](https://github.com/anncwb/vue-vben-admin/commit/d1e0e8bcea1c168631222989969e14f7d0d1b6a4)), closes [#955](https://github.com/anncwb/vue-vben-admin/issues/955)
|
||||
- **dark-theme:** style for checked tree nodes ([662b576](https://github.com/anncwb/vue-vben-admin/commit/662b576ac2088247cb58e295378f228462508a37))
|
||||
- **demo:** account page form validation ([8702965](https://github.com/anncwb/vue-vben-admin/commit/87029650570e470431fb94d35a273c5d07a73135))
|
||||
- **demo:** fix display problem of editable table with `apiSelect` ([535bddd](https://github.com/anncwb/vue-vben-admin/commit/535bdddf91785e20295c18cf80c8a22cc2172681))
|
||||
- **demo:** fix roles mock data ([c375e32](https://github.com/anncwb/vue-vben-admin/commit/c375e32305eae5128e09ad1bda39ce0cc6afd790))
|
||||
- **demo:** menu `error-log` link to 404 page ([341bd63](https://github.com/anncwb/vue-vben-admin/commit/341bd633d8ed38a5a357db8f97166c2eba2895d3))
|
||||
- **demo:** multi-modal used with dynamic component ([e1c4723](https://github.com/anncwb/vue-vben-admin/commit/e1c47233edf7675aede6d5f023726945a510ddf7))
|
||||
- **echarts:** fix graphic config cannot be used in echarts options ([#959](https://github.com/anncwb/vue-vben-admin/issues/959)) ([525484e](https://github.com/anncwb/vue-vben-admin/commit/525484e7a409b032d22231f90a92e700ef4290ae))
|
||||
- **form:** fix `validate` promise catch ([571f281](https://github.com/anncwb/vue-vben-admin/commit/571f28138f782553eb39cda2d632e5ac1aa1e145))
|
||||
- **form:** remove console error for `setFieldsValue` ([8d185bb](https://github.com/anncwb/vue-vben-admin/commit/8d185bb5841c83eb49c78e8342e65067aa6f9b80)), closes [#952](https://github.com/anncwb/vue-vben-admin/issues/952)
|
||||
- **formItem:** Fix labelcol type mismatch ([#903](https://github.com/anncwb/vue-vben-admin/issues/903)) ([03b17a8](https://github.com/anncwb/vue-vben-admin/commit/03b17a8f8bdb50322aa10e3b614bcc40b9e9dcc8))
|
||||
- **img-rotate-drag-verify:** fix `resume` method support ([32d64db](https://github.com/anncwb/vue-vben-admin/commit/32d64dbe816a0afda6ee9e91863199afb3e7b48e)), closes [#946](https://github.com/anncwb/vue-vben-admin/issues/946)
|
||||
- **login:** fix `auto fill` style in dark-theme ([cebc6a5](https://github.com/anncwb/vue-vben-admin/commit/cebc6a590e1a19af7380a55aed43b23af274df0a))
|
||||
- **modal:** ensure that props are passed correctly,fix [#897](https://github.com/anncwb/vue-vben-admin/issues/897) ([ae7821e](https://github.com/anncwb/vue-vben-admin/commit/ae7821e29690bea8934ea724bfd0ae4e2cf30c77))
|
||||
- **modal:** fixed `fullscreen` not worked ([5baaa58](https://github.com/anncwb/vue-vben-admin/commit/5baaa58581f22a915cda9fa39e4cb9f094254d3b)), closes [#918](https://github.com/anncwb/vue-vben-admin/issues/918)
|
||||
- **model:** auto validate on value change ([f844017](https://github.com/anncwb/vue-vben-admin/commit/f8440175f35076073c9f53483cf6c0164d427ff4)), closes [#920](https://github.com/anncwb/vue-vben-admin/issues/920)
|
||||
- **multiple-tab:** ignore login page ([1e63379](https://github.com/anncwb/vue-vben-admin/commit/1e63379088e1d7c823f29f607ab49d62ca22cb25))
|
||||
- **page-wrapper:** fix `class` not working ([8879ae8](https://github.com/anncwb/vue-vben-admin/commit/8879ae8d773e8dc4c252c4234eefeab9bc135a30))
|
||||
- **perm-guard:** Fix the problem that the routing query is lost after refreshing the page ([#941](https://github.com/anncwb/vue-vben-admin/issues/941)) ([9c4889f](https://github.com/anncwb/vue-vben-admin/commit/9c4889f0859bc60decf0ef40c383c1946de1d68a))
|
||||
- **qrcode:** Fix the problem that the QR code cannot be dynamically generated ([#974](https://github.com/anncwb/vue-vben-admin/issues/974)) ([fe4eae3](https://github.com/anncwb/vue-vben-admin/commit/fe4eae37146068f01ba08f033e0c2e8bd03e48b5))
|
||||
- **style:** fix checkbox-checked css in dark mode ([d3f08e3](https://github.com/anncwb/vue-vben-admin/commit/d3f08e37c5b6e46f33d525e9ef4b4c235d77a192))
|
||||
- **table:** `value` show problem in editable cell ([61ce25b](https://github.com/anncwb/vue-vben-admin/commit/61ce25be1b40d7a0e26205ca6a6757c6c43fc21e)), closes [#922](https://github.com/anncwb/vue-vben-admin/issues/922)
|
||||
- **table:** component shown in `fullscreen` mode ([a07ab6d](https://github.com/anncwb/vue-vben-admin/commit/a07ab6d7aa1060f856649a9bdbec9dfa50b14f26))
|
||||
- **table:** editable cell display with validation ([202aa42](https://github.com/anncwb/vue-vben-admin/commit/202aa42b8d5a94e84ad386bcf7feab96926c70dd)), closes [#953](https://github.com/anncwb/vue-vben-admin/issues/953)
|
||||
- **table:** fix `dataPicker` show in `fullscreen` mode ([a5a9b3f](https://github.com/anncwb/vue-vben-admin/commit/a5a9b3fb34c64b6ea9c9ab3d58045f6e5963952b))
|
||||
- **table:** fix `getSelectRows` for treeTable ([f2b8bb4](https://github.com/anncwb/vue-vben-admin/commit/f2b8bb43a0b9172b9ef9ced8e83bf91143a091d9)), closes [#1003](https://github.com/anncwb/vue-vben-admin/issues/1003)
|
||||
- **table:** fix `pagination` props working ([e327893](https://github.com/anncwb/vue-vben-admin/commit/e32789373eb5b1b531572b59692bf552dac365dc))
|
||||
- **table:** fix editable cell not support `ellipsis` ([4bb506f](https://github.com/anncwb/vue-vben-admin/commit/4bb506fb1f6ac7d246f8792d29f337ec003ff426)), closes [#944](https://github.com/anncwb/vue-vben-admin/issues/944)
|
||||
- **table:** fix expand style ([14fb21d](https://github.com/anncwb/vue-vben-admin/commit/14fb21d0b7b9ac69c7b3c463de6d709bd5713d14)), closes [#969](https://github.com/anncwb/vue-vben-admin/issues/969)
|
||||
- **table:** fix tableSettings popup in fullscreen mode ([dce3fb0](https://github.com/anncwb/vue-vben-admin/commit/dce3fb0f20516aaf4817281f5d08109e53a73ecb))
|
||||
- **tree:** fix `checkAll` effects `disabled` node ([ddd1893](https://github.com/anncwb/vue-vben-admin/commit/ddd1893b113e13786037522341abb2e75f8f9d5b))
|
||||
- ensure PAGE_NOT_FOUND_ROUTE exist ([87583c8](https://github.com/anncwb/vue-vben-admin/commit/87583c8b54d335ddf1c416859ef62bbde189c809))
|
||||
- expandIcon slot of BasicTable component is invalid ([#975](https://github.com/anncwb/vue-vben-admin/issues/975)) ([98c206d](https://github.com/anncwb/vue-vben-admin/commit/98c206d9c9661a18dde4ec7782cbe1eb6e62ebeb))
|
||||
- fix homePage affix error ([c117802](https://github.com/anncwb/vue-vben-admin/commit/c1178027f0fab2791d02efcd7c52beff5fc7dc25))
|
||||
- Fix vite profile hot update error reporting ([#968](https://github.com/anncwb/vue-vben-admin/issues/968)) ([956ed2e](https://github.com/anncwb/vue-vben-admin/commit/956ed2e3f770cc9cf822ce80f71b1e7f179792fb))
|
||||
- fixed moment locale config ([27207a7](https://github.com/anncwb/vue-vben-admin/commit/27207a78caccb04372e0275c5cee526ec460de0e))
|
||||
- infinite redirect in `BACK` mode ([4b46a84](https://github.com/anncwb/vue-vben-admin/commit/4b46a84c2b85e8da799426c54b3381ae93183db4))
|
||||
- resolving `Vue Router warn` ([237e65e](https://github.com/anncwb/vue-vben-admin/commit/237e65eac909368c4b4857da6c8deb1dc18e7684))
|
||||
- typo ([#980](https://github.com/anncwb/vue-vben-admin/issues/980)) ([7e6a89f](https://github.com/anncwb/vue-vben-admin/commit/7e6a89ffeb8c63467908d5807d3d7c4761620ee3))
|
||||
- typo for utils/env ([#1004](https://github.com/anncwb/vue-vben-admin/issues/1004)) ([e8eefd1](https://github.com/anncwb/vue-vben-admin/commit/e8eefd1bca41c181ec6395bf1d087d2018e2b1f1))
|
||||
- **table:** selection-change not triggered on row click ([6f845b5](https://github.com/anncwb/vue-vben-admin/commit/6f845b53bdc4c33fbca3e65f10f64c63166bed0e))
|
||||
- **table:** treeTable editable error ([4ae39c5](https://github.com/anncwb/vue-vben-admin/commit/4ae39c53b49532fc6c31086a31e30429d2e236ed)), closes [#811](https://github.com/anncwb/vue-vben-admin/issues/811)
|
||||
- **table-action:** fix `circle` button style ([db7254a](https://github.com/anncwb/vue-vben-admin/commit/db7254a5e0ac6d10a7ea37334ad523b150facb19))
|
||||
- **table-action:** fixed icon `margin` without label ([dc51e6a](https://github.com/anncwb/vue-vben-admin/commit/dc51e6a8d4e4f2c97b387b37959944c9bb49d779))
|
||||
- **table-action:** incorrect button color of `disabled` state ([0f28e80](https://github.com/anncwb/vue-vben-admin/commit/0f28e803d0b65537216cd9f40ad5cad63c20db9b)), closes [#891](https://github.com/anncwb/vue-vben-admin/issues/891)
|
||||
- **table-action:** stopButtonPropagation not working ([9b8f165](https://github.com/anncwb/vue-vben-admin/commit/9b8f165a365758d001e6d86ae7afe4ae3316d485))
|
||||
- **tree:** fixed `checkedKeys` with `search` mode ([f707541](https://github.com/anncwb/vue-vben-admin/commit/f707541dda78146bda89814ddccbb259d9f5d8a2))
|
||||
- **upload:** ensure the value type is correct ([05329ce](https://github.com/anncwb/vue-vben-admin/commit/05329ce9501eb899a0bbb45320e5807c83372317))
|
||||
- **useWatermark:** fix `func` call `createWatermark` call `clear` to resizeEvent removed ([#901](https://github.com/anncwb/vue-vben-admin/issues/901)) ([a1d956d](https://github.com/anncwb/vue-vben-admin/commit/a1d956d3697cd07e0ba8910768f2a73e55f18491))
|
||||
- `menuSetting` can not set collapsed to false as default ([808291b](https://github.com/anncwb/vue-vben-admin/commit/808291b503d59e3026f5f0b5e7a38b9c69bcc451))
|
||||
- ensure that safari is running properly, fix [#875](https://github.com/anncwb/vue-vben-admin/issues/875) ([dafcdd8](https://github.com/anncwb/vue-vben-admin/commit/dafcdd898caae57104f1155b0ec660ea333e7b19))
|
||||
- **table:** scrollbar style ([d8c3820](https://github.com/anncwb/vue-vben-admin/commit/d8c38207c08510d805a8dc66ffbba210e0cf4215))
|
||||
- **tailwindcss:** remove console warnings ([acacb32](https://github.com/anncwb/vue-vben-admin/commit/acacb32bb592345cd0a90b4bbeb60a9b6ab1ac3c))
|
||||
- `hasPermission` not work in `ROLE` Mode ([76a5f87](https://github.com/anncwb/vue-vben-admin/commit/76a5f87c0ce871cca48b9e4c32331353a796e7d2))
|
||||
- fix antdv console warning ([480cfb9](https://github.com/anncwb/vue-vben-admin/commit/480cfb914e78c06eb7784e33465ed91b7d4c3eee))
|
||||
- fix defHttp baseUrl work ([d5f9919](https://github.com/anncwb/vue-vben-admin/commit/d5f9919b60fdd7d5c435129e8db519c0bbd37529))
|
||||
- multi windows token sharing ([e5f3788](https://github.com/anncwb/vue-vben-admin/commit/e5f37885ffb32d04d244f0ef39ac660dda6b71e1)), closes [#761](https://github.com/anncwb/vue-vben-admin/issues/761)
|
||||
- routes filter can't effective when permission mode set to ROUTE_MAPPING ([#836](https://github.com/anncwb/vue-vben-admin/issues/836)) ([3871204](https://github.com/anncwb/vue-vben-admin/commit/3871204d08d481b8984440cd60bbf2bacb58d063))
|
||||
- support various vite modes of build, not just production ([#832](https://github.com/anncwb/vue-vben-admin/issues/832)) ([95c16a5](https://github.com/anncwb/vue-vben-admin/commit/95c16a5d26f9fd9a1d11894afe1146ca495eee93))
|
||||
- user drop-down event key loss ([20d7a25](https://github.com/anncwb/vue-vben-admin/commit/20d7a25eb898a5c28351ff269b93bf104b8ac10e))
|
||||
- user dropdown event response failure ([c73694a](https://github.com/anncwb/vue-vben-admin/commit/c73694ab8b0b6242c4d5e0f30bc7ebe3d69b4e33))
|
||||
- **upload:** make sure to carry custom parameters, fix [#802](https://github.com/anncwb/vue-vben-admin/issues/802) ([c4b22a2](https://github.com/anncwb/vue-vben-admin/commit/c4b22a225d0088d87be0c0068f543366312521db))
|
||||
- **utils:** The date function gets a non-date when the parameter is null ([#954](https://github.com/anncwb/vue-vben-admin/issues/954)) ([350c85a](https://github.com/anncwb/vue-vben-admin/commit/350c85accf5033cc5a21b71bc36d5b7a74eb2573))
|
||||
|
||||
### Features
|
||||
|
||||
- **use-loading:** add `setTip` method ([26d9476](https://github.com/anncwb/vue-vben-admin/commit/26d9476caff41cc355190604af42e0bd2ef0a353))
|
||||
- Added support for tailwindcss night mode mechanism ([#998](https://github.com/anncwb/vue-vben-admin/issues/998)) ([189bc6f](https://github.com/anncwb/vue-vben-admin/commit/189bc6feb3f2860be8c531dd1ca996f3a2cff018))
|
||||
- **api-select:** clear options before fetch ([9cf070d](https://github.com/anncwb/vue-vben-admin/commit/9cf070dd6305bb69a67ab6be85ef00bddc86fda0))
|
||||
- **api-tree-select:** add `api` options to tree-select ([d81db89](https://github.com/anncwb/vue-vben-admin/commit/d81db890dfeb533d60f378ddb86f8ac50a31252b))
|
||||
- **avatar-cropper:** add action tooltip ([6cbac4b](https://github.com/anncwb/vue-vben-admin/commit/6cbac4b7ece60a1a7c1fda931cfffce42dfe3e51))
|
||||
- **avatar-cropper:** more props added ([b96ea07](https://github.com/anncwb/vue-vben-admin/commit/b96ea0753bfd769693a368cf1e3d8316688c0dcb))
|
||||
- **axios:** add `withToken` option ([c99cf5e](https://github.com/anncwb/vue-vben-admin/commit/c99cf5e53f057cdc332ab6c0635adf9c2d27de29))
|
||||
- **axios:** use `defHttp` like `axios` ([49f39de](https://github.com/anncwb/vue-vben-admin/commit/49f39de7b40e3ec8343bdeaf3eb00fd79d395746)), closes [#850](https://github.com/anncwb/vue-vben-admin/issues/850)
|
||||
- **basic-table:** add `ApiTreeSelect` edit component ([52af1dd](https://github.com/anncwb/vue-vben-admin/commit/52af1dd0d494e66c0af20f886dcc2b983cbb096f))
|
||||
- **basic-upload:** `value` support v-model ([16c5d32](https://github.com/anncwb/vue-vben-admin/commit/16c5d327f1209f7c7437acde2ab0fa031da6a641))
|
||||
- **basic-upload:** add preview-delete event ([49e72a8](https://github.com/anncwb/vue-vben-admin/commit/49e72a8e76b78fe54e19de9e23d7c72a19427f01)), closes [#835](https://github.com/anncwb/vue-vben-admin/issues/835)
|
||||
- **demo:** add `async-validator` demo ([8b4b767](https://github.com/anncwb/vue-vben-admin/commit/8b4b767f4ca78f7c6f7586d8ba662552c2b7bb51))
|
||||
- **demo:** add basicTree with async data expand all ([5421211](https://github.com/anncwb/vue-vben-admin/commit/542121129eb5bf65f61e7b484835591756c80f04))
|
||||
- **demo:** add route multi tabs show ([0e414ba](https://github.com/anncwb/vue-vben-admin/commit/0e414ba3c10b4e47a85feb1a38cae66c815719d8)), closes [#817](https://github.com/anncwb/vue-vben-admin/issues/817)
|
||||
- **demo:** add search demo for apiSelect ([41e6d94](https://github.com/anncwb/vue-vben-admin/commit/41e6d94b3b64dc0d40b7ec57ecfaa4d966f202ae))
|
||||
- **demo:** demo default expanded tree table ([5f1a6cd](https://github.com/anncwb/vue-vben-admin/commit/5f1a6cdc599d5840df2dfebdaad029aac093cd81))
|
||||
- **demo:** multi-modal in one page usage ([7a7dab0](https://github.com/anncwb/vue-vben-admin/commit/7a7dab0c4b3602b7bd3e9381408e4168d7494c52))
|
||||
- **menu:** the route is automatically mapped to the menu ([913c22c](https://github.com/anncwb/vue-vben-admin/commit/913c22c84fc9a4221fdfff6bae0e79a68fd09b17))
|
||||
- **modal:** add `tooltip` for action buttons ([c3b9076](https://github.com/anncwb/vue-vben-admin/commit/c3b907656a5fad7a9b241562179f7a0f6fe0e6f0))
|
||||
- **notice-list:** add `pagination` support ([c16be2c](https://github.com/anncwb/vue-vben-admin/commit/c16be2c499d90126dfa35d699da9294c21a4ab48)), closes [#894](https://github.com/anncwb/vue-vben-admin/issues/894)
|
||||
- **preview:** add more features ([e23bd26](https://github.com/anncwb/vue-vben-admin/commit/e23bd2696da945291a9b652f1af39ad1936f376b))
|
||||
- customized user home page ([0a3683a](https://github.com/anncwb/vue-vben-admin/commit/0a3683a186ab55d34a12a5a3c6d794dfa1094ad4))
|
||||
- **param-menu:** feature: menu with params ([#845](https://github.com/anncwb/vue-vben-admin/issues/845)) ([48fcd76](https://github.com/anncwb/vue-vben-admin/commit/48fcd7684cabff66e8648b71527c6cb4ce7d03be))
|
||||
- **route:** add `hidePathForChildren` in `meta` ([d52b0de](https://github.com/anncwb/vue-vben-admin/commit/d52b0de83e69f7505c28e6f59ec84bbe526ecd0d))
|
||||
- **table:** add `headerTop` slot ([540423e](https://github.com/anncwb/vue-vben-admin/commit/540423ecf741a815d28d7a6baa1541ac884efe95)), closes [#881](https://github.com/anncwb/vue-vben-admin/issues/881)
|
||||
- **table:** support asynchrony in beforeFetch and afterFetch ([#827](https://github.com/anncwb/vue-vben-admin/issues/827)) ([749ba5c](https://github.com/anncwb/vue-vben-admin/commit/749ba5c1daf459625518937c239787b756c0a780))
|
||||
- **table-action:** support `tooltip` option ([5fab267](https://github.com/anncwb/vue-vben-admin/commit/5fab267a69600fdf5d7a7f9e4d9fff859d09dede)), closes [#848](https://github.com/anncwb/vue-vben-admin/issues/848)
|
||||
- **tree:** add `insertNodesByKey` method ([5a20df4](https://github.com/anncwb/vue-vben-admin/commit/5a20df45ad36b523d48bf7fe11bdb10a6d03df64))
|
||||
- add Tree LoadData demo ([9298b3c](https://github.com/anncwb/vue-vben-admin/commit/9298b3c988c10b81d83430ca31b9ce1d98a3fad9))
|
||||
- routers support `ignoreRoute` option ([72ac240](https://github.com/anncwb/vue-vben-admin/commit/72ac240f2858cd74cb62b7647ca89d63bb71d247))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
- improve legacy compatibility ([e2664f6](https://github.com/anncwb/vue-vben-admin/commit/e2664f60029f03642f8b1a6afa9b1998705fce37))
|
||||
- **menu:** Optimize the style of the bottom collapse button in the Mix menu layout ([#896](https://github.com/anncwb/vue-vben-admin/issues/896)) ([6f83070](https://github.com/anncwb/vue-vben-admin/commit/6f830703a2607c33e5d25d6d17d0e453fc2fac2e))
|
||||
- image compression configuration optimization ([cf840e3](https://github.com/anncwb/vue-vben-admin/commit/cf840e3e73b9572de0ba7bf7b32d83f6a353a8ad))
|
||||
- **icon:** remove Icon component global registration ([59d3e8c](https://github.com/anncwb/vue-vben-admin/commit/59d3e8c80f72f029f2b90432b31901ad54ed1ee4))
|
||||
- **pagewrapper:** 优化 PageWrapper 的高度自适应表现使用 getViewportOffset 替代 useContentViewHeight ([#792](https://github.com/anncwb/vue-vben-admin/issues/792)) ([4d8e398](https://github.com/anncwb/vue-vben-admin/commit/4d8e39857ea59fff99e69832b4a8cabf3a424c24))
|
||||
- **router:** reduce the number of guard files ([327d71b](https://github.com/anncwb/vue-vben-admin/commit/327d71b8fb4907ae971d040f6b84bbecb0a6d897))
|
||||
- **scrollbar:** scrollbar update when slot changed ([e9e51b2](https://github.com/anncwb/vue-vben-admin/commit/e9e51b2fdc879a66d8df08504a0955c9c21e3e27))
|
||||
|
||||
### Reverts
|
||||
|
||||
- **axios:** remove baseUrl config ([61d4efd](https://github.com/anncwb/vue-vben-admin/commit/61d4efd55a8b4f09990b5f1888e23ead43958164))
|
||||
|
||||
## [2.6.1](https://github.com/anncwb/vue-vben-admin/compare/v2.6.0...v2.6.1) (2021-07-19)
|
||||
|
||||
### Bug Fixes
|
||||
|
@@ -1,3 +1,90 @@
|
||||
## 2.7.2(2021-09-14)
|
||||
|
||||
### ✨ Features
|
||||
|
||||
- **BasicForm** 表单组件新增`Divider`,用于较长表单的区域分割
|
||||
- **BasicTable**
|
||||
- 单元格编辑新增提交回调,将根据回调函数返回的结果来决定是否将数据提交到表格
|
||||
- 行编辑添加校验方法,允许只校验而不提交值,以便异步保存数据成功后才提交倒表格
|
||||
- 修复`rowClassName`属性无法和`striped`同时使用的问题
|
||||
- 新增组件 **MarkdownViewer** 用于显示 Markdown 格式的富文本
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- **CodeEditor** 修复 JSON 编辑器在格式化无效 JSON 文本时会抛出异常的问题
|
||||
- **Tinymce** 修复 inline 模式在一些场景下会出现异常的问题
|
||||
- **BasicTable**
|
||||
- 修复可编辑单元格的内容为空时,不会显示编辑图标的问题
|
||||
- 修复表尾合计行与表格主体部分的列有时候未能对齐的问题
|
||||
- **MarkDown** 修复初始 value 属性的值不起作用的问题
|
||||
- **BasicUpload** 修复`accept`属性不支持`MIME`及点开头的后缀名的问题
|
||||
- **ApiSelect** 修复`value`属性的类型定义问题
|
||||
- **其它**
|
||||
- 修复部分封装组件在使用插槽时报错的问题
|
||||
- 修复`useECharts`的`theme`参数不起作用的问题
|
||||
- 修复`Token`失效时,按 F5 刷新页面可能会出现页面加载异常的问题
|
||||
- 修复`useRedo`的不当调用可能会导致重定向`path`异常的问题
|
||||
- 修复`vite`自定义模式名称不支持下划线的问题
|
||||
|
||||
## 2.7.1(2021-08-16)
|
||||
|
||||
- 升级 vue 3.2,如果运行失败,删除 node_modules 后重装即可
|
||||
|
||||
### ✨ Features
|
||||
|
||||
- **BasicTree** 添加搜索功能相关属性和方法
|
||||
- **BasicForm** 新增`alwaysShowLines`用于设置折叠时保留显示的行数
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- **Cropper** 修复未能及时销毁的问题
|
||||
- **BasicTable**
|
||||
- 修复`CellFormat`无法使用`Map`类型数据的问题
|
||||
- 修复可编辑单元格未能正确显示`0`值的问题
|
||||
- 修复 selection-change 事件在取消勾选时未能正确触发的问题
|
||||
- 修复浅色主题下的全屏状态背景颜色不正确的问题
|
||||
- 修复`getSelectRows`不支持远程数据跨页选择时获取完整数据的问题
|
||||
- 修复在`editComponentProps`中为编辑组件提供的`size`属性无效的问题
|
||||
- **Qrcode** 修复二维码组件在创建时未能及时绘制的问题
|
||||
- **BasicModal** 修复`helpMessage`属性不起作用的问题
|
||||
- **BasicButton** 修复按钮样式表现与 antd 官方不一致的问题
|
||||
- **其它** 修复`useRedo`(重新加载当前路由)会丢失路由`params`数据的问题
|
||||
|
||||
## 2.7.0(2021-08-03)
|
||||
|
||||
## (破坏性更新) Breaking changes
|
||||
|
||||
- 将项目`tailwindcss`还原回`windicss`,尝试了`tailwindcss`,问题可能还挺多,先切换回`windicss`提高开发效率,切换成本较低。
|
||||
- 目前项目不兼容地方有
|
||||
- `xl:!m-4` 之类的写法需要改为`!xl:m-4`,注意只有`!`这个不兼容,没用到则不用改
|
||||
- 内存溢出问题可能还在(频率低,重启下即可,重启 vite 较快)
|
||||
|
||||
### ✨ Features
|
||||
|
||||
- **Preview** 添加新的属性及事件
|
||||
- **Dark Theme** 新增对 tailwindcss 夜间模式的支持
|
||||
- **其它** 为 useLoading 添加 setTip 方法
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- **ApiTreeSelect** 修复未能正确监听`params`变化的问题
|
||||
- **ImgRotateDragVerify** 修复组件`resume`方法无法调用的问题
|
||||
- **TableAction** 修复 stopButtonPropagation 属性某些情况下不起作用的问题
|
||||
- **PageWrapper** 修复`class`属性无效的问题
|
||||
- **BasicTree** 修复`checkAll`方法会影响到`disabled`状态节点的问题
|
||||
- **BasicTable**
|
||||
- 修复可编辑单元格不支持`ellipsis`配置的问题
|
||||
- 修复全屏模式下看不到子组件弹出层(popconfirm 以及 select、treeSelect 等编辑组件)的问题
|
||||
- 修复启用`expandRowByClick`时,点击不可展开的行可能会导致样式错误的问题
|
||||
- 修复`pagination`属性动态改变不生效的问题
|
||||
- 修复`getSelectRows`不支持树形表格子级数据的问题
|
||||
- **Dark Theme** 黑暗主题下的配色问题修正
|
||||
- 修复`Tree`组件被选中节点的背景颜色
|
||||
- 修复`Alert`组件的颜色配置
|
||||
- 修复禁用状态下的`link`类型的按钮颜色问题
|
||||
- 修复`Tree`已勾选的复选框的样式问题
|
||||
- **其它** 修复 useScript 未能自动移除 script 节点的问题
|
||||
|
||||
## 2.6.1(2021-07-19)
|
||||
|
||||
### ✨ Features
|
||||
@@ -5,8 +92,10 @@
|
||||
- **NoticeList** 添加分页、超长自动省略、标题点击事件、标题删除线等功能
|
||||
- **MixSider** 优化 Mix 菜单布局时 底部折叠按钮 的样式,与其它菜单布局时的风格保持一致
|
||||
- **ApiTreeSelect** 扩展`antdv`的`TreeSelect`组件,支持远程数据源,用法类似`ApiSelect`
|
||||
- **BasicTable** 新增`ApiTreeSelect`编辑组件
|
||||
- 可以为不同的用户指定不同的后台首页:
|
||||
- **BasicTable**
|
||||
- 新增`ApiTreeSelect`编辑组件
|
||||
- 新增`headerTop`插槽
|
||||
- **其它** 可以为不同的用户指定不同的后台首页:
|
||||
- 在`getUserInfo`接口返回的用户信息中增加`homePath`字段(可选)即可为当前用户定制首页路径
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
@@ -14,7 +103,6 @@
|
||||
- **BasicTable**
|
||||
- 修复滚动条样式问题(移除了滚动样式补丁)
|
||||
- 修复树形表格的带有展开图标的单元格的内容对齐问题
|
||||
- 新增`headerTop`插槽
|
||||
- 修复操作列的按钮在 disabled 状态下的颜色显示
|
||||
- 修复可编辑单元格的值不能直接通过修改`dataSource`来更新显示的问题
|
||||
- 修复使用`ApiSelect`编辑组件时的数据回显问题
|
||||
@@ -40,7 +128,7 @@
|
||||
- **其它**
|
||||
- 修复菜单默认折叠的配置不起作用的问题
|
||||
- 修复`safari`浏览器报错导致网站打不开
|
||||
- 修复在 window 上,拉取代码后 eslint 因 endOfLine 而保错问题
|
||||
- 修复在 window 上,拉取代码后 eslint 因 endOfLine 而报错问题
|
||||
- 修复因动态路由而产生的 `Vue Router warn`
|
||||
|
||||
### 🎫 Chores
|
||||
|
@@ -150,6 +150,7 @@ yarn build
|
||||
## 后台整合示例
|
||||
|
||||
- [lamp-cloud](https://github.com/zuihou/lamp-cloud) - 基于 SpringCloud Alibaba 的微服务中后台快速开发平台
|
||||
- [matecloud](https://github.com/matevip/matecloud) - MateCloud 微服务脚手架,基于 Spring Cloud 2020.0.3、SpringBoot 2.5.3 的全开源平台
|
||||
|
||||
## 维护者
|
||||
|
||||
|
@@ -28,7 +28,7 @@ export function generateModifyVars(dark = false) {
|
||||
'success-color': '#55D187', // Success color
|
||||
'error-color': '#ED6F6F', // False color
|
||||
'warning-color': '#EFBD47', // Warning color
|
||||
'border-color-base': '#EEEEEE',
|
||||
//'border-color-base': '#EEEEEE',
|
||||
'font-size-base': '14px', // Main font size
|
||||
'border-radius-base': '2px', // Component/float fillet
|
||||
'link-color': primary, // Link color
|
||||
|
@@ -52,19 +52,19 @@ async function generateIcon() {
|
||||
const { prefix } = data;
|
||||
const isLocal = useType === 'local';
|
||||
const icons = Object.keys(data.icons).map(
|
||||
(item) => `${isLocal ? prefix + ':' : ''}${item}`
|
||||
(item) => `${isLocal ? prefix + ':' : ''}${item}`,
|
||||
);
|
||||
|
||||
await fs.writeFileSync(
|
||||
path.join(output, `icons.data.ts`),
|
||||
`export default ${isLocal ? JSON.stringify(icons) : JSON.stringify({ prefix, icons })}`
|
||||
`export default ${isLocal ? JSON.stringify(icons) : JSON.stringify({ prefix, icons })}`,
|
||||
);
|
||||
prefixSet.push(prefix);
|
||||
}
|
||||
}
|
||||
fs.emptyDir(path.join(process.cwd(), 'node_modules/.vite'));
|
||||
console.log(
|
||||
`✨ ${chalk.cyan(`[${pkg.name}]`)}` + ' - Icon generated successfully:' + `[${prefixSet}]`
|
||||
`✨ ${chalk.cyan(`[${pkg.name}]`)}` + ' - Icon generated successfully:' + `[${prefixSet}]`,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
@@ -15,7 +15,7 @@ function createConfig(
|
||||
configName,
|
||||
config,
|
||||
configFileName = GLOB_CONFIG_FILE_NAME,
|
||||
}: { configName: string; config: any; configFileName?: string } = { configName: '', config: {} }
|
||||
}: { configName: string; config: any; configFileName?: string } = { configName: '', config: {} },
|
||||
) {
|
||||
try {
|
||||
const windowConf = `window.${configName}`;
|
||||
|
@@ -11,7 +11,7 @@ export const runBuild = async () => {
|
||||
|
||||
// Generate configuration file
|
||||
if (!argvList.includes('disabled-config')) {
|
||||
await runBuildConfig();
|
||||
runBuildConfig();
|
||||
}
|
||||
|
||||
console.log(`✨ ${chalk.cyan(`[${pkg.name}]`)}` + ' - build successfully!');
|
||||
|
@@ -31,10 +31,16 @@ export function wrapperEnv(envConf: Recordable): ViteEnv {
|
||||
if (envName === 'VITE_PROXY') {
|
||||
try {
|
||||
realName = JSON.parse(realName);
|
||||
} catch (error) {}
|
||||
} catch (error) {
|
||||
realName = '';
|
||||
}
|
||||
}
|
||||
ret[envName] = realName;
|
||||
process.env[envName] = realName;
|
||||
if (typeof realName === 'string') {
|
||||
process.env[envName] = realName;
|
||||
} else if (typeof realName === 'object') {
|
||||
process.env[envName] = JSON.stringify(realName);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -44,7 +50,7 @@ export function wrapperEnv(envConf: Recordable): ViteEnv {
|
||||
*/
|
||||
function getConfFiles() {
|
||||
const script = process.env.npm_lifecycle_script;
|
||||
const reg = new RegExp('--mode ([a-z]+)');
|
||||
const reg = new RegExp('--mode ([a-z_\\d]+)');
|
||||
const result = reg.exec(script as string) as any;
|
||||
if (result) {
|
||||
const mode = result[1] as string;
|
||||
|
@@ -3,12 +3,11 @@
|
||||
* https://github.com/anncwb/vite-plugin-compression
|
||||
*/
|
||||
import type { Plugin } from 'vite';
|
||||
|
||||
import compressPlugin from 'vite-plugin-compression';
|
||||
|
||||
export function configCompressPlugin(
|
||||
compress: 'gzip' | 'brotli' | 'none',
|
||||
deleteOriginFile = false
|
||||
deleteOriginFile = false,
|
||||
): Plugin | Plugin[] {
|
||||
const compressList = compress.split(',');
|
||||
|
||||
@@ -19,16 +18,17 @@ export function configCompressPlugin(
|
||||
compressPlugin({
|
||||
ext: '.gz',
|
||||
deleteOriginFile,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
if (compressList.includes('brotli')) {
|
||||
plugins.push(
|
||||
compressPlugin({
|
||||
ext: '.br',
|
||||
algorithm: 'brotliCompress',
|
||||
deleteOriginFile,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
return plugins;
|
||||
|
@@ -3,9 +3,7 @@
|
||||
* https://github.com/anncwb/vite-plugin-html
|
||||
*/
|
||||
import type { Plugin } from 'vite';
|
||||
|
||||
import html from 'vite-plugin-html';
|
||||
|
||||
import pkg from '../../../package.json';
|
||||
import { GLOB_CONFIG_FILE_NAME } from '../../constant';
|
||||
|
||||
@@ -22,7 +20,7 @@ export function configHtmlPlugin(env: ViteEnv, isBuild: boolean) {
|
||||
minify: isBuild,
|
||||
inject: {
|
||||
// Inject data into ejs template
|
||||
injectData: {
|
||||
data: {
|
||||
title: VITE_GLOB_APP_TITLE,
|
||||
},
|
||||
// Embed the generated app.config.js file
|
||||
|
@@ -1,6 +1,5 @@
|
||||
// Image resource files used to compress the output of the production environment
|
||||
// https://github.com/anncwb/vite-plugin-imagemin
|
||||
|
||||
import viteImagemin from 'vite-plugin-imagemin';
|
||||
|
||||
export function configImageminPlugin() {
|
||||
|
@@ -1,11 +1,10 @@
|
||||
import type { Plugin } from 'vite';
|
||||
|
||||
import vue from '@vitejs/plugin-vue';
|
||||
import vueJsx from '@vitejs/plugin-vue-jsx';
|
||||
import legacy from '@vitejs/plugin-legacy';
|
||||
|
||||
import purgeIcons from 'vite-plugin-purge-icons';
|
||||
|
||||
import windiCSS from 'vite-plugin-windicss';
|
||||
import vueSetupExtend from 'vite-plugin-vue-setup-extend';
|
||||
import { configHtmlPlugin } from './html';
|
||||
import { configPwaConfig } from './pwa';
|
||||
import { configMockPlugin } from './mock';
|
||||
@@ -31,8 +30,13 @@ export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) {
|
||||
vue(),
|
||||
// have to
|
||||
vueJsx(),
|
||||
// support name
|
||||
vueSetupExtend(),
|
||||
];
|
||||
|
||||
// vite-plugin-windicss
|
||||
vitePlugins.push(windiCSS());
|
||||
|
||||
// TODO
|
||||
!isBuild && vitePlugins.push(configHmrPlugin());
|
||||
|
||||
@@ -67,7 +71,7 @@ export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) {
|
||||
|
||||
// rollup-plugin-gzip
|
||||
vitePlugins.push(
|
||||
configCompressPlugin(VITE_BUILD_COMPRESS, VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE)
|
||||
configCompressPlugin(VITE_BUILD_COMPRESS, VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE),
|
||||
);
|
||||
|
||||
// vite-plugin-pwa
|
||||
|
@@ -2,7 +2,6 @@
|
||||
* Zero-config PWA for Vite
|
||||
* https://github.com/antfu/vite-plugin-pwa
|
||||
*/
|
||||
|
||||
import { VitePWA } from 'vite-plugin-pwa';
|
||||
|
||||
export function configPwaConfig(env: ViteEnv) {
|
||||
|
@@ -2,11 +2,12 @@
|
||||
* Introduces component library styles on demand.
|
||||
* https://github.com/anncwb/vite-plugin-style-import
|
||||
*/
|
||||
|
||||
import styleImport from 'vite-plugin-style-import';
|
||||
|
||||
export function configStyleImportPlugin(isBuild: boolean) {
|
||||
if (!isBuild) return [];
|
||||
if (!isBuild) {
|
||||
return [];
|
||||
}
|
||||
const styleImportPlugin = styleImport({
|
||||
libs: [
|
||||
{
|
||||
|
@@ -33,14 +33,22 @@ export function configThemePlugin(isBuild: boolean): Plugin[] {
|
||||
return s;
|
||||
case '.ant-steps-item-icon > .ant-steps-icon':
|
||||
return s;
|
||||
case '.ant-select-item-option-selected:not(.ant-select-item-option-disabled)':
|
||||
return s;
|
||||
default:
|
||||
if (s.indexOf('.ant-btn') >= -1) {
|
||||
// 按钮被重新定制过,需要过滤掉class防止覆盖
|
||||
return s;
|
||||
}
|
||||
}
|
||||
return `[data-theme] ${s}`;
|
||||
return s.startsWith('[data-theme') ? s : `[data-theme] ${s}`;
|
||||
},
|
||||
colorVariables: [...getThemeColors(), ...colors],
|
||||
}),
|
||||
antdDarkThemePlugin({
|
||||
preloadFiles: [
|
||||
path.resolve(process.cwd(), 'node_modules/ant-design-vue/dist/antd.less'),
|
||||
//path.resolve(process.cwd(), 'node_modules/ant-design-vue/dist/antd.dark.less'),
|
||||
path.resolve(process.cwd(), 'src/design/index.less'),
|
||||
],
|
||||
filter: (id) => (isBuild ? !id.endsWith('antd.less') : true),
|
||||
@@ -48,15 +56,31 @@ export function configThemePlugin(isBuild: boolean): Plugin[] {
|
||||
darkModifyVars: {
|
||||
...generateModifyVars(true),
|
||||
'text-color': '#c9d1d9',
|
||||
'primary-1': 'rgb(255 255 255 / 8%)',
|
||||
'text-color-base': '#c9d1d9',
|
||||
'component-background': '#151515',
|
||||
'heading-color': 'rgb(255 255 255 / 65%)',
|
||||
// black: '#0e1117',
|
||||
// #8b949e
|
||||
'text-color-secondary': '#8b949e',
|
||||
'border-color-base': '#303030',
|
||||
// 'border-color-split': '#30363d',
|
||||
'item-active-bg': '#111b26',
|
||||
'app-content-background': 'rgb(255 255 255 / 4%)',
|
||||
'app-content-background': '#1e1e1e',
|
||||
'tree-node-selected-bg': '#11263c',
|
||||
|
||||
'alert-success-border-color': '#274916',
|
||||
'alert-success-bg-color': '#162312',
|
||||
'alert-success-icon-color': '#49aa19',
|
||||
'alert-info-border-color': '#153450',
|
||||
'alert-info-bg-color': '#111b26',
|
||||
'alert-info-icon-color': '#177ddc',
|
||||
'alert-warning-border-color': '#594214',
|
||||
'alert-warning-bg-color': '#2b2111',
|
||||
'alert-warning-icon-color': '#d89614',
|
||||
'alert-error-border-color': '#58181c',
|
||||
'alert-error-bg-color': '#2a1215',
|
||||
'alert-error-icon-color': '#a61d24',
|
||||
},
|
||||
}),
|
||||
];
|
||||
|
@@ -13,7 +13,7 @@ export function resultPageSuccess<T = any>(
|
||||
page: number,
|
||||
pageSize: number,
|
||||
list: T[],
|
||||
{ message = 'ok' } = {}
|
||||
{ message = 'ok' } = {},
|
||||
) {
|
||||
const pageData = pagination(page, pageSize, list);
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { MockMethod } from 'vite-plugin-mock';
|
||||
import { resultPageSuccess, resultSuccess } from '../_util';
|
||||
import { resultError, resultPageSuccess, resultSuccess } from '../_util';
|
||||
|
||||
const accountList = (() => {
|
||||
const result: any[] = [];
|
||||
@@ -28,6 +28,7 @@ const roleList = (() => {
|
||||
roleValue: '@first',
|
||||
createTime: '@datetime',
|
||||
remark: '@cword(10,20)',
|
||||
menu: [['0', '1', '2'], ['0', '1'], ['0', '2'], ['2']][index],
|
||||
'status|1': ['0', '1'],
|
||||
});
|
||||
}
|
||||
@@ -185,4 +186,17 @@ export default [
|
||||
return resultSuccess(menuList);
|
||||
},
|
||||
},
|
||||
{
|
||||
url: '/basic-api/system/accountExist',
|
||||
timeout: 500,
|
||||
method: 'post',
|
||||
response: ({ body }) => {
|
||||
const { account } = body || {};
|
||||
if (account && account.indexOf('admin') !== -1) {
|
||||
return resultError('该字段不能包含admin');
|
||||
} else {
|
||||
return resultSuccess(`${account} can use`);
|
||||
}
|
||||
},
|
||||
},
|
||||
] as MockMethod[];
|
||||
|
@@ -52,7 +52,7 @@ export default [
|
||||
response: ({ body }) => {
|
||||
const { username, password } = body;
|
||||
const checkUser = createFakeUserList().find(
|
||||
(item) => item.username === username && password === item.password
|
||||
(item) => item.username === username && password === item.password,
|
||||
);
|
||||
if (!checkUser) {
|
||||
return resultError('Incorrect account or password!');
|
||||
|
123
package.json
123
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vben-admin",
|
||||
"version": "2.6.1",
|
||||
"version": "2.7.2",
|
||||
"author": {
|
||||
"name": "vben",
|
||||
"email": "anncwb@126.com",
|
||||
@@ -34,84 +34,86 @@
|
||||
"gen:icon": "esno ./build/generate/icon/index.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@iconify/iconify": "^2.0.3",
|
||||
"@logicflow/core": "^0.6.1",
|
||||
"@logicflow/extension": "^0.6.1",
|
||||
"@vueuse/core": "^5.1.4",
|
||||
"@iconify/iconify": "^2.0.4",
|
||||
"@logicflow/core": "^0.6.16",
|
||||
"@logicflow/extension": "^0.6.16",
|
||||
"@vueuse/core": "^6.3.3",
|
||||
"@zxcvbn-ts/core": "^1.0.0-beta.0",
|
||||
"ant-design-vue": "2.2.2",
|
||||
"axios": "^0.21.1",
|
||||
"codemirror": "^5.62.0",
|
||||
"ant-design-vue": "2.2.7",
|
||||
"axios": "^0.21.4",
|
||||
"codemirror": "^5.62.3",
|
||||
"cropperjs": "^1.5.12",
|
||||
"crypto-js": "^4.0.0",
|
||||
"echarts": "^5.1.2",
|
||||
"intro.js": "^4.1.0",
|
||||
"crypto-js": "^4.1.1",
|
||||
"echarts": "^5.2.0",
|
||||
"intro.js": "^4.2.2",
|
||||
"lodash-es": "^4.17.21",
|
||||
"mockjs": "^1.1.0",
|
||||
"nprogress": "^0.2.0",
|
||||
"path-to-regexp": "^6.2.0",
|
||||
"pinia": "^2.0.0-beta.5",
|
||||
"pinia": "2.0.0-rc.9",
|
||||
"print-js": "^1.6.0",
|
||||
"qrcode": "^1.4.4",
|
||||
"resize-observer-polyfill": "^1.5.1",
|
||||
"showdown": "^1.9.1",
|
||||
"sortablejs": "^1.14.0",
|
||||
"tinymce": "^5.8.2",
|
||||
"tinymce": "^5.9.2",
|
||||
"vditor": "^3.8.6",
|
||||
"vue": "3.1.5",
|
||||
"vue-i18n": "9.1.6",
|
||||
"vue-json-pretty": "^2.0.2",
|
||||
"vue-router": "^4.0.10",
|
||||
"vue-types": "^4.0.0",
|
||||
"xlsx": "^0.17.0"
|
||||
"vue": "3.2.11",
|
||||
"vue-i18n": "9.1.7",
|
||||
"vue-json-pretty": "^2.0.4",
|
||||
"vue-router": "^4.0.11",
|
||||
"vue-types": "^4.1.0",
|
||||
"xlsx": "^0.17.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^12.1.4",
|
||||
"@commitlint/config-conventional": "^12.1.4",
|
||||
"@iconify/json": "^1.1.374",
|
||||
"@commitlint/cli": "^13.1.0",
|
||||
"@commitlint/config-conventional": "^13.1.0",
|
||||
"@iconify/json": "^1.1.401",
|
||||
"@purge-icons/generated": "^0.7.0",
|
||||
"@types/codemirror": "^5.60.2",
|
||||
"@types/crypto-js": "^4.0.2",
|
||||
"@types/fs-extra": "^9.0.12",
|
||||
"@types/inquirer": "^7.3.3",
|
||||
"@types/inquirer": "^8.1.1",
|
||||
"@types/intro.js": "^3.0.2",
|
||||
"@types/jest": "^26.0.24",
|
||||
"@types/lodash-es": "^4.17.4",
|
||||
"@types/jest": "^27.0.1",
|
||||
"@types/lodash-es": "^4.17.5",
|
||||
"@types/mockjs": "^1.0.4",
|
||||
"@types/node": "^16.3.3",
|
||||
"@types/node": "^16.9.1",
|
||||
"@types/nprogress": "^0.2.0",
|
||||
"@types/qrcode": "^1.4.1",
|
||||
"@types/qs": "^6.9.7",
|
||||
"@types/showdown": "^1.9.4",
|
||||
"@types/sortablejs": "^1.10.7",
|
||||
"@typescript-eslint/eslint-plugin": "^4.28.3",
|
||||
"@typescript-eslint/parser": "^4.28.3",
|
||||
"@vitejs/plugin-legacy": "^1.4.4",
|
||||
"@vitejs/plugin-vue": "^1.2.5",
|
||||
"@vitejs/plugin-vue-jsx": "^1.1.6",
|
||||
"@vue/compiler-sfc": "3.1.5",
|
||||
"@vue/test-utils": "^2.0.0-rc.10",
|
||||
"autoprefixer": "^10.3.1",
|
||||
"@typescript-eslint/eslint-plugin": "^4.31.0",
|
||||
"@typescript-eslint/parser": "^4.31.0",
|
||||
"@vitejs/plugin-legacy": "^1.5.3",
|
||||
"@vitejs/plugin-vue": "^1.6.2",
|
||||
"@vitejs/plugin-vue-jsx": "^1.1.8",
|
||||
"@vue/compiler-sfc": "3.2.11",
|
||||
"@vue/test-utils": "^2.0.0-rc.14",
|
||||
"autoprefixer": "^10.3.4",
|
||||
"commitizen": "^4.2.4",
|
||||
"conventional-changelog-cli": "^2.1.1",
|
||||
"cross-env": "^7.0.3",
|
||||
"dotenv": "^10.0.0",
|
||||
"eslint": "^7.31.0",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-define-config": "^1.0.9",
|
||||
"eslint-plugin-jest": "^24.3.6",
|
||||
"eslint-plugin-prettier": "^3.4.0",
|
||||
"eslint-plugin-vue": "^7.14.0",
|
||||
"esno": "^0.7.3",
|
||||
"eslint-plugin-jest": "^24.4.0",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-vue": "^7.17.0",
|
||||
"esno": "^0.9.1",
|
||||
"fs-extra": "^10.0.0",
|
||||
"http-server": "^0.12.3",
|
||||
"husky": "^7.0.1",
|
||||
"http-server": "^13.0.1",
|
||||
"husky": "^7.0.2",
|
||||
"inquirer": "^8.1.2",
|
||||
"is-ci": "^3.0.0",
|
||||
"jest": "^27.0.6",
|
||||
"jest": "^27.2.0",
|
||||
"less": "^4.1.1",
|
||||
"lint-staged": "^11.0.1",
|
||||
"lint-staged": "^11.1.2",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"postcss": "^8.3.5",
|
||||
"prettier": "^2.3.2",
|
||||
"postcss": "^8.3.6",
|
||||
"prettier": "^2.4.0",
|
||||
"pretty-quick": "^3.1.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"rollup-plugin-visualizer": "5.5.2",
|
||||
@@ -119,27 +121,28 @@
|
||||
"stylelint-config-prettier": "^8.0.2",
|
||||
"stylelint-config-standard": "^22.0.0",
|
||||
"stylelint-order": "^4.1.0",
|
||||
"tailwindcss": "^2.2.4",
|
||||
"ts-jest": "^27.0.3",
|
||||
"ts-node": "^10.1.0",
|
||||
"typescript": "4.3.5",
|
||||
"vite": "2.3.6",
|
||||
"vite-plugin-compression": "^0.3.1",
|
||||
"vite-plugin-html": "^2.0.7",
|
||||
"vite-plugin-imagemin": "^0.4.1",
|
||||
"vite-plugin-mock": "^2.9.3",
|
||||
"ts-jest": "^27.0.5",
|
||||
"ts-node": "^10.2.1",
|
||||
"typescript": "4.4.3",
|
||||
"vite": "2.5.7",
|
||||
"vite-plugin-compression": "^0.3.5",
|
||||
"vite-plugin-html": "^2.1.0",
|
||||
"vite-plugin-imagemin": "^0.4.5",
|
||||
"vite-plugin-mock": "^2.9.6",
|
||||
"vite-plugin-purge-icons": "^0.7.0",
|
||||
"vite-plugin-pwa": "^0.8.1",
|
||||
"vite-plugin-style-import": "^1.0.1",
|
||||
"vite-plugin-svg-icons": "^1.0.1",
|
||||
"vite-plugin-pwa": "^0.11.2",
|
||||
"vite-plugin-style-import": "^1.2.1",
|
||||
"vite-plugin-svg-icons": "^1.0.4",
|
||||
"vite-plugin-theme": "^0.8.1",
|
||||
"vue-eslint-parser": "^7.9.0",
|
||||
"vue-tsc": "^0.2.1"
|
||||
"vite-plugin-vue-setup-extend": "^0.1.0",
|
||||
"vite-plugin-windicss": "^1.4.2",
|
||||
"vue-eslint-parser": "^7.11.0",
|
||||
"vue-tsc": "^0.3.0"
|
||||
},
|
||||
"resolutions": {
|
||||
"//": "Used to install imagemin dependencies, because imagemin may not be installed in China. If it is abroad, you can delete it",
|
||||
"bin-wrapper": "npm:bin-wrapper-china",
|
||||
"rollup": "^2.53.2"
|
||||
"rollup": "^2.56.3"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@@ -1,6 +1,5 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
};
|
||||
|
@@ -7,8 +7,7 @@ module.exports = {
|
||||
singleQuote: true,
|
||||
quoteProps: 'as-needed',
|
||||
bracketSpacing: true,
|
||||
trailingComma: 'es5',
|
||||
jsxBracketSameLine: false,
|
||||
trailingComma: 'all',
|
||||
jsxSingleQuote: false,
|
||||
arrowParens: 'always',
|
||||
insertPragma: false,
|
||||
@@ -16,5 +15,4 @@ module.exports = {
|
||||
proseWrap: 'never',
|
||||
htmlWhitespaceSensitivity: 'strict',
|
||||
endOfLine: 'auto',
|
||||
rangeStart: 0,
|
||||
};
|
||||
|
18
src/App.vue
18
src/App.vue
@@ -6,23 +6,15 @@
|
||||
</ConfigProvider>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
<script lang="ts" setup>
|
||||
import { ConfigProvider } from 'ant-design-vue';
|
||||
import { AppProvider } from '/@/components/Application';
|
||||
import { useTitle } from '/@/hooks/web/useTitle';
|
||||
import { useLocale } from '/@/locales/useLocale';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'App',
|
||||
components: { ConfigProvider, AppProvider },
|
||||
setup() {
|
||||
useTitle();
|
||||
// support Multi-language
|
||||
const { getAntdLocale } = useLocale();
|
||||
|
||||
// support Multi-language
|
||||
const { getAntdLocale } = useLocale();
|
||||
|
||||
return { getAntdLocale };
|
||||
},
|
||||
});
|
||||
// Listening to page changes and dynamically changing site titles
|
||||
useTitle();
|
||||
</script>
|
||||
|
@@ -14,6 +14,7 @@ import { defHttp } from '/@/utils/http/axios';
|
||||
|
||||
enum Api {
|
||||
AccountList = '/system/getAccountList',
|
||||
IsAccountExist = '/system/accountExist',
|
||||
DeptList = '/system/getDeptList',
|
||||
setRoleStatus = '/system/setRoleStatus',
|
||||
MenuList = '/system/getMenuList',
|
||||
@@ -38,3 +39,6 @@ export const getAllRoleList = (params?: RoleParams) =>
|
||||
|
||||
export const setRoleStatus = (id: number, status: string) =>
|
||||
defHttp.post({ url: Api.setRoleStatus, params: { id, status } });
|
||||
|
||||
export const isAccountExist = (account: string) =>
|
||||
defHttp.post({ url: Api.IsAccountExist, params: { account } }, { errorMessageMode: 'none' });
|
||||
|
@@ -10,13 +10,13 @@ const { uploadUrl = '' } = useGlobSetting();
|
||||
*/
|
||||
export function uploadApi(
|
||||
params: UploadFileParams,
|
||||
onUploadProgress: (progressEvent: ProgressEvent) => void
|
||||
onUploadProgress: (progressEvent: ProgressEvent) => void,
|
||||
) {
|
||||
return defHttp.uploadFile<UploadApiResult>(
|
||||
{
|
||||
url: uploadUrl,
|
||||
onUploadProgress,
|
||||
},
|
||||
params
|
||||
params,
|
||||
);
|
||||
}
|
||||
|
@@ -21,7 +21,7 @@ export function loginApi(params: LoginParams, mode: ErrorMessageMode = 'modal')
|
||||
},
|
||||
{
|
||||
errorMessageMode: mode,
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ export function loginApi(params: LoginParams, mode: ErrorMessageMode = 'modal')
|
||||
* @description: getUserInfo
|
||||
*/
|
||||
export function getUserInfo() {
|
||||
return defHttp.get<GetUserInfoModel>({ url: Api.GetUserInfo });
|
||||
return defHttp.get<GetUserInfoModel>({ url: Api.GetUserInfo }, { errorMessageMode: 'none' });
|
||||
}
|
||||
|
||||
export function getPermCode() {
|
||||
|
@@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<div v-if="getShowDarkModeToggle" :class="getClass" @click="toggleDarkMode">
|
||||
<div :class="`${prefixCls}-inner`"> </div>
|
||||
<div :class="`${prefixCls}-inner`"></div>
|
||||
<SvgIcon size="14" name="sun" />
|
||||
<SvgIcon size="14" name="moon" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, computed, unref } from 'vue';
|
||||
<script lang="ts" setup>
|
||||
import { computed, unref } from 'vue';
|
||||
import { SvgIcon } from '/@/components/Icon';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
|
||||
@@ -14,39 +14,25 @@
|
||||
import { updateDarkTheme } from '/@/logics/theme/dark';
|
||||
import { ThemeEnum } from '/@/enums/appEnum';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'DarkModeToggle',
|
||||
components: { SvgIcon },
|
||||
setup() {
|
||||
const { prefixCls } = useDesign('dark-switch');
|
||||
const { getDarkMode, setDarkMode, getShowDarkModeToggle } = useRootSetting();
|
||||
const { prefixCls } = useDesign('dark-switch');
|
||||
const { getDarkMode, setDarkMode, getShowDarkModeToggle } = useRootSetting();
|
||||
|
||||
const isDark = computed(() => getDarkMode.value === ThemeEnum.DARK);
|
||||
const isDark = computed(() => getDarkMode.value === ThemeEnum.DARK);
|
||||
|
||||
const getClass = computed(() => [
|
||||
prefixCls,
|
||||
{
|
||||
[`${prefixCls}--dark`]: unref(isDark),
|
||||
},
|
||||
]);
|
||||
|
||||
function toggleDarkMode() {
|
||||
const darkMode = getDarkMode.value === ThemeEnum.DARK ? ThemeEnum.LIGHT : ThemeEnum.DARK;
|
||||
setDarkMode(darkMode);
|
||||
updateDarkTheme(darkMode);
|
||||
updateHeaderBgColor();
|
||||
updateSidebarBgColor();
|
||||
}
|
||||
|
||||
return {
|
||||
getClass,
|
||||
isDark,
|
||||
prefixCls,
|
||||
toggleDarkMode,
|
||||
getShowDarkModeToggle,
|
||||
};
|
||||
const getClass = computed(() => [
|
||||
prefixCls,
|
||||
{
|
||||
[`${prefixCls}--dark`]: unref(isDark),
|
||||
},
|
||||
});
|
||||
]);
|
||||
|
||||
function toggleDarkMode() {
|
||||
const darkMode = getDarkMode.value === ThemeEnum.DARK ? ThemeEnum.LIGHT : ThemeEnum.DARK;
|
||||
setDarkMode(darkMode);
|
||||
updateDarkTheme(darkMode);
|
||||
updateHeaderBgColor();
|
||||
updateSidebarBgColor();
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
@prefix-cls: ~'@{namespace}-dark-switch';
|
||||
|
@@ -17,16 +17,16 @@
|
||||
</span>
|
||||
</Dropdown>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
<script lang="ts" setup>
|
||||
import type { LocaleType } from '/#/config';
|
||||
import type { DropMenu } from '/@/components/Dropdown';
|
||||
import { defineComponent, ref, watchEffect, unref, computed } from 'vue';
|
||||
import { ref, watchEffect, unref, computed } from 'vue';
|
||||
import { Dropdown } from '/@/components/Dropdown';
|
||||
import { Icon } from '/@/components/Icon';
|
||||
import { useLocale } from '/@/locales/useLocale';
|
||||
import { localeList } from '/@/settings/localeSetting';
|
||||
|
||||
const props = {
|
||||
const props = defineProps({
|
||||
/**
|
||||
* Whether to display text
|
||||
*/
|
||||
@@ -35,45 +35,36 @@
|
||||
* Whether to refresh the interface when changing
|
||||
*/
|
||||
reload: { type: Boolean },
|
||||
};
|
||||
|
||||
export default defineComponent({
|
||||
name: 'AppLocalPicker',
|
||||
components: { Dropdown, Icon },
|
||||
props,
|
||||
setup(props) {
|
||||
const selectedKeys = ref<string[]>([]);
|
||||
|
||||
const { changeLocale, getLocale } = useLocale();
|
||||
|
||||
const getLocaleText = computed(() => {
|
||||
const key = selectedKeys.value[0];
|
||||
if (!key) {
|
||||
return '';
|
||||
}
|
||||
return localeList.find((item) => item.event === key)?.text;
|
||||
});
|
||||
|
||||
watchEffect(() => {
|
||||
selectedKeys.value = [unref(getLocale)];
|
||||
});
|
||||
|
||||
async function toggleLocale(lang: LocaleType | string) {
|
||||
await changeLocale(lang as LocaleType);
|
||||
selectedKeys.value = [lang as string];
|
||||
props.reload && location.reload();
|
||||
}
|
||||
|
||||
function handleMenuEvent(menu: DropMenu) {
|
||||
if (unref(getLocale) === menu.event) {
|
||||
return;
|
||||
}
|
||||
toggleLocale(menu.event as string);
|
||||
}
|
||||
|
||||
return { localeList, handleMenuEvent, selectedKeys, getLocaleText };
|
||||
},
|
||||
});
|
||||
|
||||
const selectedKeys = ref<string[]>([]);
|
||||
|
||||
const { changeLocale, getLocale } = useLocale();
|
||||
|
||||
const getLocaleText = computed(() => {
|
||||
const key = selectedKeys.value[0];
|
||||
if (!key) {
|
||||
return '';
|
||||
}
|
||||
return localeList.find((item) => item.event === key)?.text;
|
||||
});
|
||||
|
||||
watchEffect(() => {
|
||||
selectedKeys.value = [unref(getLocale)];
|
||||
});
|
||||
|
||||
async function toggleLocale(lang: LocaleType | string) {
|
||||
await changeLocale(lang as LocaleType);
|
||||
selectedKeys.value = [lang as string];
|
||||
props.reload && location.reload();
|
||||
}
|
||||
|
||||
function handleMenuEvent(menu: DropMenu) {
|
||||
if (unref(getLocale) === menu.event) {
|
||||
return;
|
||||
}
|
||||
toggleLocale(menu.event as string);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
|
@@ -10,8 +10,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, computed, unref } from 'vue';
|
||||
<script lang="ts" setup>
|
||||
import { computed, unref } from 'vue';
|
||||
import { useGlobSetting } from '/@/hooks/setting';
|
||||
import { useGo } from '/@/hooks/web/usePage';
|
||||
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
|
||||
@@ -19,11 +19,11 @@
|
||||
import { PageEnum } from '/@/enums/pageEnum';
|
||||
import { useUserStore } from '/@/store/modules/user';
|
||||
|
||||
const props = {
|
||||
const props = defineProps({
|
||||
/**
|
||||
* The theme of the current parent component
|
||||
*/
|
||||
theme: { type: String, validator: (v) => ['light', 'dark'].includes(v) },
|
||||
theme: { type: String, validator: (v: string) => ['light', 'dark'].includes(v) },
|
||||
/**
|
||||
* Whether to show title
|
||||
*/
|
||||
@@ -32,45 +32,30 @@
|
||||
* The title is also displayed when the menu is collapsed
|
||||
*/
|
||||
alwaysShowTitle: { type: Boolean },
|
||||
};
|
||||
|
||||
export default defineComponent({
|
||||
name: 'AppLogo',
|
||||
props: props,
|
||||
setup(props) {
|
||||
const { prefixCls } = useDesign('app-logo');
|
||||
const { getCollapsedShowTitle } = useMenuSetting();
|
||||
const userStore = useUserStore();
|
||||
const { title } = useGlobSetting();
|
||||
const go = useGo();
|
||||
|
||||
const getAppLogoClass = computed(() => [
|
||||
prefixCls,
|
||||
props.theme,
|
||||
{ 'collapsed-show-title': unref(getCollapsedShowTitle) },
|
||||
]);
|
||||
|
||||
const getTitleClass = computed(() => [
|
||||
`${prefixCls}__title`,
|
||||
{
|
||||
'xs:opacity-0': !props.alwaysShowTitle,
|
||||
},
|
||||
]);
|
||||
|
||||
function goHome() {
|
||||
go(userStore.getUserInfo.homePath || PageEnum.BASE_HOME);
|
||||
}
|
||||
|
||||
return {
|
||||
getAppLogoClass,
|
||||
getTitleClass,
|
||||
getCollapsedShowTitle,
|
||||
goHome,
|
||||
title,
|
||||
prefixCls,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
const { prefixCls } = useDesign('app-logo');
|
||||
const { getCollapsedShowTitle } = useMenuSetting();
|
||||
const userStore = useUserStore();
|
||||
const { title } = useGlobSetting();
|
||||
const go = useGo();
|
||||
|
||||
const getAppLogoClass = computed(() => [
|
||||
prefixCls,
|
||||
props.theme,
|
||||
{ 'collapsed-show-title': unref(getCollapsedShowTitle) },
|
||||
]);
|
||||
|
||||
const getTitleClass = computed(() => [
|
||||
`${prefixCls}__title`,
|
||||
{
|
||||
'xs:opacity-0': !props.alwaysShowTitle,
|
||||
},
|
||||
]);
|
||||
|
||||
function goHome() {
|
||||
go(userStore.getUserInfo.homePath || PageEnum.BASE_HOME);
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
@prefix-cls: ~'@{namespace}-app-logo';
|
||||
|
@@ -10,20 +10,12 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
<script lang="ts" setup>
|
||||
import AppSearchKeyItem from './AppSearchKeyItem.vue';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
export default defineComponent({
|
||||
name: 'AppSearchFooter',
|
||||
components: { AppSearchKeyItem },
|
||||
setup() {
|
||||
const { prefixCls } = useDesign('app-search-footer');
|
||||
const { t } = useI18n();
|
||||
return { prefixCls, t };
|
||||
},
|
||||
});
|
||||
const { prefixCls } = useDesign('app-search-footer');
|
||||
const { t } = useI18n();
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
@prefix-cls: ~'@{namespace}-app-search-footer';
|
||||
|
@@ -3,11 +3,9 @@
|
||||
<Icon :icon="icon" />
|
||||
</span>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
<script lang="ts" setup>
|
||||
import { Icon } from '/@/components/Icon';
|
||||
export default defineComponent({
|
||||
components: { Icon },
|
||||
props: { icon: String },
|
||||
defineProps({
|
||||
icon: String,
|
||||
});
|
||||
</script>
|
||||
|
@@ -56,85 +56,62 @@
|
||||
</transition>
|
||||
</Teleport>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, computed, unref, ref, watch, nextTick } from 'vue';
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, unref, ref, watch, nextTick } from 'vue';
|
||||
import { SearchOutlined } from '@ant-design/icons-vue';
|
||||
import AppSearchFooter from './AppSearchFooter.vue';
|
||||
import Icon from '/@/components/Icon';
|
||||
import clickOutside from '/@/directives/clickOutside';
|
||||
// @ts-ignore
|
||||
import vClickOutside from '/@/directives/clickOutside';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
import { useRefs } from '/@/hooks/core/useRefs';
|
||||
import { useMenuSearch } from './useMenuSearch';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import { useAppInject } from '/@/hooks/web/useAppInject';
|
||||
|
||||
const props = {
|
||||
const props = defineProps({
|
||||
visible: { type: Boolean },
|
||||
};
|
||||
|
||||
export default defineComponent({
|
||||
name: 'AppSearchModal',
|
||||
components: { Icon, SearchOutlined, AppSearchFooter },
|
||||
directives: {
|
||||
clickOutside,
|
||||
},
|
||||
props,
|
||||
emits: ['close'],
|
||||
setup(props, { emit }) {
|
||||
const scrollWrap = ref<ElRef>(null);
|
||||
const inputRef = ref<Nullable<HTMLElement>>(null);
|
||||
|
||||
const { t } = useI18n();
|
||||
const { prefixCls } = useDesign('app-search-modal');
|
||||
const [refs, setRefs] = useRefs();
|
||||
const { getIsMobile } = useAppInject();
|
||||
|
||||
const { handleSearch, searchResult, keyword, activeIndex, handleEnter, handleMouseenter } =
|
||||
useMenuSearch(refs, scrollWrap, emit);
|
||||
|
||||
const getIsNotData = computed(() => !keyword || unref(searchResult).length === 0);
|
||||
|
||||
const getClass = computed(() => {
|
||||
return [
|
||||
prefixCls,
|
||||
{
|
||||
[`${prefixCls}--mobile`]: unref(getIsMobile),
|
||||
},
|
||||
];
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.visible,
|
||||
(visible: boolean) => {
|
||||
visible &&
|
||||
nextTick(() => {
|
||||
unref(inputRef)?.focus();
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
function handleClose() {
|
||||
searchResult.value = [];
|
||||
emit('close');
|
||||
}
|
||||
|
||||
return {
|
||||
t,
|
||||
prefixCls,
|
||||
getClass,
|
||||
handleSearch,
|
||||
searchResult,
|
||||
activeIndex,
|
||||
getIsNotData,
|
||||
handleEnter,
|
||||
setRefs,
|
||||
scrollWrap,
|
||||
handleMouseenter,
|
||||
handleClose,
|
||||
inputRef,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['close']);
|
||||
|
||||
const scrollWrap = ref(null);
|
||||
const inputRef = ref<Nullable<HTMLElement>>(null);
|
||||
|
||||
const { t } = useI18n();
|
||||
const { prefixCls } = useDesign('app-search-modal');
|
||||
const [refs, setRefs] = useRefs();
|
||||
const { getIsMobile } = useAppInject();
|
||||
|
||||
const { handleSearch, searchResult, keyword, activeIndex, handleEnter, handleMouseenter } =
|
||||
useMenuSearch(refs, scrollWrap, emit);
|
||||
|
||||
const getIsNotData = computed(() => !keyword || unref(searchResult).length === 0);
|
||||
|
||||
const getClass = computed(() => {
|
||||
return [
|
||||
prefixCls,
|
||||
{
|
||||
[`${prefixCls}--mobile`]: unref(getIsMobile),
|
||||
},
|
||||
];
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.visible,
|
||||
(visible: boolean) => {
|
||||
visible &&
|
||||
nextTick(() => {
|
||||
unref(inputRef)?.focus();
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
function handleClose() {
|
||||
searchResult.value = [];
|
||||
emit('close');
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
@prefix-cls: ~'@{namespace}-app-search-modal';
|
||||
|
@@ -7,12 +7,12 @@
|
||||
<Icon icon="ion:chevron-forward" :style="$attrs.iconStyle" />
|
||||
</span>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, computed } from 'vue';
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue';
|
||||
import { Icon } from '/@/components/Icon';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
|
||||
const props = {
|
||||
const props = defineProps({
|
||||
/**
|
||||
* Arrow expand state
|
||||
*/
|
||||
@@ -29,31 +29,22 @@
|
||||
* Cancel padding/margin for inline
|
||||
*/
|
||||
inset: { type: Boolean },
|
||||
};
|
||||
});
|
||||
|
||||
export default defineComponent({
|
||||
name: 'BasicArrow',
|
||||
components: { Icon },
|
||||
props,
|
||||
setup(props) {
|
||||
const { prefixCls } = useDesign('basic-arrow');
|
||||
const { prefixCls } = useDesign('basic-arrow');
|
||||
|
||||
// get component class
|
||||
const getClass = computed(() => {
|
||||
const { expand, up, down, inset } = props;
|
||||
return [
|
||||
prefixCls,
|
||||
{
|
||||
[`${prefixCls}--active`]: expand,
|
||||
up,
|
||||
inset,
|
||||
down,
|
||||
},
|
||||
];
|
||||
});
|
||||
|
||||
return { getClass };
|
||||
},
|
||||
// get component class
|
||||
const getClass = computed(() => {
|
||||
const { expand, up, down, inset } = props;
|
||||
return [
|
||||
prefixCls,
|
||||
{
|
||||
[`${prefixCls}--active`]: expand,
|
||||
up,
|
||||
inset,
|
||||
down,
|
||||
},
|
||||
];
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
|
@@ -47,7 +47,7 @@
|
||||
const { prefixCls } = useDesign('basic-help');
|
||||
|
||||
const getTooltipStyle = computed(
|
||||
(): CSSProperties => ({ color: props.color, fontSize: props.fontSize })
|
||||
(): CSSProperties => ({ color: props.color, fontSize: props.fontSize }),
|
||||
);
|
||||
|
||||
const getOverlayStyle = computed((): CSSProperties => ({ maxWidth: props.maxWidth }));
|
||||
|
@@ -4,13 +4,13 @@
|
||||
<BasicHelp :class="`${prefixCls}-help`" v-if="helpMessage" :text="helpMessage" />
|
||||
</span>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
<script lang="ts" setup>
|
||||
import type { PropType } from 'vue';
|
||||
import { defineComponent, computed } from 'vue';
|
||||
import { useSlots, computed } from 'vue';
|
||||
import BasicHelp from './BasicHelp.vue';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
|
||||
const props = {
|
||||
const props = defineProps({
|
||||
/**
|
||||
* Help text list or string
|
||||
* @default: ''
|
||||
@@ -29,24 +29,15 @@
|
||||
* @default: false
|
||||
*/
|
||||
normal: { type: Boolean },
|
||||
};
|
||||
|
||||
export default defineComponent({
|
||||
name: 'BasicTitle',
|
||||
components: { BasicHelp },
|
||||
props,
|
||||
setup(props, { slots }) {
|
||||
const { prefixCls } = useDesign('basic-title');
|
||||
|
||||
const getClass = computed(() => [
|
||||
prefixCls,
|
||||
{ [`${prefixCls}-show-span`]: props.span && slots.default },
|
||||
{ [`${prefixCls}-normal`]: props.normal },
|
||||
]);
|
||||
|
||||
return { prefixCls, getClass };
|
||||
},
|
||||
});
|
||||
|
||||
const { prefixCls } = useDesign('basic-title');
|
||||
const slots = useSlots();
|
||||
const getClass = computed(() => [
|
||||
prefixCls,
|
||||
{ [`${prefixCls}-show-span`]: props.span && slots.default },
|
||||
{ [`${prefixCls}-normal`]: props.normal },
|
||||
]);
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
@prefix-cls: ~'@{namespace}-basic-title';
|
||||
|
@@ -2,39 +2,39 @@
|
||||
<Button v-bind="getBindValue" :class="getButtonClass" @click="onClick">
|
||||
<template #default="data">
|
||||
<Icon :icon="preIcon" v-if="preIcon" :size="iconSize" />
|
||||
<slot v-bind="data"></slot>
|
||||
<slot v-bind="data || {}"></slot>
|
||||
<Icon :icon="postIcon" v-if="postIcon" :size="iconSize" />
|
||||
</template>
|
||||
</Button>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, computed } from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
export default defineComponent({
|
||||
name: 'AButton',
|
||||
inheritAttrs: false,
|
||||
});
|
||||
</script>
|
||||
<script lang="ts" setup>
|
||||
import { computed, unref } from 'vue';
|
||||
import { Button } from 'ant-design-vue';
|
||||
import Icon from '/@/components/Icon/src/Icon.vue';
|
||||
import { buttonProps } from './props';
|
||||
import { useAttrs } from '/@/hooks/core/useAttrs';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'AButton',
|
||||
components: { Button, Icon },
|
||||
inheritAttrs: false,
|
||||
props: buttonProps,
|
||||
setup(props, { attrs }) {
|
||||
// get component class
|
||||
const getButtonClass = computed(() => {
|
||||
const { color, disabled } = props;
|
||||
return [
|
||||
{
|
||||
[`ant-btn-${color}`]: !!color,
|
||||
[`is-disabled`]: disabled,
|
||||
},
|
||||
attrs.class,
|
||||
];
|
||||
});
|
||||
|
||||
// get inherit binding value
|
||||
const getBindValue = computed(() => ({ ...attrs, ...props }));
|
||||
|
||||
return { getBindValue, getButtonClass };
|
||||
},
|
||||
const props = defineProps(buttonProps);
|
||||
// get component class
|
||||
const attrs = useAttrs({ excludeDefaultKeys: false });
|
||||
const getButtonClass = computed(() => {
|
||||
const { color, disabled } = props;
|
||||
return [
|
||||
{
|
||||
[`ant-btn-${color}`]: !!color,
|
||||
[`is-disabled`]: disabled,
|
||||
},
|
||||
];
|
||||
});
|
||||
|
||||
// get inherit binding value
|
||||
const getBindValue = computed(() => ({ ...unref(attrs), ...props }));
|
||||
</script>
|
||||
|
@@ -20,7 +20,6 @@
|
||||
|
||||
export default defineComponent({
|
||||
name: 'PopButton',
|
||||
components: { Popconfirm, BasicButton },
|
||||
inheritAttrs: false,
|
||||
props,
|
||||
setup(props, { slots }) {
|
||||
@@ -34,13 +33,13 @@
|
||||
okText: t('common.okText'),
|
||||
cancelText: t('common.cancelText'),
|
||||
},
|
||||
{ ...props, ...unref(attrs) }
|
||||
{ ...props, ...unref(attrs) },
|
||||
);
|
||||
});
|
||||
|
||||
return () => {
|
||||
const bindValues = omit(unref(getBindValues), 'icon');
|
||||
const btnBind = omit(bindValues, 'title');
|
||||
const btnBind = omit(bindValues, 'title') as Recordable;
|
||||
if (btnBind.disabled) btnBind.color = '';
|
||||
const Button = h(BasicButton, btnBind, extendSlots(slots));
|
||||
|
||||
|
4
src/components/CardList/index.ts
Normal file
4
src/components/CardList/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import { withInstall } from '/@/utils';
|
||||
import cardList from './src/CardList.vue';
|
||||
|
||||
export const CardList = withInstall(cardList);
|
178
src/components/CardList/src/CardList.vue
Normal file
178
src/components/CardList/src/CardList.vue
Normal file
@@ -0,0 +1,178 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<div class="bg-white mb-2 p-4">
|
||||
<BasicForm @register="registerForm" />
|
||||
</div>
|
||||
{{ sliderProp.width }}
|
||||
<div class="bg-white p-2">
|
||||
<List
|
||||
:grid="{ gutter: 5, xs: 1, sm: 2, md: 4, lg: 4, xl: 6, xxl: grid }"
|
||||
:data-source="data"
|
||||
:pagination="paginationProp"
|
||||
>
|
||||
<template #header>
|
||||
<div class="flex justify-end space-x-2"
|
||||
><slot name="header"></slot>
|
||||
<Tooltip>
|
||||
<template #title>
|
||||
<div class="w-50">每行显示数量</div
|
||||
><Slider
|
||||
id="slider"
|
||||
v-bind="sliderProp"
|
||||
v-model:value="grid"
|
||||
@change="sliderChange"
|
||||
/></template>
|
||||
<Button><TableOutlined /></Button>
|
||||
</Tooltip>
|
||||
<Tooltip @click="fetch">
|
||||
<template #title>刷新</template>
|
||||
<Button><RedoOutlined /></Button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</template>
|
||||
<template #renderItem="{ item }">
|
||||
<ListItem>
|
||||
<Card>
|
||||
<template #title></template>
|
||||
<template #cover>
|
||||
<div :class="height">
|
||||
<Image :src="item.imgs[0]" />
|
||||
</div>
|
||||
</template>
|
||||
<template class="ant-card-actions" #actions>
|
||||
<!-- <SettingOutlined key="setting" />-->
|
||||
<EditOutlined key="edit" />
|
||||
<Dropdown
|
||||
:trigger="['hover']"
|
||||
:dropMenuList="[
|
||||
{
|
||||
text: '删除',
|
||||
event: '1',
|
||||
popConfirm: {
|
||||
title: '是否确认删除',
|
||||
confirm: handleDelete.bind(null, item.id),
|
||||
},
|
||||
},
|
||||
]"
|
||||
popconfirm
|
||||
>
|
||||
<EllipsisOutlined key="ellipsis" />
|
||||
</Dropdown>
|
||||
</template>
|
||||
|
||||
<CardMeta>
|
||||
<template #title>
|
||||
<TypographyText :content="item.name" :ellipsis="{ tooltip: item.address }" />
|
||||
</template>
|
||||
<template #avatar>
|
||||
<Avatar :src="item.avatar" />
|
||||
</template>
|
||||
<template #description>{{ item.time }}</template>
|
||||
</CardMeta>
|
||||
</Card>
|
||||
</ListItem>
|
||||
</template>
|
||||
</List>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import {
|
||||
EditOutlined,
|
||||
EllipsisOutlined,
|
||||
RedoOutlined,
|
||||
TableOutlined,
|
||||
} from '@ant-design/icons-vue';
|
||||
import { List, Card, Image, Typography, Tooltip, Slider, Avatar } from 'ant-design-vue';
|
||||
import { Dropdown } from '/@/components/Dropdown';
|
||||
import { BasicForm, useForm } from '/@/components/Form';
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
import { Button } from '/@/components/Button';
|
||||
import { isFunction } from '/@/utils/is';
|
||||
import { useSlider, grid } from './data';
|
||||
const ListItem = List.Item;
|
||||
const CardMeta = Card.Meta;
|
||||
const TypographyText = Typography.Text;
|
||||
// 获取slider属性
|
||||
const sliderProp = computed(() => useSlider(4));
|
||||
// 组件接收参数
|
||||
const props = defineProps({
|
||||
// 请求API的参数
|
||||
params: propTypes.object.def({}),
|
||||
//api
|
||||
api: propTypes.func,
|
||||
});
|
||||
//暴露内部方法
|
||||
const emit = defineEmits(['getMethod', 'delete']);
|
||||
//数据
|
||||
const data = ref([]);
|
||||
// 切换每行个数
|
||||
// cover图片自适应高度
|
||||
//修改pageSize并重新请求数据
|
||||
|
||||
const height = computed(() => {
|
||||
return `h-${120 - grid.value * 6}`;
|
||||
});
|
||||
//表单
|
||||
const [registerForm, { validate }] = useForm({
|
||||
schemas: [{ field: 'type', component: 'Input', label: '类型' }],
|
||||
labelWidth: 80,
|
||||
baseColProps: { span: 6 },
|
||||
actionColOptions: { span: 24 },
|
||||
autoSubmitOnEnter: true,
|
||||
submitFunc: handleSubmit,
|
||||
});
|
||||
//表单提交
|
||||
async function handleSubmit() {
|
||||
const data = await validate();
|
||||
await fetch(data);
|
||||
}
|
||||
function sliderChange(n) {
|
||||
pageSize.value = n * 4;
|
||||
fetch();
|
||||
}
|
||||
|
||||
// 自动请求并暴露内部方法
|
||||
onMounted(() => {
|
||||
fetch();
|
||||
emit('getMethod', fetch);
|
||||
});
|
||||
|
||||
async function fetch(p = {}) {
|
||||
const { api, params } = props;
|
||||
if (api && isFunction(api)) {
|
||||
const res = await api({ ...params, page: page.value, pageSize: pageSize.value, ...p });
|
||||
data.value = res.items;
|
||||
total.value = res.total;
|
||||
}
|
||||
}
|
||||
//分页相关
|
||||
const page = ref(1);
|
||||
const pageSize = ref(36);
|
||||
const total = ref(0);
|
||||
const paginationProp = ref({
|
||||
showSizeChanger: false,
|
||||
showQuickJumper: true,
|
||||
pageSize,
|
||||
current: page,
|
||||
total,
|
||||
showTotal: (total) => `总 ${total} 条`,
|
||||
onChange: pageChange,
|
||||
onShowSizeChange: pageSizeChange,
|
||||
});
|
||||
|
||||
function pageChange(p, pz) {
|
||||
page.value = p;
|
||||
pageSize.value = pz;
|
||||
fetch();
|
||||
}
|
||||
function pageSizeChange(current, size) {
|
||||
pageSize.value = size;
|
||||
fetch();
|
||||
}
|
||||
|
||||
async function handleDelete(id) {
|
||||
emit('delete', id);
|
||||
}
|
||||
</script>
|
25
src/components/CardList/src/data.ts
Normal file
25
src/components/CardList/src/data.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { ref } from 'vue';
|
||||
//每行个数
|
||||
export const grid = ref(12);
|
||||
// slider属性
|
||||
export const useSlider = (min = 6, max = 12) => {
|
||||
// 每行显示个数滑动条
|
||||
const getMarks = () => {
|
||||
const l = {};
|
||||
for (let i = min; i < max + 1; i++) {
|
||||
l[i] = {
|
||||
style: {
|
||||
color: '#fff',
|
||||
},
|
||||
label: i,
|
||||
};
|
||||
}
|
||||
return l;
|
||||
};
|
||||
return {
|
||||
min,
|
||||
max,
|
||||
marks: getMarks(),
|
||||
step: 1,
|
||||
};
|
||||
};
|
@@ -3,24 +3,17 @@
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, onMounted } from 'vue';
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { onClickOutside } from '@vueuse/core';
|
||||
export default defineComponent({
|
||||
name: 'ClickOutSide',
|
||||
emits: ['mounted', 'clickOutside'],
|
||||
setup(_, { emit }) {
|
||||
const wrap = ref<ElRef>(null);
|
||||
const emit = defineEmits(['mounted', 'clickOutside']);
|
||||
const wrap = ref<ElRef>(null);
|
||||
|
||||
onClickOutside(wrap, () => {
|
||||
emit('clickOutside');
|
||||
});
|
||||
onClickOutside(wrap, () => {
|
||||
emit('clickOutside');
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
emit('mounted');
|
||||
});
|
||||
|
||||
return { wrap };
|
||||
},
|
||||
onMounted(() => {
|
||||
emit('mounted');
|
||||
});
|
||||
</script>
|
||||
|
@@ -8,45 +8,47 @@
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, computed } from 'vue';
|
||||
import CodeMirrorEditor from './codemirror/CodeMirror.vue';
|
||||
import { isString } from '/@/utils/is';
|
||||
|
||||
const MODE = {
|
||||
<script lang="ts">
|
||||
export const MODE = {
|
||||
JSON: 'application/json',
|
||||
html: 'htmlmixed',
|
||||
js: 'javascript',
|
||||
};
|
||||
</script>
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue';
|
||||
import CodeMirrorEditor from './codemirror/CodeMirror.vue';
|
||||
import { isString } from '/@/utils/is';
|
||||
|
||||
const props = {
|
||||
const props = defineProps({
|
||||
value: { type: [Object, String] as PropType<Record<string, any> | string> },
|
||||
mode: { type: String, default: MODE.JSON },
|
||||
readonly: { type: Boolean },
|
||||
};
|
||||
|
||||
export default defineComponent({
|
||||
name: 'CodeEditor',
|
||||
components: { CodeMirrorEditor },
|
||||
props,
|
||||
emits: ['change', 'update:value'],
|
||||
setup(props, { emit }) {
|
||||
const getValue = computed(() => {
|
||||
const { value, mode } = props;
|
||||
if (mode !== MODE.JSON) {
|
||||
return value as string;
|
||||
}
|
||||
return isString(value)
|
||||
? JSON.stringify(JSON.parse(value), null, 2)
|
||||
: JSON.stringify(value, null, 2);
|
||||
});
|
||||
|
||||
function handleValueChange(v) {
|
||||
emit('update:value', v);
|
||||
emit('change', v);
|
||||
}
|
||||
|
||||
return { handleValueChange, getValue };
|
||||
},
|
||||
autoFormat: { type: Boolean, default: true },
|
||||
});
|
||||
|
||||
const emit = defineEmits(['change', 'update:value', 'format-error']);
|
||||
|
||||
const getValue = computed(() => {
|
||||
const { value, mode, autoFormat } = props;
|
||||
if (!autoFormat || mode !== MODE.JSON) {
|
||||
return value as string;
|
||||
}
|
||||
let result = value;
|
||||
if (isString(value)) {
|
||||
try {
|
||||
result = JSON.parse(value);
|
||||
} catch (e) {
|
||||
emit('format-error', value);
|
||||
return value as string;
|
||||
}
|
||||
}
|
||||
return JSON.stringify(result, null, 2);
|
||||
});
|
||||
|
||||
function handleValueChange(v) {
|
||||
emit('update:value', v);
|
||||
emit('change', v);
|
||||
}
|
||||
</script>
|
||||
|
@@ -1,18 +1,9 @@
|
||||
<template>
|
||||
<div class="relative !h-full w-full overflow-hidden" ref="el"> </div>
|
||||
<div class="relative !h-full w-full overflow-hidden" ref="el"></div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {
|
||||
ref,
|
||||
onMounted,
|
||||
onUnmounted,
|
||||
watchEffect,
|
||||
watch,
|
||||
defineComponent,
|
||||
unref,
|
||||
nextTick,
|
||||
} from 'vue';
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, onUnmounted, watchEffect, watch, unref, nextTick } from 'vue';
|
||||
import { useDebounceFn } from '@vueuse/core';
|
||||
import { useAppStore } from '/@/store/modules/app';
|
||||
import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn';
|
||||
@@ -26,95 +17,89 @@
|
||||
import 'codemirror/mode/css/css';
|
||||
import 'codemirror/mode/htmlmixed/htmlmixed';
|
||||
|
||||
const props = {
|
||||
const props = defineProps({
|
||||
mode: { type: String, default: 'application/json' },
|
||||
value: { type: String, default: '' },
|
||||
readonly: { type: Boolean, default: false },
|
||||
};
|
||||
});
|
||||
|
||||
export default defineComponent({
|
||||
props,
|
||||
emits: ['change'],
|
||||
setup(props, { emit }) {
|
||||
const el = ref();
|
||||
let editor: Nullable<CodeMirror.Editor>;
|
||||
const emit = defineEmits(['change']);
|
||||
|
||||
const debounceRefresh = useDebounceFn(refresh, 100);
|
||||
const appStore = useAppStore();
|
||||
const el = ref();
|
||||
let editor: Nullable<CodeMirror.Editor>;
|
||||
|
||||
watch(
|
||||
() => props.value,
|
||||
async (value) => {
|
||||
await nextTick();
|
||||
const oldValue = editor?.getValue();
|
||||
if (value !== oldValue) {
|
||||
editor?.setValue(value ? value : '');
|
||||
}
|
||||
},
|
||||
{ flush: 'post' }
|
||||
);
|
||||
const debounceRefresh = useDebounceFn(refresh, 100);
|
||||
const appStore = useAppStore();
|
||||
|
||||
watchEffect(() => {
|
||||
editor?.setOption('mode', props.mode);
|
||||
});
|
||||
|
||||
watch(
|
||||
() => appStore.getDarkMode,
|
||||
async () => {
|
||||
setTheme();
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
}
|
||||
);
|
||||
|
||||
function setTheme() {
|
||||
unref(editor)?.setOption(
|
||||
'theme',
|
||||
appStore.getDarkMode === 'light' ? 'idea' : 'material-palenight'
|
||||
);
|
||||
watch(
|
||||
() => props.value,
|
||||
async (value) => {
|
||||
await nextTick();
|
||||
const oldValue = editor?.getValue();
|
||||
if (value !== oldValue) {
|
||||
editor?.setValue(value ? value : '');
|
||||
}
|
||||
|
||||
function refresh() {
|
||||
editor?.refresh();
|
||||
}
|
||||
|
||||
async function init() {
|
||||
const addonOptions = {
|
||||
autoCloseBrackets: true,
|
||||
autoCloseTags: true,
|
||||
foldGutter: true,
|
||||
gutters: ['CodeMirror-linenumbers'],
|
||||
};
|
||||
|
||||
editor = CodeMirror(el.value!, {
|
||||
value: '',
|
||||
mode: props.mode,
|
||||
readOnly: props.readonly,
|
||||
tabSize: 2,
|
||||
theme: 'material-palenight',
|
||||
lineWrapping: true,
|
||||
lineNumbers: true,
|
||||
...addonOptions,
|
||||
});
|
||||
editor?.setValue(props.value);
|
||||
setTheme();
|
||||
editor?.on('change', () => {
|
||||
emit('change', editor?.getValue());
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await nextTick();
|
||||
init();
|
||||
useWindowSizeFn(debounceRefresh);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
editor = null;
|
||||
});
|
||||
|
||||
return { el };
|
||||
},
|
||||
{ flush: 'post' },
|
||||
);
|
||||
|
||||
watchEffect(() => {
|
||||
editor?.setOption('mode', props.mode);
|
||||
});
|
||||
|
||||
watch(
|
||||
() => appStore.getDarkMode,
|
||||
async () => {
|
||||
setTheme();
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
},
|
||||
);
|
||||
|
||||
function setTheme() {
|
||||
unref(editor)?.setOption(
|
||||
'theme',
|
||||
appStore.getDarkMode === 'light' ? 'idea' : 'material-palenight',
|
||||
);
|
||||
}
|
||||
|
||||
function refresh() {
|
||||
editor?.refresh();
|
||||
}
|
||||
|
||||
async function init() {
|
||||
const addonOptions = {
|
||||
autoCloseBrackets: true,
|
||||
autoCloseTags: true,
|
||||
foldGutter: true,
|
||||
gutters: ['CodeMirror-linenumbers'],
|
||||
};
|
||||
|
||||
editor = CodeMirror(el.value!, {
|
||||
value: '',
|
||||
mode: props.mode,
|
||||
readOnly: props.readonly,
|
||||
tabSize: 2,
|
||||
theme: 'material-palenight',
|
||||
lineWrapping: true,
|
||||
lineNumbers: true,
|
||||
...addonOptions,
|
||||
});
|
||||
editor?.setValue(props.value);
|
||||
setTheme();
|
||||
editor?.on('change', () => {
|
||||
emit('change', editor?.getValue());
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await nextTick();
|
||||
init();
|
||||
useWindowSizeFn(debounceRefresh);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
editor = null;
|
||||
});
|
||||
</script>
|
||||
|
@@ -2,13 +2,11 @@
|
||||
<vue-json-pretty :path="'res'" :deep="3" :showLength="true" :data="data" />
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
<script lang="ts" setup>
|
||||
import VueJsonPretty from 'vue-json-pretty';
|
||||
import 'vue-json-pretty/lib/styles.css';
|
||||
import { defineComponent } from 'vue';
|
||||
export default defineComponent({
|
||||
name: 'JsonPreview',
|
||||
components: { VueJsonPretty },
|
||||
props: { data: Object },
|
||||
|
||||
defineProps({
|
||||
data: Object,
|
||||
});
|
||||
</script>
|
||||
|
@@ -54,7 +54,7 @@
|
||||
return;
|
||||
}
|
||||
nextTick(() => {
|
||||
const wrap = unref(scrollbar.wrap);
|
||||
const wrap = unref(scrollbar.wrap) as any;
|
||||
if (!wrap) {
|
||||
return;
|
||||
}
|
||||
|
@@ -22,9 +22,9 @@
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
<script lang="ts" setup>
|
||||
import type { PropType } from 'vue';
|
||||
import { defineComponent, ref } from 'vue';
|
||||
import { ref } from 'vue';
|
||||
// component
|
||||
import { Skeleton } from 'ant-design-vue';
|
||||
import { CollapseTransition } from '/@/components/Transition';
|
||||
@@ -34,7 +34,7 @@
|
||||
import { useTimeoutFn } from '/@/hooks/core/useTimeout';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
|
||||
const props = {
|
||||
const props = defineProps({
|
||||
title: { type: String, default: '' },
|
||||
loading: { type: Boolean },
|
||||
/**
|
||||
@@ -57,39 +57,22 @@
|
||||
* Delayed loading time
|
||||
*/
|
||||
lazyTime: { type: Number, default: 0 },
|
||||
};
|
||||
|
||||
export default defineComponent({
|
||||
name: 'CollapseContainer',
|
||||
components: {
|
||||
Skeleton,
|
||||
CollapseHeader,
|
||||
CollapseTransition,
|
||||
},
|
||||
props,
|
||||
setup(props) {
|
||||
const show = ref(true);
|
||||
|
||||
const { prefixCls } = useDesign('collapse-container');
|
||||
|
||||
/**
|
||||
* @description: Handling development events
|
||||
*/
|
||||
function handleExpand() {
|
||||
show.value = !show.value;
|
||||
if (props.triggerWindowResize) {
|
||||
// 200 milliseconds here is because the expansion has animation,
|
||||
useTimeoutFn(triggerWindowResize, 200);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
show,
|
||||
handleExpand,
|
||||
prefixCls,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
const show = ref(true);
|
||||
|
||||
const { prefixCls } = useDesign('collapse-container');
|
||||
|
||||
/**
|
||||
* @description: Handling development events
|
||||
*/
|
||||
function handleExpand() {
|
||||
show.value = !show.value;
|
||||
if (props.triggerWindowResize) {
|
||||
// 200 milliseconds here is because the expansion has animation,
|
||||
useTimeoutFn(triggerWindowResize, 200);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less">
|
||||
@prefix-cls: ~'@{namespace}-collapse-container';
|
||||
|
@@ -46,7 +46,7 @@
|
||||
name: 'ContextMenu',
|
||||
props,
|
||||
setup(props) {
|
||||
const wrapRef = ref<ElRef>(null);
|
||||
const wrapRef = ref(null);
|
||||
const showRef = ref(false);
|
||||
|
||||
const getStyle = computed((): CSSProperties => {
|
||||
|
@@ -4,7 +4,7 @@
|
||||
<CountButton :size="size" :count="count" :value="state" :beforeStartFunc="sendCodeApi" />
|
||||
</template>
|
||||
<template #[item]="data" v-for="item in Object.keys($slots).filter((k) => k !== 'addonAfter')">
|
||||
<slot :name="item" v-bind="data"></slot>
|
||||
<slot :name="item" v-bind="data || {}"></slot>
|
||||
</template>
|
||||
</a-input>
|
||||
</template>
|
||||
|
@@ -122,15 +122,17 @@
|
||||
import { isFunction } from '/@/utils/is';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
|
||||
type apiFunParams = { file: Blob; name: string; filename: string };
|
||||
|
||||
const props = {
|
||||
circled: { type: Boolean, default: true },
|
||||
uploadApi: {
|
||||
type: Function as PropType<({ file: Blob, name: string, filename: string }) => Promise<any>>,
|
||||
type: Function as PropType<(params: apiFunParams) => Promise<any>>,
|
||||
},
|
||||
};
|
||||
|
||||
export default defineComponent({
|
||||
name: 'CropperAvatar',
|
||||
name: 'CropperModal',
|
||||
components: { BasicModal, Space, CropperImage, Upload, Avatar, Tooltip },
|
||||
props,
|
||||
emits: ['uploadSuccess', 'register'],
|
||||
|
@@ -12,7 +12,7 @@
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import type { CSSProperties } from 'vue';
|
||||
import { defineComponent, onMounted, ref, unref, computed } from 'vue';
|
||||
import { defineComponent, onMounted, ref, unref, computed, onUnmounted } from 'vue';
|
||||
import Cropper from 'cropperjs';
|
||||
import 'cropperjs/dist/cropper.css';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
@@ -93,6 +93,10 @@
|
||||
|
||||
onMounted(init);
|
||||
|
||||
onUnmounted(() => {
|
||||
cropper.value?.destroy();
|
||||
});
|
||||
|
||||
async function init() {
|
||||
const imgEl = unref(imgElRef);
|
||||
if (!imgEl) {
|
||||
|
@@ -77,7 +77,7 @@
|
||||
const getStyle = computed((): CSSProperties => ({ width: unref(getWidth) }));
|
||||
|
||||
const getImageWrapperStyle = computed(
|
||||
(): CSSProperties => ({ width: unref(getWidth), height: unref(getWidth) })
|
||||
(): CSSProperties => ({ width: unref(getWidth), height: unref(getWidth) }),
|
||||
);
|
||||
|
||||
watchEffect(() => {
|
||||
@@ -88,7 +88,7 @@
|
||||
() => sourceValue.value,
|
||||
(v: string) => {
|
||||
emit('update:value', v);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
function handleUploadSuccess({ source }) {
|
||||
@@ -103,7 +103,7 @@
|
||||
t,
|
||||
prefixCls,
|
||||
register,
|
||||
openModal,
|
||||
openModal: openModal as any,
|
||||
getIconWidth,
|
||||
sourceValue,
|
||||
getClass,
|
||||
|
@@ -14,7 +14,7 @@ export interface DescItem {
|
||||
// render
|
||||
render?: (
|
||||
val: any,
|
||||
data: Recordable
|
||||
data: Recordable,
|
||||
) => VNode | undefined | JSX.Element | Element | string | number;
|
||||
}
|
||||
|
||||
|
@@ -25,7 +25,7 @@
|
||||
</ScrollContainer>
|
||||
<DrawerFooter v-bind="getProps" @close="onClose" @ok="handleOk" :height="getFooterHeight">
|
||||
<template #[item]="data" v-for="item in Object.keys($slots)">
|
||||
<slot :name="item" v-bind="data"></slot>
|
||||
<slot :name="item" v-bind="data || {}"></slot>
|
||||
</template>
|
||||
</DrawerFooter>
|
||||
</Drawer>
|
||||
@@ -139,7 +139,7 @@
|
||||
(newVal, oldVal) => {
|
||||
if (newVal !== oldVal) visibleRef.value = newVal;
|
||||
},
|
||||
{ deep: true }
|
||||
{ deep: true },
|
||||
);
|
||||
|
||||
watch(
|
||||
@@ -149,7 +149,7 @@
|
||||
emit('visible-change', visible);
|
||||
instance && drawerInstance.emitVisible?.(visible, instance.uid);
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// Cancel event
|
||||
@@ -181,9 +181,9 @@
|
||||
onClose,
|
||||
t,
|
||||
prefixCls,
|
||||
getMergeProps,
|
||||
getMergeProps: getMergeProps as any,
|
||||
getScrollContentStyle,
|
||||
getProps,
|
||||
getProps: getProps as any,
|
||||
getLoading,
|
||||
getBindValues,
|
||||
getFooterHeight,
|
||||
|
@@ -8,6 +8,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import type { Ref } from 'vue';
|
||||
import type { Definition } from '@logicflow/core';
|
||||
import { defineComponent, ref, onMounted, unref, nextTick, computed, watch } from 'vue';
|
||||
import FlowChartToolbar from './FlowChartToolbar.vue';
|
||||
@@ -46,10 +47,10 @@
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const lfElRef = ref<ElRef>(null);
|
||||
const graphData = ref<Recordable>({});
|
||||
const lfElRef = ref(null);
|
||||
const graphData = ref({});
|
||||
|
||||
const lfInstance = ref<Nullable<LogicFlow>>(null);
|
||||
const lfInstance = ref(null) as Ref<LogicFlow | null>;
|
||||
|
||||
const { prefixCls } = useDesign('flow-chart');
|
||||
const appStore = useAppStore();
|
||||
@@ -78,7 +79,7 @@
|
||||
() => props.data,
|
||||
() => {
|
||||
onRender();
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// TODO
|
||||
@@ -93,7 +94,7 @@
|
||||
() => unref(getFlowOptions),
|
||||
(options) => {
|
||||
unref(lfInstance)?.updateEditConfig(options);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// init logicFlow
|
||||
|
@@ -19,17 +19,17 @@
|
||||
:setFormModel="setFormModel"
|
||||
>
|
||||
<template #[item]="data" v-for="item in Object.keys($slots)">
|
||||
<slot :name="item" v-bind="data"></slot>
|
||||
<slot :name="item" v-bind="data || {}"></slot>
|
||||
</template>
|
||||
</FormItem>
|
||||
</template>
|
||||
|
||||
<FormAction v-bind="{ ...getProps, ...advanceState }" @toggle-advanced="handleToggleAdvanced">
|
||||
<FormAction v-bind="getFormActionBindProps" @toggle-advanced="handleToggleAdvanced">
|
||||
<template
|
||||
#[item]="data"
|
||||
v-for="item in ['resetBefore', 'submitBefore', 'advanceBefore', 'advanceAfter']"
|
||||
>
|
||||
<slot :name="item" v-bind="data"></slot>
|
||||
<slot :name="item" v-bind="data || {}"></slot>
|
||||
</template>
|
||||
</FormAction>
|
||||
<slot name="formFooter"></slot>
|
||||
@@ -62,8 +62,6 @@
|
||||
import { basicProps } from './props';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
|
||||
import type { RowProps } from 'ant-design-vue/lib/grid/Row';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'BasicForm',
|
||||
components: { FormItem, Form, Row, FormAction },
|
||||
@@ -103,7 +101,7 @@
|
||||
});
|
||||
|
||||
// Get uniform row style and Row configuration for the entire form
|
||||
const getRow = computed((): RowProps => {
|
||||
const getRow = computed((): Recordable => {
|
||||
const { baseRowStyle = {}, rowProps } = unref(getProps);
|
||||
return {
|
||||
style: baseRowStyle,
|
||||
@@ -112,7 +110,7 @@
|
||||
});
|
||||
|
||||
const getBindValue = computed(
|
||||
() => ({ ...attrs, ...props, ...unref(getProps) } as Recordable)
|
||||
() => ({ ...attrs, ...props, ...unref(getProps) } as Recordable),
|
||||
);
|
||||
|
||||
const getSchema = computed((): FormSchema[] => {
|
||||
@@ -132,7 +130,11 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
return schemas as FormSchema[];
|
||||
if (unref(getProps).showAdvancedButton) {
|
||||
return schemas.filter((schema) => schema.component !== 'Divider') as FormSchema[];
|
||||
} else {
|
||||
return schemas as FormSchema[];
|
||||
}
|
||||
});
|
||||
|
||||
const { handleToggleAdvanced } = useAdvanced({
|
||||
@@ -196,14 +198,14 @@
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
watch(
|
||||
() => unref(getProps).schemas,
|
||||
(schemas) => {
|
||||
resetSchema(schemas ?? []);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
watch(
|
||||
@@ -220,7 +222,7 @@
|
||||
initDefault();
|
||||
isInitedDefaultRef.value = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
async function setProps(formProps: Partial<FormProps>): Promise<void> {
|
||||
@@ -231,9 +233,7 @@
|
||||
formModel[key] = value;
|
||||
const { validateTrigger } = unref(getBindValue);
|
||||
if (!validateTrigger || validateTrigger === 'change') {
|
||||
try {
|
||||
validateFields([key]);
|
||||
} catch (e) {}
|
||||
validateFields([key]).catch((_) => {});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,10 +280,12 @@
|
||||
getProps,
|
||||
formElRef,
|
||||
getSchema,
|
||||
formActionType,
|
||||
formActionType: formActionType as any,
|
||||
setFormModel,
|
||||
prefixCls,
|
||||
getFormClass,
|
||||
getFormActionBindProps: computed(
|
||||
(): Recordable => ({ ...getProps.value, ...advanceState }),
|
||||
),
|
||||
...formActionType,
|
||||
};
|
||||
},
|
||||
|
@@ -18,6 +18,7 @@ import {
|
||||
TreeSelect,
|
||||
Slider,
|
||||
Rate,
|
||||
Divider,
|
||||
} from 'ant-design-vue';
|
||||
|
||||
import RadioButtonGroup from './components/RadioButtonGroup.vue';
|
||||
@@ -61,6 +62,7 @@ componentMap.set('IconPicker', IconPicker);
|
||||
componentMap.set('InputCountDown', CountdownInput);
|
||||
|
||||
componentMap.set('Upload', BasicUpload);
|
||||
componentMap.set('Divider', Divider);
|
||||
|
||||
export function add(compName: ComponentType, component: Component) {
|
||||
componentMap.set(compName, component);
|
||||
|
@@ -1,13 +1,13 @@
|
||||
<template>
|
||||
<Select
|
||||
@dropdownVisibleChange="handleFetch"
|
||||
v-bind="attrs"
|
||||
v-bind="$attrs"
|
||||
@change="handleChange"
|
||||
:options="getOptions"
|
||||
v-model:value="state"
|
||||
>
|
||||
<template #[item]="data" v-for="item in Object.keys($slots)">
|
||||
<slot :name="item" v-bind="data"></slot>
|
||||
<slot :name="item" v-bind="data || {}"></slot>
|
||||
</template>
|
||||
<template #suffixIcon v-if="loading">
|
||||
<LoadingOutlined spin />
|
||||
@@ -41,12 +41,7 @@
|
||||
},
|
||||
inheritAttrs: false,
|
||||
props: {
|
||||
value: propTypes.oneOfType([
|
||||
propTypes.object,
|
||||
propTypes.number,
|
||||
propTypes.string,
|
||||
propTypes.array,
|
||||
]),
|
||||
value: [Array, Object, String, Number],
|
||||
numberToString: propTypes.bool,
|
||||
api: {
|
||||
type: Function as PropType<(arg?: Recordable) => Promise<OptionsItem[]>>,
|
||||
@@ -100,7 +95,7 @@
|
||||
() => {
|
||||
!unref(isFirstLoad) && fetch();
|
||||
},
|
||||
{ deep: true }
|
||||
{ deep: true },
|
||||
);
|
||||
|
||||
async function fetch() {
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<a-tree-select v-bind="getAttrs" @change="handleChange">
|
||||
<template #[item]="data" v-for="item in Object.keys($slots)">
|
||||
<slot :name="item" v-bind="data"></slot>
|
||||
<slot :name="item" v-bind="data || {}"></slot>
|
||||
</template>
|
||||
<template #suffixIcon v-if="loading">
|
||||
<LoadingOutlined spin />
|
||||
@@ -45,14 +45,15 @@
|
||||
() => props.params,
|
||||
() => {
|
||||
isFirstLoaded.value && fetch();
|
||||
}
|
||||
},
|
||||
{ deep: true },
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.immediate,
|
||||
(v) => {
|
||||
v && !isFirstLoaded.value && fetch();
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<a-col v-bind="actionColOpt" :style="{ textAlign: 'right' }" v-if="showActionButtonGroup">
|
||||
<div style="width: 100%; text-align: right">
|
||||
<a-col v-bind="actionColOpt" v-if="showActionButtonGroup">
|
||||
<div style="width: 100%" :style="{ textAlign: actionColOpt.style.textAlign }">
|
||||
<FormItem>
|
||||
<slot name="resetBefore"></slot>
|
||||
<Button
|
||||
@@ -92,6 +92,7 @@
|
||||
? { span: actionSpan < 6 ? 24 : actionSpan }
|
||||
: {};
|
||||
const actionColOpt: Partial<ColEx> = {
|
||||
style: { textAlign: 'right' },
|
||||
span: showAdvancedButton ? 6 : 4,
|
||||
...advancedSpanObj,
|
||||
...actionColOptions,
|
||||
@@ -104,7 +105,7 @@
|
||||
{
|
||||
text: t('common.resetText'),
|
||||
},
|
||||
props.resetButtonOptions
|
||||
props.resetButtonOptions,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -113,7 +114,7 @@
|
||||
{
|
||||
text: t('common.queryText'),
|
||||
},
|
||||
props.submitButtonOptions
|
||||
props.submitButtonOptions,
|
||||
);
|
||||
});
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
import type { ValidationRule } from 'ant-design-vue/lib/form/Form';
|
||||
import type { TableActionType } from '/@/components/Table';
|
||||
import { defineComponent, computed, unref, toRefs } from 'vue';
|
||||
import { Form, Col } from 'ant-design-vue';
|
||||
import { Form, Col, Divider } from 'ant-design-vue';
|
||||
import { componentMap } from '../componentMap';
|
||||
import { BasicHelp } from '/@/components/Basic';
|
||||
import { isBoolean, isFunction, isNull } from '/@/utils/is';
|
||||
@@ -73,11 +73,17 @@
|
||||
|
||||
const getComponentsProps = computed(() => {
|
||||
const { schema, tableAction, formModel, formActionType } = props;
|
||||
const { componentProps = {} } = schema;
|
||||
if (!isFunction(componentProps)) {
|
||||
return componentProps;
|
||||
let { componentProps = {} } = schema;
|
||||
if (isFunction(componentProps)) {
|
||||
componentProps = componentProps({ schema, tableAction, formModel, formActionType }) ?? {};
|
||||
}
|
||||
return componentProps({ schema, tableAction, formModel, formActionType }) ?? {};
|
||||
if (schema.component === 'Divider') {
|
||||
componentProps = Object.assign({ type: 'horizontal' }, componentProps, {
|
||||
orientation: 'left',
|
||||
plain: true,
|
||||
});
|
||||
}
|
||||
return componentProps as Recordable;
|
||||
});
|
||||
|
||||
const getDisable = computed(() => {
|
||||
@@ -177,7 +183,7 @@
|
||||
}
|
||||
|
||||
const requiredRuleIndex: number = rules.findIndex(
|
||||
(rule) => Reflect.has(rule, 'required') && !Reflect.has(rule, 'validator')
|
||||
(rule) => Reflect.has(rule, 'required') && !Reflect.has(rule, 'validator'),
|
||||
);
|
||||
|
||||
if (requiredRuleIndex !== -1) {
|
||||
@@ -300,38 +306,46 @@
|
||||
}
|
||||
|
||||
function renderItem() {
|
||||
const { itemProps, slot, render, field, suffix } = props.schema;
|
||||
const { itemProps, slot, render, field, suffix, component } = props.schema;
|
||||
const { labelCol, wrapperCol } = unref(itemLabelWidthProp);
|
||||
const { colon } = props.formProps;
|
||||
|
||||
const getContent = () => {
|
||||
return slot
|
||||
? getSlot(slots, slot, unref(getValues))
|
||||
: render
|
||||
? render(unref(getValues))
|
||||
: renderComponent();
|
||||
};
|
||||
if (component === 'Divider') {
|
||||
return (
|
||||
<Col span={24}>
|
||||
<Divider {...unref(getComponentsProps)}>{renderLabelHelpMessage()}</Divider>
|
||||
</Col>
|
||||
);
|
||||
} else {
|
||||
const getContent = () => {
|
||||
return slot
|
||||
? getSlot(slots, slot, unref(getValues))
|
||||
: render
|
||||
? render(unref(getValues))
|
||||
: renderComponent();
|
||||
};
|
||||
|
||||
const showSuffix = !!suffix;
|
||||
const getSuffix = isFunction(suffix) ? suffix(unref(getValues)) : suffix;
|
||||
const showSuffix = !!suffix;
|
||||
const getSuffix = isFunction(suffix) ? suffix(unref(getValues)) : suffix;
|
||||
|
||||
return (
|
||||
<Form.Item
|
||||
name={field}
|
||||
colon={colon}
|
||||
class={{ 'suffix-item': showSuffix }}
|
||||
{...(itemProps as Recordable)}
|
||||
label={renderLabelHelpMessage()}
|
||||
rules={handleRules()}
|
||||
labelCol={labelCol}
|
||||
wrapperCol={wrapperCol}
|
||||
>
|
||||
<div style="display:flex">
|
||||
<div style="flex:1">{getContent()}</div>
|
||||
{showSuffix && <span class="suffix">{getSuffix}</span>}
|
||||
</div>
|
||||
</Form.Item>
|
||||
);
|
||||
return (
|
||||
<Form.Item
|
||||
name={field}
|
||||
colon={colon}
|
||||
class={{ 'suffix-item': showSuffix }}
|
||||
{...(itemProps as Recordable)}
|
||||
label={renderLabelHelpMessage()}
|
||||
rules={handleRules()}
|
||||
labelCol={labelCol}
|
||||
wrapperCol={wrapperCol}
|
||||
>
|
||||
<div style="display:flex">
|
||||
<div style="flex:1">{getContent()}</div>
|
||||
{showSuffix && <span class="suffix">{getSuffix}</span>}
|
||||
</div>
|
||||
</Form.Item>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return () => {
|
||||
|
@@ -38,7 +38,7 @@ function genType() {
|
||||
export function setComponentRuleType(
|
||||
rule: ValidationRule,
|
||||
component: ComponentType,
|
||||
valueFormat: string
|
||||
valueFormat: string,
|
||||
) {
|
||||
if (['DatePicker', 'MonthPicker', 'WeekPicker', 'TimePicker'].includes(component)) {
|
||||
rule.type = valueFormat ? 'string' : 'object';
|
||||
|
@@ -58,7 +58,7 @@ export default function ({
|
||||
debounceUpdateAdvanced();
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
function getAdvanced(itemCol: Partial<ColEx>, itemColSum = 0, isLastAction = false) {
|
||||
@@ -103,7 +103,7 @@ export default function ({
|
||||
}
|
||||
return { isAdvanced: advanceState.isAdvanced, itemColSum };
|
||||
}
|
||||
if (itemColSum > BASIC_COL_LEN) {
|
||||
if (itemColSum > BASIC_COL_LEN * (unref(getProps).alwaysShowLines || 1)) {
|
||||
return { isAdvanced: advanceState.isAdvanced, itemColSum };
|
||||
} else {
|
||||
// The first line is always displayed
|
||||
@@ -139,7 +139,7 @@ export default function ({
|
||||
if (isShow && (colProps || baseColProps)) {
|
||||
const { itemColSum: sum, isAdvanced } = getAdvanced(
|
||||
{ ...baseColProps, ...colProps },
|
||||
itemColSum
|
||||
itemColSum,
|
||||
);
|
||||
|
||||
itemColSum = sum || 0;
|
||||
|
@@ -18,7 +18,7 @@ export function useForm(props?: Props): UseFormReturnType {
|
||||
const form = unref(formRef);
|
||||
if (!form) {
|
||||
error(
|
||||
'The form instance has not been obtained, please make sure that the form has been rendered when performing the form operation!'
|
||||
'The form instance has not been obtained, please make sure that the form has been rendered when performing the form operation!',
|
||||
);
|
||||
}
|
||||
await nextTick();
|
||||
@@ -44,7 +44,7 @@ export function useForm(props?: Props): UseFormReturnType {
|
||||
{
|
||||
immediate: true,
|
||||
deep: true,
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ export function useForm(props?: Props): UseFormReturnType {
|
||||
appendSchemaByField: async (
|
||||
schema: FormSchema,
|
||||
prefixField: string | undefined,
|
||||
first: boolean
|
||||
first: boolean,
|
||||
) => {
|
||||
const form = await getForm();
|
||||
form.appendSchemaByField(schema, prefixField, first);
|
||||
|
@@ -84,7 +84,7 @@ export function useFormEvents({
|
||||
validKeys.push(key);
|
||||
}
|
||||
});
|
||||
validateFields(validKeys);
|
||||
validateFields(validKeys).catch((_) => {});
|
||||
}
|
||||
/**
|
||||
* @description: Delete based on field name
|
||||
@@ -149,11 +149,13 @@ export function useFormEvents({
|
||||
updateData = [...data];
|
||||
}
|
||||
|
||||
const hasField = updateData.every((item) => Reflect.has(item, 'field') && item.field);
|
||||
const hasField = updateData.every(
|
||||
(item) => item.component === 'Divider' || (Reflect.has(item, 'field') && item.field),
|
||||
);
|
||||
|
||||
if (!hasField) {
|
||||
error(
|
||||
'All children of the form Schema array that need to be updated must contain the `field` field'
|
||||
'All children of the form Schema array that need to be updated must contain the `field` field',
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -169,11 +171,13 @@ export function useFormEvents({
|
||||
updateData = [...data];
|
||||
}
|
||||
|
||||
const hasField = updateData.every((item) => Reflect.has(item, 'field') && item.field);
|
||||
const hasField = updateData.every(
|
||||
(item) => item.component === 'Divider' || (Reflect.has(item, 'field') && item.field),
|
||||
);
|
||||
|
||||
if (!hasField) {
|
||||
error(
|
||||
'All children of the form Schema array that need to be updated must contain the `field` field'
|
||||
'All children of the form Schema array that need to be updated must contain the `field` field',
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
@@ -59,6 +59,8 @@ export const basicProps = {
|
||||
rulesMessageJoinLabel: propTypes.bool.def(true),
|
||||
// 超过3行自动折叠
|
||||
autoAdvancedLine: propTypes.number.def(3),
|
||||
// 不受折叠影响的行数
|
||||
alwaysShowLines: propTypes.number.def(1),
|
||||
|
||||
// 是否显示操作按钮
|
||||
showActionButtonGroup: propTypes.bool.def(true),
|
||||
|
@@ -37,7 +37,7 @@ export interface FormActionType {
|
||||
appendSchemaByField: (
|
||||
schema: FormSchema,
|
||||
prefixField: string | undefined,
|
||||
first?: boolean | undefined
|
||||
first?: boolean | undefined,
|
||||
) => Promise<void>;
|
||||
validateFields: (nameList?: NamePath[]) => Promise<any>;
|
||||
validate: (nameList?: NamePath[]) => Promise<any>;
|
||||
@@ -97,6 +97,8 @@ export interface FormProps {
|
||||
autoFocusFirstItem?: boolean;
|
||||
// Automatically collapse over the specified number of rows
|
||||
autoAdvancedLine?: number;
|
||||
// Always show lines
|
||||
alwaysShowLines?: number;
|
||||
// Whether to show the operation button
|
||||
showActionButtonGroup?: boolean;
|
||||
|
||||
|
@@ -109,4 +109,5 @@ export type ComponentType =
|
||||
| 'IconPicker'
|
||||
| 'Render'
|
||||
| 'Slider'
|
||||
| 'Rate';
|
||||
| 'Rate'
|
||||
| 'Divider';
|
||||
|
@@ -63,7 +63,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<template v-else
|
||||
><div class="p-5"> <Empty /></div>
|
||||
><div class="p-5"><Empty /></div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
copy: propTypes.bool.def(false),
|
||||
mode: propTypes.oneOf<('svg' | 'iconify')[]>(['svg', 'iconify']).def('iconify'),
|
||||
},
|
||||
emits: ['change'],
|
||||
emits: ['change', 'update:value'],
|
||||
setup(props, { emit }) {
|
||||
const isSvgMode = props.mode === 'svg';
|
||||
const icons = isSvgMode ? getSvgIcons() : getIcons();
|
||||
@@ -139,7 +139,7 @@
|
||||
|
||||
const { getPaginationList, getTotal, setCurrentPage } = usePagination(
|
||||
currentList,
|
||||
props.pageSize
|
||||
props.pageSize,
|
||||
);
|
||||
|
||||
watchEffect(() => {
|
||||
@@ -148,7 +148,10 @@
|
||||
|
||||
watch(
|
||||
() => currentSelect.value,
|
||||
(v) => emit('change', v)
|
||||
(v) => {
|
||||
emit('update:value', v);
|
||||
return emit('change', v);
|
||||
},
|
||||
);
|
||||
|
||||
function handlePageChange(page: number) {
|
||||
|
@@ -4,7 +4,7 @@ import type { LoadingProps } from './typing';
|
||||
import type { Ref } from 'vue';
|
||||
|
||||
export interface UseLoadingOptions {
|
||||
target?: HTMLElement | Ref<ElRef>;
|
||||
target?: any;
|
||||
props?: Partial<LoadingProps>;
|
||||
}
|
||||
|
||||
@@ -12,10 +12,12 @@ interface Fn {
|
||||
(): void;
|
||||
}
|
||||
|
||||
export function useLoading(props: Partial<LoadingProps>): [Fn, Fn];
|
||||
export function useLoading(opt: Partial<UseLoadingOptions>): [Fn, Fn];
|
||||
export function useLoading(props: Partial<LoadingProps>): [Fn, Fn, (string) => void];
|
||||
export function useLoading(opt: Partial<UseLoadingOptions>): [Fn, Fn, (string) => void];
|
||||
|
||||
export function useLoading(opt: Partial<LoadingProps> | Partial<UseLoadingOptions>): [Fn, Fn] {
|
||||
export function useLoading(
|
||||
opt: Partial<LoadingProps> | Partial<UseLoadingOptions>,
|
||||
): [Fn, Fn, (string) => void] {
|
||||
let props: Partial<LoadingProps>;
|
||||
let target: HTMLElement | Ref<ElRef> = document.body;
|
||||
|
||||
@@ -30,7 +32,7 @@ export function useLoading(opt: Partial<LoadingProps> | Partial<UseLoadingOption
|
||||
const instance = createLoading(props, undefined, true);
|
||||
|
||||
const open = (): void => {
|
||||
const t = unref(target);
|
||||
const t = unref(target as Ref<ElRef>);
|
||||
if (!t) return;
|
||||
instance.open(t);
|
||||
};
|
||||
@@ -39,5 +41,9 @@ export function useLoading(opt: Partial<LoadingProps> | Partial<UseLoadingOption
|
||||
instance.close();
|
||||
};
|
||||
|
||||
return [open, close];
|
||||
const setTip = (tip: string) => {
|
||||
instance.setTip(tip);
|
||||
};
|
||||
|
||||
return [open, close, setTip];
|
||||
}
|
||||
|
@@ -1,5 +1,7 @@
|
||||
import { withInstall } from '/@/utils';
|
||||
import markDown from './src/Markdown.vue';
|
||||
import markDownViewer from './src/MarkdownViewer.vue';
|
||||
|
||||
export const MarkDown = withInstall(markDown);
|
||||
export const MarkdownViewer = withInstall(markDownViewer);
|
||||
export * from './src/typing';
|
||||
|
@@ -2,6 +2,7 @@
|
||||
<div ref="wrapRef"></div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import type { Ref } from 'vue';
|
||||
import {
|
||||
defineComponent,
|
||||
ref,
|
||||
@@ -30,14 +31,14 @@
|
||||
emits: ['change', 'get', 'update:value'],
|
||||
setup(props, { attrs, emit }) {
|
||||
const wrapRef = ref<ElRef>(null);
|
||||
const vditorRef = ref<Nullable<Vditor>>(null);
|
||||
const vditorRef = ref(null) as Ref<Nullable<Vditor>>;
|
||||
const initedRef = ref(false);
|
||||
|
||||
const modalFn = useModalContext();
|
||||
|
||||
const { getLocale } = useLocale();
|
||||
const { getDarkMode } = useRootSetting();
|
||||
const valueRef = ref('');
|
||||
const valueRef = ref(props.value || '');
|
||||
|
||||
watch(
|
||||
[() => getDarkMode.value, () => initedRef.value],
|
||||
@@ -51,7 +52,7 @@
|
||||
{
|
||||
immediate: true,
|
||||
flush: 'post',
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
watch(
|
||||
@@ -61,7 +62,7 @@
|
||||
instance.getVditor()?.setValue(v);
|
||||
}
|
||||
valueRef.value = v;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const getCurrentLang = computed((): 'zh_CN' | 'en_US' | 'ja_JP' | 'ko_KR' => {
|
||||
@@ -89,6 +90,9 @@
|
||||
theme: getDarkMode.value === 'dark' ? 'dark' : 'classic',
|
||||
lang: unref(getCurrentLang),
|
||||
mode: 'sv',
|
||||
fullscreen: {
|
||||
index: 520,
|
||||
},
|
||||
preview: {
|
||||
actions: [],
|
||||
},
|
||||
|
22
src/components/Markdown/src/MarkdownViewer.vue
Normal file
22
src/components/Markdown/src/MarkdownViewer.vue
Normal file
@@ -0,0 +1,22 @@
|
||||
<template>
|
||||
<div v-html="getHtmlData" :class="$props.class" class="markdown-viewer"></div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue';
|
||||
import showdown from 'showdown';
|
||||
|
||||
const converter = new showdown.Converter();
|
||||
converter.setOption('tables', true);
|
||||
const props = defineProps({
|
||||
value: { type: String },
|
||||
class: { type: String },
|
||||
});
|
||||
const getHtmlData = computed(() => converter.makeHtml(props.value || ''));
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.markdown-viewer {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
@@ -56,15 +56,15 @@
|
||||
const { prefixCls } = useDesign('basic-menu');
|
||||
const { items, mode, accordion } = toRefs(props);
|
||||
|
||||
const { getCollapsed, getIsHorizontal, getTopMenuAlign, getSplit } = useMenuSetting();
|
||||
const { getCollapsed, getTopMenuAlign, getSplit } = useMenuSetting();
|
||||
|
||||
const { currentRoute } = useRouter();
|
||||
|
||||
const { handleOpenChange, setOpenKeys, getOpenKeys } = useOpenKeys(
|
||||
menuState,
|
||||
items,
|
||||
mode,
|
||||
accordion
|
||||
mode as any,
|
||||
accordion,
|
||||
);
|
||||
|
||||
const getIsTopMenu = computed(() => {
|
||||
@@ -114,7 +114,7 @@
|
||||
() => props.items,
|
||||
() => {
|
||||
handleMenuChange();
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
async function handleMenuClick({ key }: { key: string; keyPath: string[] }) {
|
||||
@@ -126,9 +126,6 @@
|
||||
emit('menuClick', key);
|
||||
|
||||
isClickGo.value = true;
|
||||
// const parentPath = await getCurrentParentPath(key);
|
||||
|
||||
// menuState.openKeys = [parentPath];
|
||||
menuState.selectedKeys = [key];
|
||||
}
|
||||
|
||||
@@ -150,8 +147,6 @@
|
||||
}
|
||||
|
||||
return {
|
||||
prefixCls,
|
||||
getIsHorizontal,
|
||||
handleMenuClick,
|
||||
getInlineCollapseOptions,
|
||||
getMenuClass,
|
||||
|
@@ -1,13 +1,11 @@
|
||||
<template>
|
||||
<MenuItem :key="item.path">
|
||||
<!-- <MenuItem :class="getLevelClass"> -->
|
||||
<MenuItemContent v-bind="$props" :item="item" />
|
||||
</MenuItem>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { Menu } from 'ant-design-vue';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
import { itemProps } from '../props';
|
||||
|
||||
import MenuItemContent from './MenuItemContent.vue';
|
||||
@@ -15,20 +13,8 @@
|
||||
name: 'BasicMenuItem',
|
||||
components: { MenuItem: Menu.Item, MenuItemContent },
|
||||
props: itemProps,
|
||||
setup() // props
|
||||
{
|
||||
const { prefixCls } = useDesign('basic-menu-item');
|
||||
|
||||
// const getLevelClass = computed(() => {
|
||||
// const { level, theme } = props;
|
||||
|
||||
// const levelCls = [`${prefixCls}__level${level}`, theme];
|
||||
// return levelCls;
|
||||
// });
|
||||
return {
|
||||
prefixCls,
|
||||
// getLevelClass,
|
||||
};
|
||||
setup() {
|
||||
return {};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
@@ -4,6 +4,8 @@ import type { PropType } from 'vue';
|
||||
import { MenuModeEnum, MenuTypeEnum } from '/@/enums/menuEnum';
|
||||
import { ThemeEnum } from '/@/enums/appEnum';
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
import type { MenuTheme } from 'ant-design-vue';
|
||||
import type { MenuMode } from 'ant-design-vue/lib/menu/src/interface';
|
||||
export const basicProps = {
|
||||
items: {
|
||||
type: Array as PropType<Menu[]>,
|
||||
@@ -14,7 +16,7 @@ export const basicProps = {
|
||||
inlineIndent: propTypes.number.def(20),
|
||||
// 菜单组件的mode属性
|
||||
mode: {
|
||||
type: String as PropType<MenuModeEnum>,
|
||||
type: String as PropType<MenuMode>,
|
||||
default: MenuModeEnum.INLINE,
|
||||
},
|
||||
|
||||
@@ -22,7 +24,10 @@ export const basicProps = {
|
||||
type: String as PropType<MenuTypeEnum>,
|
||||
default: MenuTypeEnum.MIX,
|
||||
},
|
||||
theme: propTypes.string.def(ThemeEnum.DARK),
|
||||
theme: {
|
||||
type: String as PropType<MenuTheme>,
|
||||
default: ThemeEnum.DARK,
|
||||
},
|
||||
inlineCollapsed: propTypes.bool,
|
||||
mixSider: propTypes.bool,
|
||||
|
||||
|
@@ -14,7 +14,7 @@ export function useOpenKeys(
|
||||
menuState: MenuState,
|
||||
menus: Ref<MenuType[]>,
|
||||
mode: Ref<MenuModeEnum>,
|
||||
accordion: Ref<boolean>
|
||||
accordion: Ref<boolean>,
|
||||
) {
|
||||
const { getCollapsed, getIsMixSidebar } = useMenuSetting();
|
||||
|
||||
@@ -37,7 +37,7 @@ export function useOpenKeys(
|
||||
}
|
||||
},
|
||||
16,
|
||||
!native
|
||||
!native,
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<Modal v-bind="getBindValue" @cancel="handleCancel">
|
||||
<Modal v-bind="getBindValue">
|
||||
<template #closeIcon v-if="!$slots.closeIcon">
|
||||
<ModalClose
|
||||
:canFullscreen="getProps.canFullscreen"
|
||||
@@ -20,7 +20,7 @@
|
||||
<template #footer v-if="!$slots.footer">
|
||||
<ModalFooter v-bind="getBindValue" @ok="handleOk" @cancel="handleCancel">
|
||||
<template #[item]="data" v-for="item in Object.keys($slots)">
|
||||
<slot :name="item" v-bind="data"></slot>
|
||||
<slot :name="item" v-bind="data || {}"></slot>
|
||||
</template>
|
||||
</ModalFooter>
|
||||
</template>
|
||||
@@ -44,7 +44,7 @@
|
||||
</ModalWrapper>
|
||||
|
||||
<template #[item]="data" v-for="item in Object.keys(omit($slots, 'default'))">
|
||||
<slot :name="item" v-bind="data"></slot>
|
||||
<slot :name="item" v-bind="data || {}"></slot>
|
||||
</template>
|
||||
</Modal>
|
||||
</template>
|
||||
@@ -104,7 +104,7 @@
|
||||
}
|
||||
|
||||
// Custom title component: get title
|
||||
const getMergeProps = computed((): ModalProps => {
|
||||
const getMergeProps = computed((): Recordable => {
|
||||
return {
|
||||
...props,
|
||||
...(unref(propsRef) as any),
|
||||
@@ -118,7 +118,7 @@
|
||||
});
|
||||
|
||||
// modal component does not need title and origin buttons
|
||||
const getProps = computed((): ModalProps => {
|
||||
const getProps = computed((): Recordable => {
|
||||
const opt = {
|
||||
...unref(getMergeProps),
|
||||
visible: unref(visibleRef),
|
||||
@@ -140,9 +140,9 @@
|
||||
wrapClassName: unref(getWrapClassName),
|
||||
};
|
||||
if (unref(fullScreenRef)) {
|
||||
return omit(attr, 'height');
|
||||
return omit(attr, ['height', 'title']);
|
||||
}
|
||||
return attr;
|
||||
return omit(attr, 'title');
|
||||
});
|
||||
|
||||
const getWrapperHeight = computed(() => {
|
||||
@@ -169,7 +169,7 @@
|
||||
},
|
||||
{
|
||||
immediate: false,
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// 取消事件
|
||||
@@ -212,7 +212,7 @@
|
||||
extHeightRef.value = height;
|
||||
}
|
||||
|
||||
function handleTitleDbClick(e: ChangeEvent) {
|
||||
function handleTitleDbClick(e) {
|
||||
if (!props.canFullscreen) return;
|
||||
e.stopPropagation();
|
||||
handleFullScreen(e);
|
||||
|
@@ -62,7 +62,7 @@
|
||||
{
|
||||
attributes: true,
|
||||
subtree: true,
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
createModalContext({
|
||||
@@ -89,7 +89,7 @@
|
||||
} else {
|
||||
minRealHeightRef.value = realHeightRef.value;
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
@@ -125,7 +125,7 @@
|
||||
const modalDom = bodyDom.parentElement && bodyDom.parentElement.parentElement;
|
||||
if (!modalDom) return;
|
||||
|
||||
const modalRect = getComputedStyle(modalDom).top;
|
||||
const modalRect = getComputedStyle(modalDom as Element).top;
|
||||
const modalTop = Number.parseInt(modalRect);
|
||||
let maxHeight =
|
||||
window.innerHeight -
|
||||
|
@@ -48,6 +48,7 @@ export function useModal(): UseModalReturnType {
|
||||
if (unref(loaded) && isProdMode() && modalMethod === unref(modal)) return;
|
||||
|
||||
modal.value = modalMethod;
|
||||
loaded.value = true;
|
||||
modalMethod.emitVisible = (visible: boolean, uid: number) => {
|
||||
visibleData[uid] = visible;
|
||||
};
|
||||
|
@@ -19,7 +19,7 @@
|
||||
width: 520px;
|
||||
padding-bottom: 0;
|
||||
|
||||
.scrollbar {
|
||||
.ant-modal-body > .scrollbar {
|
||||
padding: 14px;
|
||||
}
|
||||
|
||||
|
@@ -5,3 +5,5 @@ import pageWrapper from './src/PageWrapper.vue';
|
||||
|
||||
export const PageFooter = withInstall(pageFooter);
|
||||
export const PageWrapper = withInstall(pageWrapper);
|
||||
|
||||
export const PageWrapperFixedHeightKey = 'PageWrapperFixedHeight';
|
||||
|
@@ -3,7 +3,7 @@
|
||||
<PageHeader
|
||||
:ghost="ghost"
|
||||
:title="title"
|
||||
v-bind="$attrs"
|
||||
v-bind="omit($attrs, 'class')"
|
||||
ref="headerRef"
|
||||
v-if="content || $slots.headerContent || title || getHeaderSlots.length"
|
||||
>
|
||||
@@ -14,7 +14,7 @@
|
||||
<slot name="headerContent" v-else></slot>
|
||||
</template>
|
||||
<template #[item]="data" v-for="item in getHeaderSlots">
|
||||
<slot :name="item" v-bind="data"></slot>
|
||||
<slot :name="item" v-bind="data || {}"></slot>
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import type { CSSProperties, PropType } from 'vue';
|
||||
import { CSSProperties, PropType, provide } from 'vue';
|
||||
|
||||
import { defineComponent, computed, watch, ref, unref } from 'vue';
|
||||
import PageFooter from './PageFooter.vue';
|
||||
@@ -43,6 +43,7 @@
|
||||
import { omit } from 'lodash-es';
|
||||
import { PageHeader } from 'ant-design-vue';
|
||||
import { useContentHeight } from '/@/hooks/web/useContentHeight';
|
||||
import { PageWrapperFixedHeightKey } from '..';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'PageWrapper',
|
||||
@@ -60,23 +61,31 @@
|
||||
contentFullHeight: propTypes.bool,
|
||||
contentClass: propTypes.string,
|
||||
fixedHeight: propTypes.bool,
|
||||
upwardSpace: propTypes.oneOfType([propTypes.number, propTypes.string]).def(0),
|
||||
},
|
||||
setup(props, { slots }) {
|
||||
setup(props, { slots, attrs }) {
|
||||
const wrapperRef = ref(null);
|
||||
const headerRef = ref(null);
|
||||
const contentRef = ref(null);
|
||||
const footerRef = ref(null);
|
||||
const { prefixCls } = useDesign('page-wrapper');
|
||||
|
||||
provide(
|
||||
PageWrapperFixedHeightKey,
|
||||
computed(() => props.fixedHeight),
|
||||
);
|
||||
|
||||
const getIsContentFullHeight = computed(() => {
|
||||
return props.contentFullHeight;
|
||||
});
|
||||
|
||||
const getUpwardSpace = computed(() => props.upwardSpace);
|
||||
const { redoHeight, setCompensation, contentHeight } = useContentHeight(
|
||||
getIsContentFullHeight,
|
||||
wrapperRef,
|
||||
[headerRef, footerRef],
|
||||
[contentRef]
|
||||
[contentRef],
|
||||
getUpwardSpace,
|
||||
);
|
||||
setCompensation({ useLayoutFooter: true, elements: [footerRef] });
|
||||
|
||||
@@ -86,6 +95,7 @@
|
||||
{
|
||||
[`${prefixCls}--dense`]: props.dense,
|
||||
},
|
||||
attrs.class ?? {},
|
||||
];
|
||||
});
|
||||
|
||||
@@ -128,7 +138,7 @@
|
||||
{
|
||||
flush: 'post',
|
||||
immediate: true,
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
return {
|
||||
|
@@ -1,6 +1,5 @@
|
||||
<script lang="tsx">
|
||||
import { defineComponent, ref, unref, computed, reactive, watchEffect } from 'vue';
|
||||
import { Props } from './typing';
|
||||
import { CloseOutlined, LeftOutlined, RightOutlined } from '@ant-design/icons-vue';
|
||||
import resumeSvg from '/@/assets/svg/preview/resume.svg';
|
||||
import rotateSvg from '/@/assets/svg/preview/p-rotate.svg';
|
||||
@@ -38,13 +37,33 @@
|
||||
type: Number as PropType<number>,
|
||||
default: 0,
|
||||
},
|
||||
scaleStep: {
|
||||
type: Number as PropType<number>,
|
||||
},
|
||||
defaultWidth: {
|
||||
type: Number as PropType<number>,
|
||||
},
|
||||
maskClosable: {
|
||||
type: Boolean as PropType<boolean>,
|
||||
},
|
||||
rememberState: {
|
||||
type: Boolean as PropType<boolean>,
|
||||
},
|
||||
};
|
||||
|
||||
const prefixCls = 'img-preview';
|
||||
export default defineComponent({
|
||||
name: 'ImagePreview',
|
||||
props,
|
||||
setup(props: Props) {
|
||||
emits: ['img-load', 'img-error'],
|
||||
setup(props, { expose, emit }) {
|
||||
interface stateInfo {
|
||||
scale: number;
|
||||
rotate: number;
|
||||
top: number;
|
||||
left: number;
|
||||
}
|
||||
const stateMap = new Map<string, stateInfo>();
|
||||
const imgState = reactive<ImgState>({
|
||||
currentUrl: '',
|
||||
imgScale: 1,
|
||||
@@ -96,6 +115,15 @@
|
||||
};
|
||||
}
|
||||
|
||||
const getScaleStep = computed(() => {
|
||||
const scaleStep = props?.scaleStep ?? 0;
|
||||
if (scaleStep ?? (0 > 0 && scaleStep < 100)) {
|
||||
return scaleStep / 100;
|
||||
} else {
|
||||
return imgState.imgScale / 10;
|
||||
}
|
||||
});
|
||||
|
||||
// 监听鼠标滚轮
|
||||
function scrollFunc(e: any) {
|
||||
e = e || window.event;
|
||||
@@ -104,11 +132,11 @@
|
||||
e.preventDefault();
|
||||
if (e.delta > 0) {
|
||||
// 滑轮向上滚动
|
||||
scaleFunc(0.015);
|
||||
scaleFunc(getScaleStep.value);
|
||||
}
|
||||
if (e.delta < 0) {
|
||||
// 滑轮向下滚动
|
||||
scaleFunc(-0.015);
|
||||
scaleFunc(-getScaleStep.value);
|
||||
}
|
||||
}
|
||||
// 缩放函数
|
||||
@@ -134,11 +162,54 @@
|
||||
imgState.status = StatueEnum.LOADING;
|
||||
const img = new Image();
|
||||
img.src = url;
|
||||
img.onload = () => {
|
||||
img.onload = (e: Event) => {
|
||||
if (imgState.currentUrl !== url) {
|
||||
const ele: any[] = e.composedPath();
|
||||
if (props.rememberState) {
|
||||
// 保存当前图片的缩放信息
|
||||
stateMap.set(imgState.currentUrl, {
|
||||
scale: imgState.imgScale,
|
||||
top: imgState.imgTop,
|
||||
left: imgState.imgLeft,
|
||||
rotate: imgState.imgRotate,
|
||||
});
|
||||
// 如果之前已存储缩放信息,就应用
|
||||
const stateInfo = stateMap.get(url);
|
||||
if (stateInfo) {
|
||||
imgState.imgScale = stateInfo.scale;
|
||||
imgState.imgTop = stateInfo.top;
|
||||
imgState.imgRotate = stateInfo.rotate;
|
||||
imgState.imgLeft = stateInfo.left;
|
||||
} else {
|
||||
initState();
|
||||
if (props.defaultWidth) {
|
||||
imgState.imgScale = props.defaultWidth / ele[0].naturalWidth;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (props.defaultWidth) {
|
||||
imgState.imgScale = props.defaultWidth / ele[0].naturalWidth;
|
||||
}
|
||||
}
|
||||
|
||||
ele &&
|
||||
emit('img-load', {
|
||||
index: imgState.currentIndex,
|
||||
dom: ele[0] as HTMLImageElement,
|
||||
url,
|
||||
});
|
||||
}
|
||||
imgState.currentUrl = url;
|
||||
imgState.status = StatueEnum.DONE;
|
||||
};
|
||||
img.onerror = () => {
|
||||
img.onerror = (e: Event) => {
|
||||
const ele: EventTarget[] = e.composedPath();
|
||||
ele &&
|
||||
emit('img-error', {
|
||||
index: imgState.currentIndex,
|
||||
dom: ele[0] as HTMLImageElement,
|
||||
url,
|
||||
});
|
||||
imgState.status = StatueEnum.FAIL;
|
||||
};
|
||||
}
|
||||
@@ -146,6 +217,10 @@
|
||||
// 关闭
|
||||
function handleClose(e: MouseEvent) {
|
||||
e && e.stopPropagation();
|
||||
close();
|
||||
}
|
||||
|
||||
function close() {
|
||||
imgState.show = false;
|
||||
// 移除火狐浏览器下的鼠标滚动事件
|
||||
document.body.removeEventListener('DOMMouseScroll', scrollFunc);
|
||||
@@ -158,6 +233,19 @@
|
||||
initState();
|
||||
}
|
||||
|
||||
expose({
|
||||
resume,
|
||||
close,
|
||||
prev: handleChange.bind(null, 'left'),
|
||||
next: handleChange.bind(null, 'right'),
|
||||
setScale: (scale: number) => {
|
||||
if (scale > 0 && scale <= 10) imgState.imgScale = scale;
|
||||
},
|
||||
setRotate: (rotate: number) => {
|
||||
imgState.imgRotate = rotate;
|
||||
},
|
||||
});
|
||||
|
||||
// 上一页下一页
|
||||
function handleChange(direction: 'left' | 'right') {
|
||||
const { currentIndex } = imgState;
|
||||
@@ -205,6 +293,7 @@
|
||||
transform: `scale(${imgScale}) rotate(${imgRotate}deg)`,
|
||||
marginTop: `${imgTop}px`,
|
||||
marginLeft: `${imgLeft}px`,
|
||||
maxWidth: props.defaultWidth ? 'unset' : '100%',
|
||||
};
|
||||
});
|
||||
|
||||
@@ -222,6 +311,16 @@
|
||||
}
|
||||
});
|
||||
|
||||
const handleMaskClick = (e: MouseEvent) => {
|
||||
if (
|
||||
props.maskClosable &&
|
||||
e.target &&
|
||||
(e.target as HTMLDivElement).classList.contains(`${prefixCls}-content`)
|
||||
) {
|
||||
handleClose(e);
|
||||
}
|
||||
};
|
||||
|
||||
const renderClose = () => {
|
||||
return (
|
||||
<div class={`${prefixCls}__close`} onClick={handleClose}>
|
||||
@@ -246,10 +345,16 @@
|
||||
const renderController = () => {
|
||||
return (
|
||||
<div class={`${prefixCls}__controller`}>
|
||||
<div class={`${prefixCls}__controller-item`} onClick={() => scaleFunc(-0.15)}>
|
||||
<div
|
||||
class={`${prefixCls}__controller-item`}
|
||||
onClick={() => scaleFunc(-getScaleStep.value)}
|
||||
>
|
||||
<img src={unScaleSvg} />
|
||||
</div>
|
||||
<div class={`${prefixCls}__controller-item`} onClick={() => scaleFunc(0.15)}>
|
||||
<div
|
||||
class={`${prefixCls}__controller-item`}
|
||||
onClick={() => scaleFunc(getScaleStep.value)}
|
||||
>
|
||||
<img src={scaleSvg} />
|
||||
</div>
|
||||
<div class={`${prefixCls}__controller-item`} onClick={resume}>
|
||||
@@ -279,7 +384,12 @@
|
||||
return () => {
|
||||
return (
|
||||
imgState.show && (
|
||||
<div class={prefixCls} ref={wrapElRef} onMouseup={handleMouseUp}>
|
||||
<div
|
||||
class={prefixCls}
|
||||
ref={wrapElRef}
|
||||
onMouseup={handleMouseUp}
|
||||
onClick={handleMaskClick}
|
||||
>
|
||||
<div class={`${prefixCls}-content`}>
|
||||
{/*<Spin*/}
|
||||
{/* indicator={<LoadingOutlined style="font-size: 24px" spin />}*/}
|
||||
|
@@ -56,7 +56,7 @@
|
||||
setup(props) {
|
||||
const { prefixCls } = useDesign('image-preview');
|
||||
|
||||
const getImageList = computed(() => {
|
||||
const getImageList = computed((): any[] => {
|
||||
const { imageList } = props;
|
||||
if (!imageList) {
|
||||
return [];
|
||||
|
@@ -6,15 +6,12 @@ import { createVNode, render } from 'vue';
|
||||
let instance: ReturnType<typeof createVNode> | null = null;
|
||||
export function createImgPreview(options: Options) {
|
||||
if (!isClient) return;
|
||||
const { imageList, show = true, index = 0 } = options;
|
||||
|
||||
const propsData: Partial<Props> = {};
|
||||
const container = document.createElement('div');
|
||||
propsData.imageList = imageList;
|
||||
propsData.show = show;
|
||||
propsData.index = index;
|
||||
Object.assign(propsData, { show: true, index: 0, scaleStep: 100 }, options);
|
||||
|
||||
instance = createVNode(ImgPreview, propsData);
|
||||
render(instance, container);
|
||||
document.body.appendChild(container);
|
||||
return instance.component?.exposed;
|
||||
}
|
||||
|
@@ -2,6 +2,12 @@ export interface Options {
|
||||
show?: boolean;
|
||||
imageList: string[];
|
||||
index?: number;
|
||||
scaleStep?: number;
|
||||
defaultWidth?: number;
|
||||
maskClosable?: boolean;
|
||||
rememberState?: boolean;
|
||||
onImgLoad?: ({ index: number, url: string, dom: HTMLImageElement }) => void;
|
||||
onImgError?: ({ index: number, url: string, dom: HTMLImageElement }) => void;
|
||||
}
|
||||
|
||||
export interface Props {
|
||||
@@ -9,6 +15,19 @@ export interface Props {
|
||||
instance: Props;
|
||||
imageList: string[];
|
||||
index: number;
|
||||
scaleStep: number;
|
||||
defaultWidth: number;
|
||||
maskClosable: boolean;
|
||||
rememberState: boolean;
|
||||
}
|
||||
|
||||
export interface PreviewActions {
|
||||
resume: () => void;
|
||||
close: () => void;
|
||||
prev: () => void;
|
||||
next: () => void;
|
||||
setScale: (scale: number) => void;
|
||||
setRotate: (rotate: number) => void;
|
||||
}
|
||||
|
||||
export interface ImageProps {
|
||||
|
@@ -4,7 +4,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, watchEffect, PropType, ref, unref } from 'vue';
|
||||
import { defineComponent, watch, PropType, ref, unref, onMounted } from 'vue';
|
||||
import { toCanvas, QRCodeRenderersOptions, LogoType } from './qrcodePlus';
|
||||
import { toDataURL } from 'qrcode';
|
||||
import { downloadByUrl } from '/@/utils/file/download';
|
||||
@@ -93,11 +93,18 @@
|
||||
});
|
||||
}
|
||||
|
||||
watchEffect(() => {
|
||||
setTimeout(() => {
|
||||
onMounted(createQrcode);
|
||||
|
||||
// 监听参数变化重新生成二维码
|
||||
watch(
|
||||
props,
|
||||
() => {
|
||||
createQrcode();
|
||||
}, 30);
|
||||
});
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
},
|
||||
);
|
||||
|
||||
return { wrapRef, download };
|
||||
},
|
||||
|
@@ -1,7 +1,15 @@
|
||||
import { toCanvas } from 'qrcode';
|
||||
import type { QRCodeRenderersOptions } from 'qrcode';
|
||||
import { RenderQrCodeParams, ContentType } from './typing';
|
||||
export const renderQrCode = ({ canvas, content, width = 0, options = {} }: RenderQrCodeParams) => {
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
|
||||
export const renderQrCode = ({
|
||||
canvas,
|
||||
content,
|
||||
width = 0,
|
||||
options: params = {},
|
||||
}: RenderQrCodeParams) => {
|
||||
const options = cloneDeep(params);
|
||||
// 容错率,默认对内容少的二维码采用高容错率,内容多的二维码采用低容错率
|
||||
options.errorCorrectionLevel = options.errorCorrectionLevel || getErrorCorrectionLevel(content);
|
||||
|
||||
|
@@ -44,7 +44,7 @@ export default defineComponent({
|
||||
|
||||
const clickTrackHandler = (e: any) => {
|
||||
const offset = Math.abs(
|
||||
e.target.getBoundingClientRect()[bar.value.direction] - e[bar.value.client]
|
||||
e.target.getBoundingClientRect()[bar.value.direction] - e[bar.value.client],
|
||||
);
|
||||
const thumbHalf = thumb.value[bar.value.offset] / 2;
|
||||
const thumbPositionPercentage =
|
||||
@@ -104,7 +104,7 @@ export default defineComponent({
|
||||
move: props.move,
|
||||
bar: bar.value,
|
||||
}),
|
||||
})
|
||||
}),
|
||||
);
|
||||
},
|
||||
});
|
||||
|
@@ -75,7 +75,7 @@
|
||||
items,
|
||||
accordion,
|
||||
mixSider,
|
||||
collapse
|
||||
collapse,
|
||||
);
|
||||
|
||||
const getBindValues = computed(() => ({ ...attrs, ...props }));
|
||||
@@ -89,7 +89,7 @@
|
||||
setOpenKeys(currentRoute.value.path);
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
watch(
|
||||
@@ -100,7 +100,7 @@
|
||||
}
|
||||
setOpenKeys(currentRoute.value.path);
|
||||
},
|
||||
{ flush: 'post' }
|
||||
{ flush: 'post' },
|
||||
);
|
||||
|
||||
listenerRouteChange((route) => {
|
||||
|
@@ -87,7 +87,7 @@
|
||||
nextTick(() => {
|
||||
updateOpened();
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
function updateOpened() {
|
||||
@@ -124,7 +124,7 @@
|
||||
isRemoveAllPopup,
|
||||
sliceIndex,
|
||||
level: 0,
|
||||
props,
|
||||
props: props as any,
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
|
@@ -98,7 +98,7 @@
|
||||
active.value = false;
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
return { getClass, prefixCls, getItemStyle, getCollapse, handleClickItem, showTooptip };
|
||||
|
@@ -286,7 +286,7 @@
|
||||
if (props.name && Array.isArray(data)) {
|
||||
state.opened = (data as (string | number)[]).includes(props.name);
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
rootMenuEmitter.on('on-update-active-name:submenu', (data: number[]) => {
|
||||
|
@@ -1,9 +1,9 @@
|
||||
import type { InjectionKey, Ref } from 'vue';
|
||||
import type { Emitter } from '/@/utils/mitt';
|
||||
import { createContext, useContext } from '/@/hooks/core/useContext';
|
||||
import mitt from '/@/utils/mitt';
|
||||
|
||||
export interface SimpleRootMenuContextProps {
|
||||
rootMenuEmitter: typeof mitt;
|
||||
rootMenuEmitter: Emitter;
|
||||
activeName: Ref<string | number>;
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user