mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-08-26 00:26:20 +08:00
Compare commits
83 Commits
v5.5.5
...
electron-v
Author | SHA1 | Date | |
---|---|---|---|
![]() |
67071326a1 | ||
![]() |
30387b94a2 | ||
![]() |
643f25347b | ||
![]() |
49a739ffc6 | ||
![]() |
128e749702 | ||
![]() |
c91fd146b8 | ||
![]() |
74874a88a6 | ||
![]() |
f0f890c583 | ||
![]() |
ea48a01d8f | ||
![]() |
9311c658a1 | ||
![]() |
12151d9742 | ||
![]() |
de655af23b | ||
![]() |
6fe909bfba | ||
![]() |
899a99535f | ||
![]() |
29bdf2d13b | ||
![]() |
4f633c1a9a | ||
![]() |
b2951b2975 | ||
![]() |
d9f8722c27 | ||
![]() |
1539fc738c | ||
![]() |
200859fc7e | ||
![]() |
36fb6b2222 | ||
![]() |
3304d54546 | ||
![]() |
ca57d223b4 | ||
![]() |
0fa587c246 | ||
![]() |
4fd2fee782 | ||
![]() |
c4a4ca5232 | ||
![]() |
73db7f3ef5 | ||
![]() |
aef2134b60 | ||
![]() |
f920895b8c | ||
![]() |
10257e3611 | ||
![]() |
a88a2c8afa | ||
![]() |
d92697e7f7 | ||
![]() |
e34285a51e | ||
![]() |
721b5f3d3e | ||
![]() |
5e694b3194 | ||
![]() |
bf5e697c42 | ||
![]() |
9437e97ce4 | ||
![]() |
77c09b4ddf | ||
![]() |
70d07c683a | ||
![]() |
e840905934 | ||
![]() |
8b192d05fd | ||
![]() |
9f910c3486 | ||
![]() |
25b0822afd | ||
![]() |
8292024fc7 | ||
![]() |
9a0e813143 | ||
![]() |
1a73329691 | ||
![]() |
ab161444fc | ||
![]() |
0243e68fbe | ||
![]() |
54c0d4ed83 | ||
![]() |
e320311128 | ||
![]() |
1faa52335c | ||
![]() |
9ff600657b | ||
![]() |
d14527a292 | ||
![]() |
eb70c48d14 | ||
![]() |
302de1deaf | ||
![]() |
ea0c2ad58b | ||
![]() |
678646b4ba | ||
![]() |
a4da6dedf8 | ||
![]() |
332a8be29c | ||
![]() |
357ae0e565 | ||
![]() |
fe2310300c | ||
![]() |
7e99c62abf | ||
![]() |
a3b2d5c2e1 | ||
![]() |
39f9c6a3f4 | ||
![]() |
48c616ea81 | ||
![]() |
06e279c917 | ||
![]() |
ff65b061ef | ||
![]() |
b8f145aa7f | ||
![]() |
091596eda8 | ||
![]() |
17b0111424 | ||
![]() |
6e5ddb6d25 | ||
![]() |
46a10959c8 | ||
![]() |
382df99988 | ||
![]() |
d00b6bb83e | ||
![]() |
82a05e3b3a | ||
![]() |
d3d1e1616c | ||
![]() |
a4682a7116 | ||
![]() |
a8935aaf8c | ||
![]() |
a6b480fb8f | ||
![]() |
a87fa3ffbe | ||
![]() |
d450df946c | ||
![]() |
20f902ed2c | ||
![]() |
7536be5e49 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -5,6 +5,7 @@ dist-ssr
|
||||
dist.zip
|
||||
dist.tar
|
||||
dist.war
|
||||
dist-electron
|
||||
.nitro
|
||||
.output
|
||||
*-dist.zip
|
||||
|
@@ -2,5 +2,5 @@ ports:
|
||||
- port: 5555
|
||||
onOpen: open-preview
|
||||
tasks:
|
||||
- init: corepack enable && pnpm install
|
||||
- init: npm i -g corepack && pnpm install
|
||||
command: pnpm run dev:play
|
||||
|
@@ -1,6 +0,0 @@
|
||||
echo Start running commit-msg hook...
|
||||
|
||||
# Check whether the git commit information is standardized
|
||||
pnpm exec commitlint --edit "$1"
|
||||
|
||||
echo Run commit-msg hook done.
|
@@ -1,3 +0,0 @@
|
||||
# 每次 git pull 之后, 安装依赖
|
||||
|
||||
pnpm install
|
@@ -1,7 +0,0 @@
|
||||
# update `.vscode/vben-admin.code-workspace` file
|
||||
pnpm vsh code-workspace --auto-commit
|
||||
|
||||
# Format and submit code according to lintstagedrc.js configuration
|
||||
pnpm exec lint-staged
|
||||
|
||||
echo Run pre-commit hook done.
|
@@ -1,20 +0,0 @@
|
||||
export default {
|
||||
'*.md': ['prettier --cache --ignore-unknown --write'],
|
||||
'*.vue': [
|
||||
'prettier --write',
|
||||
'eslint --cache --fix',
|
||||
'stylelint --fix --allow-empty-input',
|
||||
],
|
||||
'*.{js,jsx,ts,tsx}': [
|
||||
'prettier --cache --ignore-unknown --write',
|
||||
'eslint --cache --fix',
|
||||
],
|
||||
'*.{scss,less,styl,html,vue,css}': [
|
||||
'prettier --cache --ignore-unknown --write',
|
||||
'stylelint --fix --allow-empty-input',
|
||||
],
|
||||
'package.json': ['prettier --cache --write'],
|
||||
'{!(package)*.json,*.code-snippets,.!(browserslist)*rc}': [
|
||||
'prettier --cache --write--parser json',
|
||||
],
|
||||
};
|
@@ -1 +1 @@
|
||||
20.14.0
|
||||
22.1.0
|
||||
|
3
.npmrc
3
.npmrc
@@ -1,4 +1,7 @@
|
||||
registry = "https://registry.npmmirror.com"
|
||||
ELECTRON_MIRROR="https://npmmirror.com/mirrors/electron/"
|
||||
public-hoist-pattern[]=lefthook
|
||||
ELECTRON_MIRROR="https://npmmirror.com/mirrors/electron/"
|
||||
public-hoist-pattern[]=husky
|
||||
public-hoist-pattern[]=eslint
|
||||
public-hoist-pattern[]=prettier
|
||||
|
7
.vscode/settings.json
vendored
7
.vscode/settings.json
vendored
@@ -14,7 +14,7 @@
|
||||
"editor.tabSize": 2,
|
||||
"editor.detectIndentation": false,
|
||||
"editor.cursorBlinking": "expand",
|
||||
"editor.largeFileOptimizations": false,
|
||||
"editor.largeFileOptimizations": true,
|
||||
"editor.accessibilitySupport": "off",
|
||||
"editor.cursorSmoothCaretAnimation": "on",
|
||||
"editor.guides.bracketPairs": "active",
|
||||
@@ -91,6 +91,7 @@
|
||||
"**/bower_components": true,
|
||||
"**/.turbo": true,
|
||||
"**/.idea": true,
|
||||
"**/.vitepress": true,
|
||||
"**/tmp": true,
|
||||
"**/.git": true,
|
||||
"**/.svn": true,
|
||||
@@ -112,6 +113,8 @@
|
||||
"**/yarn.lock": true
|
||||
},
|
||||
|
||||
"typescript.tsserver.exclude": ["**/node_modules", "**/dist", "**/.turbo"],
|
||||
|
||||
// search
|
||||
"search.searchEditor.singleClickBehaviour": "peekDefinition",
|
||||
"search.followSymlinks": false,
|
||||
@@ -216,7 +219,7 @@
|
||||
"*.env": "$(capture).env.*",
|
||||
"README.md": "README*,CHANGELOG*,LICENSE,CNAME",
|
||||
"package.json": "pnpm-lock.yaml,pnpm-workspace.yaml,.gitattributes,.gitignore,.gitpod.yml,.npmrc,.browserslistrc,.node-version,.git*,.tazerc.json",
|
||||
"eslint.config.mjs": ".eslintignore,.prettierignore,.stylelintignore,.commitlintrc.*,.prettierrc.*,stylelint.config.*,.lintstagedrc.mjs,cspell.json",
|
||||
"eslint.config.mjs": ".eslintignore,.prettierignore,.stylelintignore,.commitlintrc.*,.prettierrc.*,stylelint.config.*,.lintstagedrc.mjs,cspell.json,lefthook.yml",
|
||||
"tailwind.config.mjs": "postcss.*"
|
||||
},
|
||||
"commentTranslate.hover.enabled": false,
|
||||
|
@@ -1,8 +1,13 @@
|
||||
<div align="center"> <a href="https://github.com/anncwb/vue-vben-admin"> <img alt="VbenAdmin Logo" width="215" src="https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp"> </a> <br> <br>
|
||||
<div align="center">
|
||||
<a href="https://github.com/anncwb/vue-vben-admin">
|
||||
<img alt="VbenAdmin Logo" width="215" src="https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp">
|
||||
</a>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
[](LICENSE)
|
||||
|
||||
<h1>Vue Vben Admin</h1>
|
||||
<h1>Vue Vben Admin</h1>
|
||||
</div>
|
||||
|
||||
[](https://sonarcloud.io/summary/new_code?id=vbenjs_vue-vben-admin)    
|
||||
@@ -15,27 +20,27 @@ Vue Vben Adminは、最新の`vue3`、`vite`、`TypeScript`などの主流技術
|
||||
|
||||
## アップグレード通知
|
||||
|
||||
これは最新バージョン5.0であり、以前のバージョンとは互換性がありません。新しいプロジェクトを開始する場合は、最新バージョンを使用することをお勧めします。古いバージョンを表示したい場合は、[v2ブランチ](https://github.com/vbenjs/vue-vben-admin/tree/v2)を使用してください。
|
||||
これは最新バージョン `5.0` であり、以前のバージョンとは互換性がありません。新しいプロジェクトを開始する場合は、最新バージョンを使用することをお勧めします。古いバージョンを表示したい場合は、[v2ブランチ](https://github.com/vbenjs/vue-vben-admin/tree/v2)を使用してください。
|
||||
|
||||
## 特徴
|
||||
|
||||
- **最新技術スタック**: Vue 3やViteなどの最先端フロントエンド技術で開発
|
||||
- **TypeScript**: アプリケーション規模のJavaScriptのための言語
|
||||
- **テーマ**: 複数のテーマカラーが利用可能で、カスタマイズオプションも豊富
|
||||
- **国際化**: 完全な内蔵国際化サポート
|
||||
- **権限管理**: 動的ルートベースの権限生成ソリューションを内蔵
|
||||
- **最新技術スタック**:Vue 3やViteなどの最先端フロントエンド技術で開発
|
||||
- **TypeScript**:アプリケーション規模のJavaScriptのための言語
|
||||
- **テーマ**:複数のテーマカラーが利用可能で、カスタマイズオプションも豊富
|
||||
- **国際化**:完全な内蔵国際化サポート
|
||||
- **権限管理**:動的ルートベースの権限生成ソリューションを内蔵
|
||||
|
||||
## プレビュー
|
||||
|
||||
- [Vben Admin](https://vben.pro/) - フルバージョンの中国語サイト
|
||||
|
||||
テストアカウント: vben/123456
|
||||
テストアカウント:vben/123456
|
||||
|
||||
<p align="center">
|
||||
<img alt="VbenAdmin Logo" width="100%" src="https://anncwb.github.io/anncwb/images/preview1.png">
|
||||
<img alt="VbenAdmin Logo" width="100%" src="https://anncwb.github.io/anncwb/images/preview2.png">
|
||||
<img alt="VbenAdmin Logo" width="100%" src="https://anncwb.github.io/anncwb/images/preview3.png">
|
||||
</p>
|
||||
<div align="center">
|
||||
<img alt="VbenAdmin Logo" width="100%" src="https://anncwb.github.io/anncwb/images/preview1.png">
|
||||
<img alt="VbenAdmin Logo" width="100%" src="https://anncwb.github.io/anncwb/images/preview2.png">
|
||||
<img alt="VbenAdmin Logo" width="100%" src="https://anncwb.github.io/anncwb/images/preview3.png">
|
||||
</div>
|
||||
|
||||
### Gitpodを使用
|
||||
|
||||
@@ -49,30 +54,27 @@ Gitpod(GitHub用の無料オンライン開発環境)でプロジェクト
|
||||
|
||||
## インストールと使用
|
||||
|
||||
- プロジェクトコードを取得
|
||||
1. プロジェクトコードを取得
|
||||
|
||||
```bash
|
||||
git clone https://github.com/vbenjs/vue-vben-admin.git
|
||||
```
|
||||
|
||||
- 依存関係のインストール
|
||||
2. 依存関係のインストール
|
||||
|
||||
```bash
|
||||
cd vue-vben-admin
|
||||
|
||||
corepack enable
|
||||
|
||||
npm i -g corepack
|
||||
pnpm install
|
||||
|
||||
```
|
||||
|
||||
- 実行
|
||||
3. 実行
|
||||
|
||||
```bash
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
- ビルド
|
||||
4. ビルド
|
||||
|
||||
```bash
|
||||
pnpm build
|
||||
@@ -86,40 +88,39 @@ pnpm build
|
||||
|
||||
ご参加をお待ちしておりますするか、Pull Requestを送信してください。
|
||||
|
||||
**Pull Request:**
|
||||
**Pull Request プロセス:**
|
||||
|
||||
1. コードをフォーク!
|
||||
2. 自分のブランチを作成: `git checkout -b feat/xxxx`
|
||||
3. 変更をコミット: `git commit -am 'feat(function): add xxxxx'`
|
||||
4. ブランチをプッシュ: `git push origin feat/xxxx`
|
||||
1. コードをフォーク
|
||||
2. 自分のブランチを作成:`git checkout -b feat/xxxx`
|
||||
3. 変更をコミット:`git commit -am 'feat(function): add xxxxx'`
|
||||
4. ブランチをプッシュ:`git push origin feat/xxxx`
|
||||
5. `pull request`を送信
|
||||
|
||||
## Git貢献提出規則
|
||||
|
||||
- 参考 [vue](https://github.com/vuejs/vue/blob/dev/.github/COMMIT_CONVENTION.md) 規則 ([Angular](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-angular))
|
||||
参考 [vue](https://github.com/vuejs/vue/blob/dev/.github/COMMIT_CONVENTION.md) 規則 ([Angular](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-angular))
|
||||
|
||||
- `feat` 新機能の追加
|
||||
- `fix` 問題/バグの修正
|
||||
- `style` コードスタイルに関連し、実行結果に影響しない
|
||||
- `perf` 最適化/パフォーマンス向上
|
||||
- `refactor` リファクタリング
|
||||
- `revert` 変更の取り消し
|
||||
- `test` テスト関連
|
||||
- `docs` ドキュメント/注釈
|
||||
- `chore` 依存関係の更新/スキャフォールディング設定の変更など
|
||||
- `ci` 継続的インテグレーション
|
||||
- `types` 型定義ファイルの変更
|
||||
- `wip` 開発中
|
||||
- `feat` 新機能の追加
|
||||
- `fix` 問題/バグの修正
|
||||
- `style` コードスタイルに関連し、実行結果に影響しない
|
||||
- `perf` 最適化/パフォーマンス向上
|
||||
- `refactor` リファクタリング
|
||||
- `revert` 変更の取り消し
|
||||
- `test` テスト関連
|
||||
- `docs` ドキュメント/注釈
|
||||
- `chore` 依存関係の更新/スキャフォールディング設定の変更など
|
||||
- `ci` 継続的インテグレーション
|
||||
- `types` 型定義ファイルの変更
|
||||
|
||||
## ブラウザサポート
|
||||
|
||||
ローカル開発には`Chrome 80+`ブラウザを推奨します
|
||||
ローカル開発には `Chrome 80+` ブラウザを推奨します
|
||||
|
||||
モダンブラウザをサポートし、IEはサポートしません
|
||||
|
||||
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt=" Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt=" Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari |
|
||||
| :-: | :-: | :-: | :-: | :-: |
|
||||
| サポートしない | 最新2バージョン | 最新2バージョン | 最新2バージョン | 最新2バージョン |
|
||||
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari |
|
||||
| :-: | :-: | :-: | :-: |
|
||||
| 最新2バージョン | 最新2バージョン | 最新2バージョン | 最新2バージョン |
|
||||
|
||||
## メンテナー
|
||||
|
||||
@@ -140,8 +141,7 @@ pnpm build
|
||||
## 貢献者
|
||||
|
||||
<a href="https://github.com/vbenjs/vue-vben-admin/graphs/contributors">
|
||||
<img alt="Contributors"
|
||||
src="https://opencollective.com/vbenjs/contributors.svg?button=false" />
|
||||
<img alt="Contributors" src="https://opencollective.com/vbenjs/contributors.svg?button=false" />
|
||||
</a>
|
||||
|
||||
## Discord
|
||||
|
87
README.md
87
README.md
@@ -1,8 +1,13 @@
|
||||
<div align="center"> <a href="https://github.com/anncwb/vue-vben-admin"> <img alt="VbenAdmin Logo" width="215" src="https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp"> </a> <br> <br>
|
||||
<div align="center">
|
||||
<a href="https://github.com/anncwb/vue-vben-admin">
|
||||
<img alt="VbenAdmin Logo" width="215" src="https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp">
|
||||
</a>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
[](LICENSE)
|
||||
|
||||
<h1>Vue Vben Admin</h1>
|
||||
<h1>Vue Vben Admin</h1>
|
||||
</div>
|
||||
|
||||
[](https://sonarcloud.io/summary/new_code?id=vbenjs_vue-vben-admin)    
|
||||
@@ -17,7 +22,7 @@ Vue Vben Admin is a free and open source middle and back-end template. Using the
|
||||
|
||||
This is the latest version, 5.0, and it is not compatible with previous versions. If you are starting a new project, it is recommended to use the latest version. If you wish to view the old version, please use the [v2 branch](https://github.com/vbenjs/vue-vben-admin/tree/v2).
|
||||
|
||||
## Feature
|
||||
## Features
|
||||
|
||||
- **Latest Technology Stack**: Developed with cutting-edge front-end technologies like Vue 3 and Vite
|
||||
- **TypeScript**: A language for application-scale JavaScript
|
||||
@@ -31,11 +36,11 @@ This is the latest version, 5.0, and it is not compatible with previous versions
|
||||
|
||||
Test Account: vben/123456
|
||||
|
||||
<p align="center">
|
||||
<img alt="VbenAdmin Logo" width="100%" src="https://anncwb.github.io/anncwb/images/preview1.png">
|
||||
<img alt="VbenAdmin Logo" width="100%" src="https://anncwb.github.io/anncwb/images/preview2.png">
|
||||
<img alt="VbenAdmin Logo" width="100%" src="https://anncwb.github.io/anncwb/images/preview3.png">
|
||||
</p>
|
||||
<div align="center">
|
||||
<img alt="VbenAdmin Logo" width="100%" src="https://anncwb.github.io/anncwb/images/preview1.png">
|
||||
<img alt="VbenAdmin Logo" width="100%" src="https://anncwb.github.io/anncwb/images/preview2.png">
|
||||
<img alt="VbenAdmin Logo" width="100%" src="https://anncwb.github.io/anncwb/images/preview3.png">
|
||||
</div>
|
||||
|
||||
### Use Gitpod
|
||||
|
||||
@@ -47,31 +52,29 @@ Open the project in Gitpod (free online dev environment for GitHub) and start co
|
||||
|
||||
[Document](https://doc.vben.pro/)
|
||||
|
||||
## Install and use
|
||||
## Install and Use
|
||||
|
||||
- Get the project code
|
||||
1. Get the project code
|
||||
|
||||
```bash
|
||||
git clone https://github.com/vbenjs/vue-vben-admin.git
|
||||
```
|
||||
|
||||
- Installation dependencies
|
||||
2. Install dependencies
|
||||
|
||||
```bash
|
||||
cd vue-vben-admin
|
||||
|
||||
corepack enable
|
||||
|
||||
npm i -g corepack
|
||||
pnpm install
|
||||
```
|
||||
|
||||
- run
|
||||
3. Run
|
||||
|
||||
```bash
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
- build
|
||||
4. Build
|
||||
|
||||
```bash
|
||||
pnpm build
|
||||
@@ -81,44 +84,43 @@ pnpm build
|
||||
|
||||
[CHANGELOG](https://github.com/vbenjs/vue-vben-admin/releases)
|
||||
|
||||
## How to contribute
|
||||
## How to Contribute
|
||||
|
||||
You are very welcome to join Or submit a Pull Request。
|
||||
You are very welcome to join! [Raise an issue](https://github.com/anncwb/vue-vben-admin/issues/new/choose) or submit a Pull Request.
|
||||
|
||||
**Pull Request:**
|
||||
**Pull Request Process:**
|
||||
|
||||
1. Fork code!
|
||||
2. Create your own branch: `git checkout -b feat/xxxx`
|
||||
1. Fork the code
|
||||
2. Create your branch: `git checkout -b feat/xxxx`
|
||||
3. Submit your changes: `git commit -am 'feat(function): add xxxxx'`
|
||||
4. Push your branch: `git push origin feat/xxxx`
|
||||
5. submit`pull request`
|
||||
5. Submit `pull request`
|
||||
|
||||
## Git Contribution submission specification
|
||||
## Git Contribution Submission Specification
|
||||
|
||||
- reference [vue](https://github.com/vuejs/vue/blob/dev/.github/COMMIT_CONVENTION.md) specification ([Angular](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-angular))
|
||||
Reference [vue](https://github.com/vuejs/vue/blob/dev/.github/COMMIT_CONVENTION.md) specification ([Angular](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-angular))
|
||||
|
||||
- `feat` Add new features
|
||||
- `fix` Fix the problem/BUG
|
||||
- `style` The code style is related and does not affect the running result
|
||||
- `perf` Optimization/performance improvement
|
||||
- `refactor` Refactor
|
||||
- `revert` Undo edit
|
||||
- `test` Test related
|
||||
- `docs` Documentation/notes
|
||||
- `chore` Dependency update/scaffolding configuration modification etc.
|
||||
- `ci` Continuous integration
|
||||
- `types` Type definition file changes
|
||||
- `wip` In development
|
||||
- `feat` Add new features
|
||||
- `fix` Fix the problem/BUG
|
||||
- `style` The code style is related and does not affect the running result
|
||||
- `perf` Optimization/performance improvement
|
||||
- `refactor` Refactor
|
||||
- `revert` Undo edit
|
||||
- `test` Test related
|
||||
- `docs` Documentation/notes
|
||||
- `chore` Dependency update/scaffolding configuration modification etc.
|
||||
- `ci` Continuous integration
|
||||
- `types` Type definition file changes
|
||||
|
||||
## Browser support
|
||||
## Browser Support
|
||||
|
||||
The `Chrome 80+` browser is recommended for local development
|
||||
|
||||
Support modern browsers, not IE
|
||||
|
||||
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt=" Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt=" Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari |
|
||||
| :-: | :-: | :-: | :-: | :-: |
|
||||
| not support | last 2 versions | last 2 versions | last 2 versions | last 2 versions |
|
||||
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari |
|
||||
| :-: | :-: | :-: | :-: |
|
||||
| last 2 versions | last 2 versions | last 2 versions | last 2 versions |
|
||||
|
||||
## Maintainer
|
||||
|
||||
@@ -136,11 +138,10 @@ If you think this project is helpful to you, you can help the author buy a cup o
|
||||
|
||||
<a style="display: block;width: 100px;height: 50px;line-height: 50px; color: #fff;text-align: center; background: #408aee;border-radius: 4px;" href="https://www.paypal.com/paypalme/cvvben">Paypal Me</a>
|
||||
|
||||
## Contributor
|
||||
## Contributors
|
||||
|
||||
<a href="https://github.com/vbenjs/vue-vben-admin/graphs/contributors">
|
||||
<img alt="Contributors"
|
||||
src="https://opencollective.com/vbenjs/contributors.svg?button=false" />
|
||||
<img alt="Contributors" src="https://opencollective.com/vbenjs/contributors.svg?button=false" />
|
||||
</a>
|
||||
|
||||
## Discord
|
||||
|
@@ -1,8 +1,13 @@
|
||||
<div align="center"> <a href="https://github.com/anncwb/vue-vben-admin"> <img alt="VbenAdmin Logo" width="215" src="https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp"> </a> <br> <br>
|
||||
<div align="center">
|
||||
<a href="https://github.com/anncwb/vue-vben-admin">
|
||||
<img alt="VbenAdmin Logo" width="215" src="https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp">
|
||||
</a>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
[](LICENSE)
|
||||
|
||||
<h1>Vue Vben Admin</h1>
|
||||
<h1>Vue Vben Admin</h1>
|
||||
</div>
|
||||
|
||||
[](https://sonarcloud.io/summary/new_code?id=vbenjs_vue-vben-admin)    
|
||||
@@ -15,31 +20,31 @@ Vue Vben Admin 是 Vue Vben Admin 的升级版本。作为一个免费开源的
|
||||
|
||||
## 升级提示
|
||||
|
||||
该版本为最新版本`5.0`, 与其他版本不兼容,如果你是新项目,建议使用最新版本。如果你想查看旧版本,请使用 [v2 分支](https://github.com/vbenjs/vue-vben-admin/tree/v2)
|
||||
该版本为最新版本 `5.0`,与其他版本不兼容,如果你是新项目,建议使用最新版本。如果你想查看旧版本,请使用 [v2 分支](https://github.com/vbenjs/vue-vben-admin/tree/v2)
|
||||
|
||||
## 特性
|
||||
|
||||
- **最新技术栈**:使用 Vue3/vite 等前端前沿技术开发
|
||||
- **TypeScript**: 应用程序级 JavaScript 的语言
|
||||
- **TypeScript**:应用程序级 JavaScript 的语言
|
||||
- **主题**:提供多套主题色彩,可配置自定义主题
|
||||
- **国际化**:内置完善的国际化方案
|
||||
- **权限** 内置完善的动态路由权限生成方案
|
||||
- **权限**:内置完善的动态路由权限生成方案
|
||||
|
||||
## 预览
|
||||
|
||||
- [Vben Admin](https://vben.pro/) - 完整版中文站点
|
||||
|
||||
测试账号: vben/123456
|
||||
测试账号:vben/123456
|
||||
|
||||
<p align="center">
|
||||
<img alt="VbenAdmin Logo" width="100%" src="https://anncwb.github.io/anncwb/images/preview1.png">
|
||||
<img alt="VbenAdmin Logo" width="100%" src="https://anncwb.github.io/anncwb/images/preview2.png">
|
||||
<img alt="VbenAdmin Logo" width="100%" src="https://anncwb.github.io/anncwb/images/preview3.png">
|
||||
</p>
|
||||
<div align="center">
|
||||
<img alt="VbenAdmin Logo" width="100%" src="https://anncwb.github.io/anncwb/images/preview1.png">
|
||||
<img alt="VbenAdmin Logo" width="100%" src="https://anncwb.github.io/anncwb/images/preview2.png">
|
||||
<img alt="VbenAdmin Logo" width="100%" src="https://anncwb.github.io/anncwb/images/preview3.png">
|
||||
</div>
|
||||
|
||||
### 使用 Gitpod
|
||||
|
||||
在 Gitpod(适用于 GitHub 的免费在线开发环境)中打开项目,并立即开始编码.
|
||||
在 Gitpod(适用于 GitHub 的免费在线开发环境)中打开项目,并立即开始编码。
|
||||
|
||||
[](https://gitpod.io/#https://github.com/vbenjs/vue-vben-admin)
|
||||
|
||||
@@ -49,29 +54,27 @@ Vue Vben Admin 是 Vue Vben Admin 的升级版本。作为一个免费开源的
|
||||
|
||||
## 安装使用
|
||||
|
||||
- 获取项目代码
|
||||
1. 获取项目代码
|
||||
|
||||
```bash
|
||||
git clone https://github.com/vbenjs/vue-vben-admin.git
|
||||
```
|
||||
|
||||
- 安装依赖
|
||||
2. 安装依赖
|
||||
|
||||
```bash
|
||||
cd vue-vben-admin
|
||||
|
||||
corepack enable
|
||||
|
||||
npm i -g corepack
|
||||
pnpm install
|
||||
```
|
||||
|
||||
- 运行
|
||||
3. 运行
|
||||
|
||||
```bash
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
- 打包
|
||||
4. 打包
|
||||
|
||||
```bash
|
||||
pnpm build
|
||||
@@ -85,68 +88,66 @@ pnpm build
|
||||
|
||||
非常欢迎你的加入 或者提交一个 Pull Request。
|
||||
|
||||
**Pull Request:**
|
||||
**Pull Request 流程:**
|
||||
|
||||
1. Fork 代码!
|
||||
2. 创建自己的分支: `git checkout -b feature/xxxx`
|
||||
3. 提交你的修改: `git commit -am 'feat(function): add xxxxx'`
|
||||
4. 推送您的分支: `git push origin feature/xxxx`
|
||||
5. 提交`pull request`
|
||||
1. Fork 代码
|
||||
2. 创建自己的分支:`git checkout -b feature/xxxx`
|
||||
3. 提交你的修改:`git commit -am 'feat(function): add xxxxx'`
|
||||
4. 推送您的分支:`git push origin feature/xxxx`
|
||||
5. 提交 `pull request`
|
||||
|
||||
## Git 贡献提交规范
|
||||
|
||||
- 参考 [vue](https://github.com/vuejs/vue/blob/dev/.github/COMMIT_CONVENTION.md) 规范 ([Angular](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-angular))
|
||||
参考 [vue](https://github.com/vuejs/vue/blob/dev/.github/COMMIT_CONVENTION.md) 规范 ([Angular](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-angular))
|
||||
|
||||
- `feat` 增加新功能
|
||||
- `fix` 修复问题/BUG
|
||||
- `style` 代码风格相关无影响运行结果的
|
||||
- `perf` 优化/性能提升
|
||||
- `refactor` 重构
|
||||
- `revert` 撤销修改
|
||||
- `test` 测试相关
|
||||
- `docs` 文档/注释
|
||||
- `chore` 依赖更新/脚手架配置修改等
|
||||
- `ci` 持续集成
|
||||
- `types` 类型定义文件更改
|
||||
- `wip` 开发中
|
||||
- `feat` 增加新功能
|
||||
- `fix` 修复问题/BUG
|
||||
- `style` 代码风格相关无影响运行结果的
|
||||
- `perf` 优化/性能提升
|
||||
- `refactor` 重构
|
||||
- `revert` 撤销修改
|
||||
- `test` 测试相关
|
||||
- `docs` 文档/注释
|
||||
- `chore` 依赖更新/脚手架配置修改等
|
||||
- `ci` 持续集成
|
||||
- `types` 类型定义文件更改
|
||||
|
||||
## 浏览器支持
|
||||
|
||||
本地开发推荐使用`Chrome 80+` 浏览器
|
||||
本地开发推荐使用 `Chrome 80+` 浏览器
|
||||
|
||||
支持现代浏览器, 不支持 IE
|
||||
支持现代浏览器,不支持 IE
|
||||
|
||||
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt=" Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt=" Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari |
|
||||
| :-: | :-: | :-: | :-: | :-: |
|
||||
| not support | last 2 versions | last 2 versions | last 2 versions | last 2 versions |
|
||||
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari |
|
||||
| :-: | :-: | :-: | :-: |
|
||||
| last 2 versions | last 2 versions | last 2 versions | last 2 versions |
|
||||
|
||||
## 维护者
|
||||
|
||||
[@Vben](https://github.com/anncwb)
|
||||
|
||||
## Star History
|
||||
## Star 历史
|
||||
|
||||
[](https://star-history.com/#vbenjs/vue-vben-admin&Date)
|
||||
|
||||
## 捐赠
|
||||
|
||||
如果你觉得这个项目对你有帮助,你可以帮作者买一杯咖啡表示支持!
|
||||
如果你觉得这个项目对你有帮助,你可以帮作者买一杯咖啡表示支持!
|
||||
|
||||

|
||||
|
||||
<a style="display: block;width: 100px;height: 50px;line-height: 50px; color: #fff;text-align: center; background: #408aed;border-radius: 4px;" href="https://www.paypal.com/paypalme/cvvben">Paypal Me</a>
|
||||
|
||||
## Contributor
|
||||
## 贡献者
|
||||
|
||||
<a href="https://github.com/vbenjs/vue-vben-admin/graphs/contributors">
|
||||
<img alt="Contributors"
|
||||
src="https://opencollective.com/vbenjs/contributors.svg?button=false" />
|
||||
<img alt="Contributors" src="https://opencollective.com/vbenjs/contributors.svg?button=false" />
|
||||
</a>
|
||||
|
||||
## Discord
|
||||
|
||||
- [Github Discussions](https://github.com/anncwb/vue-vben-admin/discussions)
|
||||
|
||||
## License
|
||||
## 许可证
|
||||
|
||||
[MIT © Vben-2020](./LICENSE)
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/web-antd",
|
||||
"version": "5.5.5",
|
||||
"version": "5.5.6",
|
||||
"homepage": "https://vben.pro",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
@@ -73,8 +73,8 @@ const withDefaultPlaceholder = <T extends Component>(
|
||||
componentProps: Recordable<any> = {},
|
||||
) => {
|
||||
return defineComponent({
|
||||
inheritAttrs: false,
|
||||
name: component.name,
|
||||
inheritAttrs: false,
|
||||
setup: (props: any, { attrs, expose, slots }) => {
|
||||
const placeholder =
|
||||
props?.placeholder ||
|
||||
@@ -136,20 +136,34 @@ async function initComponentAdapter() {
|
||||
// 如果你的组件体积比较大,可以使用异步加载
|
||||
// Button: () =>
|
||||
// import('xxx').then((res) => res.Button),
|
||||
ApiSelect: withDefaultPlaceholder(ApiComponent, 'select', {
|
||||
component: Select,
|
||||
loadingSlot: 'suffixIcon',
|
||||
visibleEvent: 'onDropdownVisibleChange',
|
||||
modelPropName: 'value',
|
||||
}),
|
||||
ApiTreeSelect: withDefaultPlaceholder(ApiComponent, 'select', {
|
||||
component: TreeSelect,
|
||||
fieldNames: { label: 'label', value: 'value', children: 'children' },
|
||||
loadingSlot: 'suffixIcon',
|
||||
modelPropName: 'value',
|
||||
optionsPropName: 'treeData',
|
||||
visibleEvent: 'onVisibleChange',
|
||||
}),
|
||||
ApiSelect: withDefaultPlaceholder(
|
||||
{
|
||||
...ApiComponent,
|
||||
name: 'ApiSelect',
|
||||
},
|
||||
'select',
|
||||
{
|
||||
component: Select,
|
||||
loadingSlot: 'suffixIcon',
|
||||
visibleEvent: 'onDropdownVisibleChange',
|
||||
modelPropName: 'value',
|
||||
},
|
||||
),
|
||||
ApiTreeSelect: withDefaultPlaceholder(
|
||||
{
|
||||
...ApiComponent,
|
||||
name: 'ApiTreeSelect',
|
||||
},
|
||||
'select',
|
||||
{
|
||||
component: TreeSelect,
|
||||
fieldNames: { label: 'label', value: 'value', children: 'children' },
|
||||
loadingSlot: 'suffixIcon',
|
||||
modelPropName: 'value',
|
||||
optionsPropName: 'treeData',
|
||||
visibleEvent: 'onVisibleChange',
|
||||
},
|
||||
),
|
||||
AutoComplete,
|
||||
Checkbox,
|
||||
CheckboxGroup,
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import type { Router } from 'vue-router';
|
||||
|
||||
import { DEFAULT_HOME_PATH, LOGIN_PATH } from '@vben/constants';
|
||||
import { LOGIN_PATH } from '@vben/constants';
|
||||
import { preferences } from '@vben/preferences';
|
||||
import { useAccessStore, useUserStore } from '@vben/stores';
|
||||
import { startProgress, stopProgress } from '@vben/utils';
|
||||
@@ -18,7 +18,7 @@ function setupCommonGuard(router: Router) {
|
||||
// 记录已经加载的页面
|
||||
const loadedPaths = new Set<string>();
|
||||
|
||||
router.beforeEach(async (to) => {
|
||||
router.beforeEach((to) => {
|
||||
to.meta.loaded = loadedPaths.has(to.path);
|
||||
|
||||
// 页面加载进度条
|
||||
@@ -56,7 +56,7 @@ function setupAccessGuard(router: Router) {
|
||||
return decodeURIComponent(
|
||||
(to.query?.redirect as string) ||
|
||||
userStore.userInfo?.homePath ||
|
||||
DEFAULT_HOME_PATH,
|
||||
preferences.app.defaultHomePath,
|
||||
);
|
||||
}
|
||||
return true;
|
||||
@@ -75,7 +75,7 @@ function setupAccessGuard(router: Router) {
|
||||
path: LOGIN_PATH,
|
||||
// 如不需要,直接删除 query
|
||||
query:
|
||||
to.fullPath === DEFAULT_HOME_PATH
|
||||
to.fullPath === preferences.app.defaultHomePath
|
||||
? {}
|
||||
: { redirect: encodeURIComponent(to.fullPath) },
|
||||
// 携带当前跳转的页面,登录后重新跳转该页面
|
||||
@@ -108,8 +108,8 @@ function setupAccessGuard(router: Router) {
|
||||
accessStore.setAccessRoutes(accessibleRoutes);
|
||||
accessStore.setIsAccessChecked(true);
|
||||
const redirectPath = (from.query.redirect ??
|
||||
(to.path === DEFAULT_HOME_PATH
|
||||
? userInfo.homePath || DEFAULT_HOME_PATH
|
||||
(to.path === preferences.app.defaultHomePath
|
||||
? userInfo.homePath || preferences.app.defaultHomePath
|
||||
: to.fullPath)) as string;
|
||||
|
||||
return {
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import type { RouteRecordRaw } from 'vue-router';
|
||||
|
||||
import { DEFAULT_HOME_PATH, LOGIN_PATH } from '@vben/constants';
|
||||
import { LOGIN_PATH } from '@vben/constants';
|
||||
import { preferences } from '@vben/preferences';
|
||||
|
||||
import { $t } from '#/locales';
|
||||
|
||||
@@ -34,7 +35,7 @@ const coreRoutes: RouteRecordRaw[] = [
|
||||
},
|
||||
name: 'Root',
|
||||
path: '/',
|
||||
redirect: DEFAULT_HOME_PATH,
|
||||
redirect: preferences.app.defaultHomePath,
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
|
@@ -3,7 +3,8 @@ import type { Recordable, UserInfo } from '@vben/types';
|
||||
import { ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
import { DEFAULT_HOME_PATH, LOGIN_PATH } from '@vben/constants';
|
||||
import { LOGIN_PATH } from '@vben/constants';
|
||||
import { preferences } from '@vben/preferences';
|
||||
import { resetAllStores, useAccessStore, useUserStore } from '@vben/stores';
|
||||
|
||||
import { notification } from 'ant-design-vue';
|
||||
@@ -54,7 +55,9 @@ export const useAuthStore = defineStore('auth', () => {
|
||||
} else {
|
||||
onSuccess
|
||||
? await onSuccess?.()
|
||||
: await router.push(userInfo.homePath || DEFAULT_HOME_PATH);
|
||||
: await router.push(
|
||||
userInfo.homePath || preferences.app.defaultHomePath,
|
||||
);
|
||||
}
|
||||
|
||||
if (userInfo?.realName) {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/web-ele",
|
||||
"version": "5.5.5",
|
||||
"version": "5.5.6",
|
||||
"homepage": "https://vben.pro",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
@@ -130,8 +130,8 @@ const withDefaultPlaceholder = <T extends Component>(
|
||||
componentProps: Recordable<any> = {},
|
||||
) => {
|
||||
return defineComponent({
|
||||
inheritAttrs: false,
|
||||
name: component.name,
|
||||
inheritAttrs: false,
|
||||
setup: (props: any, { attrs, expose, slots }) => {
|
||||
const placeholder =
|
||||
props?.placeholder ||
|
||||
@@ -184,19 +184,33 @@ async function initComponentAdapter() {
|
||||
// 如果你的组件体积比较大,可以使用异步加载
|
||||
// Button: () =>
|
||||
// import('xxx').then((res) => res.Button),
|
||||
ApiSelect: withDefaultPlaceholder(ApiComponent, 'select', {
|
||||
component: ElSelectV2,
|
||||
loadingSlot: 'loading',
|
||||
visibleEvent: 'onVisibleChange',
|
||||
}),
|
||||
ApiTreeSelect: withDefaultPlaceholder(ApiComponent, 'select', {
|
||||
component: ElTreeSelect,
|
||||
props: { label: 'label', children: 'children' },
|
||||
nodeKey: 'value',
|
||||
loadingSlot: 'loading',
|
||||
optionsPropName: 'data',
|
||||
visibleEvent: 'onVisibleChange',
|
||||
}),
|
||||
ApiSelect: withDefaultPlaceholder(
|
||||
{
|
||||
...ApiComponent,
|
||||
name: 'ApiSelect',
|
||||
},
|
||||
'select',
|
||||
{
|
||||
component: ElSelectV2,
|
||||
loadingSlot: 'loading',
|
||||
visibleEvent: 'onVisibleChange',
|
||||
},
|
||||
),
|
||||
ApiTreeSelect: withDefaultPlaceholder(
|
||||
{
|
||||
...ApiComponent,
|
||||
name: 'ApiTreeSelect',
|
||||
},
|
||||
'select',
|
||||
{
|
||||
component: ElTreeSelect,
|
||||
props: { label: 'label', children: 'children' },
|
||||
nodeKey: 'value',
|
||||
loadingSlot: 'loading',
|
||||
optionsPropName: 'data',
|
||||
visibleEvent: 'onVisibleChange',
|
||||
},
|
||||
),
|
||||
Checkbox: ElCheckbox,
|
||||
CheckboxGroup: (props, { attrs, slots }) => {
|
||||
let defaultSlot;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import type { Router } from 'vue-router';
|
||||
|
||||
import { DEFAULT_HOME_PATH, LOGIN_PATH } from '@vben/constants';
|
||||
import { LOGIN_PATH } from '@vben/constants';
|
||||
import { preferences } from '@vben/preferences';
|
||||
import { useAccessStore, useUserStore } from '@vben/stores';
|
||||
import { startProgress, stopProgress } from '@vben/utils';
|
||||
@@ -18,7 +18,7 @@ function setupCommonGuard(router: Router) {
|
||||
// 记录已经加载的页面
|
||||
const loadedPaths = new Set<string>();
|
||||
|
||||
router.beforeEach(async (to) => {
|
||||
router.beforeEach((to) => {
|
||||
to.meta.loaded = loadedPaths.has(to.path);
|
||||
|
||||
// 页面加载进度条
|
||||
@@ -56,7 +56,7 @@ function setupAccessGuard(router: Router) {
|
||||
return decodeURIComponent(
|
||||
(to.query?.redirect as string) ||
|
||||
userStore.userInfo?.homePath ||
|
||||
DEFAULT_HOME_PATH,
|
||||
preferences.app.defaultHomePath,
|
||||
);
|
||||
}
|
||||
return true;
|
||||
@@ -75,7 +75,7 @@ function setupAccessGuard(router: Router) {
|
||||
path: LOGIN_PATH,
|
||||
// 如不需要,直接删除 query
|
||||
query:
|
||||
to.fullPath === DEFAULT_HOME_PATH
|
||||
to.fullPath === preferences.app.defaultHomePath
|
||||
? {}
|
||||
: { redirect: encodeURIComponent(to.fullPath) },
|
||||
// 携带当前跳转的页面,登录后重新跳转该页面
|
||||
@@ -108,8 +108,8 @@ function setupAccessGuard(router: Router) {
|
||||
accessStore.setAccessRoutes(accessibleRoutes);
|
||||
accessStore.setIsAccessChecked(true);
|
||||
const redirectPath = (from.query.redirect ??
|
||||
(to.path === DEFAULT_HOME_PATH
|
||||
? userInfo.homePath || DEFAULT_HOME_PATH
|
||||
(to.path === preferences.app.defaultHomePath
|
||||
? userInfo.homePath || preferences.app.defaultHomePath
|
||||
: to.fullPath)) as string;
|
||||
|
||||
return {
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import type { RouteRecordRaw } from 'vue-router';
|
||||
|
||||
import { DEFAULT_HOME_PATH, LOGIN_PATH } from '@vben/constants';
|
||||
import { LOGIN_PATH } from '@vben/constants';
|
||||
import { preferences } from '@vben/preferences';
|
||||
|
||||
import { $t } from '#/locales';
|
||||
|
||||
@@ -34,7 +35,7 @@ const coreRoutes: RouteRecordRaw[] = [
|
||||
},
|
||||
name: 'Root',
|
||||
path: '/',
|
||||
redirect: DEFAULT_HOME_PATH,
|
||||
redirect: preferences.app.defaultHomePath,
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
|
@@ -3,7 +3,8 @@ import type { Recordable, UserInfo } from '@vben/types';
|
||||
import { ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
import { DEFAULT_HOME_PATH, LOGIN_PATH } from '@vben/constants';
|
||||
import { LOGIN_PATH } from '@vben/constants';
|
||||
import { preferences } from '@vben/preferences';
|
||||
import { resetAllStores, useAccessStore, useUserStore } from '@vben/stores';
|
||||
|
||||
import { ElNotification } from 'element-plus';
|
||||
@@ -55,7 +56,9 @@ export const useAuthStore = defineStore('auth', () => {
|
||||
} else {
|
||||
onSuccess
|
||||
? await onSuccess?.()
|
||||
: await router.push(userInfo.homePath || DEFAULT_HOME_PATH);
|
||||
: await router.push(
|
||||
userInfo.homePath || preferences.app.defaultHomePath,
|
||||
);
|
||||
}
|
||||
|
||||
if (userInfo?.realName) {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/web-naive",
|
||||
"version": "5.5.5",
|
||||
"version": "5.5.6",
|
||||
"homepage": "https://vben.pro",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
@@ -76,8 +76,8 @@ const withDefaultPlaceholder = <T extends Component>(
|
||||
componentProps: Recordable<any> = {},
|
||||
) => {
|
||||
return defineComponent({
|
||||
inheritAttrs: false,
|
||||
name: component.name,
|
||||
inheritAttrs: false,
|
||||
setup: (props: any, { attrs, expose, slots }) => {
|
||||
const placeholder =
|
||||
props?.placeholder ||
|
||||
@@ -131,19 +131,33 @@ async function initComponentAdapter() {
|
||||
// Button: () =>
|
||||
// import('xxx').then((res) => res.Button),
|
||||
|
||||
ApiSelect: withDefaultPlaceholder(ApiComponent, 'select', {
|
||||
component: NSelect,
|
||||
modelPropName: 'value',
|
||||
}),
|
||||
ApiTreeSelect: withDefaultPlaceholder(ApiComponent, 'select', {
|
||||
component: NTreeSelect,
|
||||
nodeKey: 'value',
|
||||
loadingSlot: 'arrow',
|
||||
keyField: 'value',
|
||||
modelPropName: 'value',
|
||||
optionsPropName: 'options',
|
||||
visibleEvent: 'onVisibleChange',
|
||||
}),
|
||||
ApiSelect: withDefaultPlaceholder(
|
||||
{
|
||||
...ApiComponent,
|
||||
name: 'ApiSelect',
|
||||
},
|
||||
'select',
|
||||
{
|
||||
component: NSelect,
|
||||
modelPropName: 'value',
|
||||
},
|
||||
),
|
||||
ApiTreeSelect: withDefaultPlaceholder(
|
||||
{
|
||||
...ApiComponent,
|
||||
name: 'ApiTreeSelect',
|
||||
},
|
||||
'select',
|
||||
{
|
||||
component: NTreeSelect,
|
||||
nodeKey: 'value',
|
||||
loadingSlot: 'arrow',
|
||||
keyField: 'value',
|
||||
modelPropName: 'value',
|
||||
optionsPropName: 'options',
|
||||
visibleEvent: 'onVisibleChange',
|
||||
},
|
||||
),
|
||||
Checkbox: NCheckbox,
|
||||
CheckboxGroup: (props, { attrs, slots }) => {
|
||||
let defaultSlot;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import type { Router } from 'vue-router';
|
||||
|
||||
import { DEFAULT_HOME_PATH, LOGIN_PATH } from '@vben/constants';
|
||||
import { LOGIN_PATH } from '@vben/constants';
|
||||
import { preferences } from '@vben/preferences';
|
||||
import { useAccessStore, useUserStore } from '@vben/stores';
|
||||
import { startProgress, stopProgress } from '@vben/utils';
|
||||
@@ -18,7 +18,7 @@ function setupCommonGuard(router: Router) {
|
||||
// 记录已经加载的页面
|
||||
const loadedPaths = new Set<string>();
|
||||
|
||||
router.beforeEach(async (to) => {
|
||||
router.beforeEach((to) => {
|
||||
to.meta.loaded = loadedPaths.has(to.path);
|
||||
|
||||
// 页面加载进度条
|
||||
@@ -56,7 +56,7 @@ function setupAccessGuard(router: Router) {
|
||||
return decodeURIComponent(
|
||||
(to.query?.redirect as string) ||
|
||||
userStore.userInfo?.homePath ||
|
||||
DEFAULT_HOME_PATH,
|
||||
preferences.app.defaultHomePath,
|
||||
);
|
||||
}
|
||||
return true;
|
||||
@@ -75,7 +75,7 @@ function setupAccessGuard(router: Router) {
|
||||
path: LOGIN_PATH,
|
||||
// 如不需要,直接删除 query
|
||||
query:
|
||||
to.fullPath === DEFAULT_HOME_PATH
|
||||
to.fullPath === preferences.app.defaultHomePath
|
||||
? {}
|
||||
: { redirect: encodeURIComponent(to.fullPath) },
|
||||
// 携带当前跳转的页面,登录后重新跳转该页面
|
||||
@@ -107,8 +107,8 @@ function setupAccessGuard(router: Router) {
|
||||
accessStore.setAccessRoutes(accessibleRoutes);
|
||||
accessStore.setIsAccessChecked(true);
|
||||
const redirectPath = (from.query.redirect ??
|
||||
(to.path === DEFAULT_HOME_PATH
|
||||
? userInfo.homePath || DEFAULT_HOME_PATH
|
||||
(to.path === preferences.app.defaultHomePath
|
||||
? userInfo.homePath || preferences.app.defaultHomePath
|
||||
: to.fullPath)) as string;
|
||||
|
||||
return {
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import type { RouteRecordRaw } from 'vue-router';
|
||||
|
||||
import { DEFAULT_HOME_PATH, LOGIN_PATH } from '@vben/constants';
|
||||
import { LOGIN_PATH } from '@vben/constants';
|
||||
import { preferences } from '@vben/preferences';
|
||||
|
||||
import { $t } from '#/locales';
|
||||
|
||||
@@ -34,7 +35,7 @@ const coreRoutes: RouteRecordRaw[] = [
|
||||
},
|
||||
name: 'Root',
|
||||
path: '/',
|
||||
redirect: DEFAULT_HOME_PATH,
|
||||
redirect: preferences.app.defaultHomePath,
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
|
@@ -3,7 +3,8 @@ import type { Recordable, UserInfo } from '@vben/types';
|
||||
import { ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
import { DEFAULT_HOME_PATH, LOGIN_PATH } from '@vben/constants';
|
||||
import { LOGIN_PATH } from '@vben/constants';
|
||||
import { preferences } from '@vben/preferences';
|
||||
import { resetAllStores, useAccessStore, useUserStore } from '@vben/stores';
|
||||
|
||||
import { defineStore } from 'pinia';
|
||||
@@ -55,7 +56,9 @@ export const useAuthStore = defineStore('auth', () => {
|
||||
} else {
|
||||
onSuccess
|
||||
? await onSuccess?.()
|
||||
: await router.push(userInfo.homePath || DEFAULT_HOME_PATH);
|
||||
: await router.push(
|
||||
userInfo.homePath || preferences.app.defaultHomePath,
|
||||
);
|
||||
}
|
||||
|
||||
if (userInfo?.realName) {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/docs",
|
||||
"version": "5.5.5",
|
||||
"version": "5.5.6",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "vitepress build",
|
||||
|
@@ -78,7 +78,7 @@ const [Drawer, drawerApi] = useVbenDrawer({
|
||||
| --- | --- | --- | --- |
|
||||
| appendToMain | 是否挂载到内容区域(默认挂载到body) | `boolean` | `false` |
|
||||
| connectedComponent | 连接另一个Modal组件 | `Component` | - |
|
||||
| destroyOnClose | 关闭时销毁`connectedComponent` | `boolean` | `false` |
|
||||
| destroyOnClose | 关闭时销毁 | `boolean` | `false` |
|
||||
| title | 标题 | `string\|slot` | - |
|
||||
| titleTooltip | 标题提示信息 | `string\|slot` | - |
|
||||
| description | 描述信息 | `string\|slot` | - |
|
||||
|
@@ -98,8 +98,8 @@ The execution command is: `pnpm run [script]` or `npm run [script]`.
|
||||
"postinstall": "pnpm -r run stub --if-present",
|
||||
// Only allow using pnpm
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
// Install husky
|
||||
"prepare": "is-ci || husky",
|
||||
// Install lefthook
|
||||
"prepare": "is-ci || lefthook install",
|
||||
// Preview the application
|
||||
"preview": "turbo-run preview",
|
||||
// Package specification check
|
||||
|
@@ -60,6 +60,29 @@ VITE_INJECT_APP_LOADING=true
|
||||
VITE_ARCHIVER=true
|
||||
```
|
||||
|
||||
```bash [.env.production]
|
||||
# Public Path for Resources, must start and end with /
|
||||
VITE_BASE=/
|
||||
|
||||
# API URL
|
||||
VITE_GLOB_API_URL=https://mock-napi.vben.pro/api
|
||||
|
||||
# Whether to enable compression, can be set to none, brotli, gzip
|
||||
VITE_COMPRESS=gzip
|
||||
|
||||
# Whether to enable PWA
|
||||
VITE_PWA=false
|
||||
|
||||
# vue-router mode
|
||||
VITE_ROUTER_HISTORY=hash
|
||||
|
||||
# Whether to inject global loading
|
||||
VITE_INJECT_APP_LOADING=true
|
||||
|
||||
# Whether to generate dist.zip after packaging
|
||||
VITE_ARCHIVER=true
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
## Dynamic Configuration in Production Environment
|
||||
@@ -142,6 +165,7 @@ import { defineOverridesPreferences } from '@vben/preferences';
|
||||
/**
|
||||
* @description Project configuration file
|
||||
* Only a part of the configuration in the project needs to be covered, and unnecessary configurations do not need to be covered. The default configuration will be automatically used
|
||||
* !!! Please clear the cache after changing the configuration, otherwise it may not take effect
|
||||
*/
|
||||
export const overridesPreferences = defineOverridesPreferences({
|
||||
// overrides
|
||||
@@ -164,6 +188,7 @@ const defaultPreferences: Preferences = {
|
||||
contentCompact: 'wide',
|
||||
defaultAvatar:
|
||||
'https://unpkg.com/@vbenjs/static-source@0.1.7/source/avatar-v1.webp',
|
||||
defaultHomePath: '/analytics',
|
||||
dynamicTitle: true,
|
||||
enableCheckUpdates: true,
|
||||
enablePreferences: true,
|
||||
@@ -171,7 +196,7 @@ const defaultPreferences: Preferences = {
|
||||
isMobile: false,
|
||||
layout: 'sidebar-nav',
|
||||
locale: 'zh-CN',
|
||||
loginExpiredMode: 'modal',
|
||||
loginExpiredMode: 'page',
|
||||
name: 'Vben Admin',
|
||||
preferencesButtonPosition: 'auto',
|
||||
watermark: false,
|
||||
@@ -190,14 +215,16 @@ const defaultPreferences: Preferences = {
|
||||
enable: true,
|
||||
icp: '',
|
||||
icpLink: '',
|
||||
settingShow: true,
|
||||
},
|
||||
footer: {
|
||||
enable: true,
|
||||
enable: false,
|
||||
fixed: false,
|
||||
},
|
||||
header: {
|
||||
enable: true,
|
||||
hidden: false,
|
||||
menuAlign: 'start',
|
||||
mode: 'fixed',
|
||||
},
|
||||
logo: {
|
||||
@@ -219,23 +246,28 @@ const defaultPreferences: Preferences = {
|
||||
sidebar: {
|
||||
autoActivateChild: false,
|
||||
collapsed: false,
|
||||
collapsedButton: true,
|
||||
collapsedShowTitle: false,
|
||||
enable: true,
|
||||
expandOnHover: true,
|
||||
extraCollapse: true,
|
||||
extraCollapse: false,
|
||||
fixedButton: true,
|
||||
hidden: false,
|
||||
width: 230,
|
||||
width: 224,
|
||||
},
|
||||
tabbar: {
|
||||
draggable: true,
|
||||
enable: true,
|
||||
height: 36,
|
||||
height: 38,
|
||||
keepAlive: true,
|
||||
maxCount: 0,
|
||||
middleClickToClose: false,
|
||||
persist: true,
|
||||
showIcon: true,
|
||||
showMaximize: true,
|
||||
showMore: true,
|
||||
styleType: 'chrome',
|
||||
wheelable: true,
|
||||
},
|
||||
theme: {
|
||||
builtinType: 'default',
|
||||
@@ -246,7 +278,7 @@ const defaultPreferences: Preferences = {
|
||||
mode: 'dark',
|
||||
radius: '0.5',
|
||||
semiDarkHeader: false,
|
||||
semiDarkSidebar: true,
|
||||
semiDarkSidebar: false,
|
||||
},
|
||||
transition: {
|
||||
enable: true,
|
||||
@@ -260,9 +292,9 @@ const defaultPreferences: Preferences = {
|
||||
languageToggle: true,
|
||||
lockScreen: true,
|
||||
notification: true,
|
||||
refresh: true,
|
||||
sidebarToggle: true,
|
||||
themeToggle: true,
|
||||
refresh: true,
|
||||
},
|
||||
};
|
||||
```
|
||||
@@ -289,6 +321,8 @@ interface AppPreferences {
|
||||
contentCompact: ContentCompactType;
|
||||
// /** Default application avatar */
|
||||
defaultAvatar: string;
|
||||
/** Default homepage path */
|
||||
defaultHomePath: string;
|
||||
// /** Enable dynamic title */
|
||||
dynamicTitle: boolean;
|
||||
/** Whether to enable update checks */
|
||||
@@ -342,6 +376,8 @@ interface CopyrightPreferences {
|
||||
icp: string;
|
||||
/** Link to the ICP */
|
||||
icpLink: string;
|
||||
/** Whether to show in settings panel */
|
||||
settingShow?: boolean;
|
||||
}
|
||||
|
||||
interface FooterPreferences {
|
||||
@@ -356,6 +392,8 @@ interface HeaderPreferences {
|
||||
enable: boolean;
|
||||
/** Whether the header is hidden, css-hidden */
|
||||
hidden: boolean;
|
||||
/** Header menu alignment */
|
||||
menuAlign: LayoutHeaderMenuAlignType;
|
||||
/** Header display mode */
|
||||
mode: LayoutHeaderModeType;
|
||||
}
|
||||
@@ -376,8 +414,12 @@ interface NavigationPreferences {
|
||||
styleType: NavigationStyleType;
|
||||
}
|
||||
interface SidebarPreferences {
|
||||
/** Automatically activate child menu when clicking on directory */
|
||||
autoActivateChild: boolean;
|
||||
/** Whether the sidebar is collapsed */
|
||||
collapsed: boolean;
|
||||
/** Whether the sidebar collapse button is visible */
|
||||
collapsedButton: boolean;
|
||||
/** Whether to show title when sidebar is collapsed */
|
||||
collapsedShowTitle: boolean;
|
||||
/** Whether the sidebar is visible */
|
||||
@@ -386,6 +428,8 @@ interface SidebarPreferences {
|
||||
expandOnHover: boolean;
|
||||
/** Whether the sidebar extension area is collapsed */
|
||||
extraCollapse: boolean;
|
||||
/** Whether the sidebar fixed button is visible */
|
||||
fixedButton: boolean;
|
||||
/** Whether the sidebar is hidden - css */
|
||||
hidden: boolean;
|
||||
/** Sidebar width */
|
||||
@@ -414,6 +458,10 @@ interface TabbarPreferences {
|
||||
height: number;
|
||||
/** Whether tab caching is enabled */
|
||||
keepAlive: boolean;
|
||||
/** Maximum number of tabs */
|
||||
maxCount: number;
|
||||
/** Whether to close tab when middle-clicked */
|
||||
middleClickToClose: boolean;
|
||||
/** Whether tabs are persistent */
|
||||
persist: boolean;
|
||||
/** Whether icons in multiple tabs are enabled */
|
||||
@@ -424,6 +472,8 @@ interface TabbarPreferences {
|
||||
showMore: boolean;
|
||||
/** Tab style */
|
||||
styleType: TabsStyleType;
|
||||
/** Whether mouse wheel response is enabled */
|
||||
wheelable: boolean;
|
||||
}
|
||||
interface ThemePreferences {
|
||||
/** Built-in theme name */
|
||||
@@ -511,5 +561,6 @@ interface Preferences {
|
||||
|
||||
- The `overridesPreferences` method only needs to override a part of the configurations in the project. There's no need to override configurations that are not needed; they will automatically use the default settings.
|
||||
- Any configuration item can be overridden. You just need to override it within the `overridesPreferences` method. Do not modify the default configuration file.
|
||||
- Please clear the cache after changing the configuration, otherwise it may not take effect.
|
||||
|
||||
:::
|
||||
|
@@ -58,7 +58,7 @@ Open a terminal in your code directory and execute the following commands:
|
||||
cd vue-vben-admin
|
||||
|
||||
# Enable the project-specified version of pnpm
|
||||
corepack enable
|
||||
npm i -g corepack
|
||||
|
||||
# Install dependencies
|
||||
pnpm install
|
||||
|
@@ -18,7 +18,7 @@ If you encounter a problem, you can start looking from the following aspects:
|
||||
|
||||
## Dependency Issues
|
||||
|
||||
In a `Monorepo` project, it is necessary to develop the habit of executing `pnpm install` every time you `git pull` the code, as new dependency packages are often added. The project has already configured automatic execution of `pnpm install` in `.husky/git-merge`, but sometimes there might be issues. If it does not execute automatically, it is recommended to execute it manually once.
|
||||
In a `Monorepo` project, it's important to get into the habit of running `pnpm install` after every `git pull` because new dependencies are often added. The project has configured automatic execution of `pnpm install` in `lefthook.yml`, but sometimes there might be issues. If it does not execute automatically, it is recommended to execute it manually once.
|
||||
|
||||
## About Cache Update Issues
|
||||
|
||||
|
@@ -33,8 +33,8 @@ The project integrates the following code verification tools:
|
||||
- [Prettier](https://prettier.io/) for code formatting
|
||||
- [Commitlint](https://commitlint.js.org/) for checking the standard of git commit messages
|
||||
- [Publint](https://publint.dev/) for checking the standard of npm packages
|
||||
- [Lint Staged](https://github.com/lint-staged/lint-staged) for running code verification before git commits
|
||||
- [Cspell](https://cspell.org/) for checking spelling errors
|
||||
- [lefthook](https://github.com/evilmartians/lefthook) for managing Git hooks, automatically running code checks and formatting before commits
|
||||
|
||||
## ESLint
|
||||
|
||||
@@ -148,18 +148,66 @@ The cspell configuration file is `cspell.json`, which can be modified according
|
||||
|
||||
Git hooks are generally combined with various lints to check code style during git commits. If the check fails, the commit will not proceed. Developers need to modify and resubmit.
|
||||
|
||||
### husky
|
||||
### lefthook
|
||||
|
||||
One issue is that the check will verify all code, but we only want to check the code we are committing. This is where husky comes in.
|
||||
One issue is that the check will verify all code, but we only want to check the code we are committing. This is where lefthook comes in.
|
||||
|
||||
The most effective solution is to perform Lint checks locally before committing. A common practice is to use husky or pre-commit to perform a Lint check before local submission.
|
||||
The most effective solution is to perform Lint checks locally before committing. A common practice is to use lefthook to perform a Lint check before local submission.
|
||||
|
||||
The project defines corresponding hooks inside `.husky`.
|
||||
The project defines corresponding hooks inside `lefthook.yml`:
|
||||
|
||||
#### How to Disable Husky
|
||||
- `pre-commit`: Runs before commit, used for code formatting and checking
|
||||
|
||||
If you want to disable Husky, simply delete the .husky directory.
|
||||
- `code-workspace`: Updates VSCode workspace configuration
|
||||
- `lint-md`: Formats Markdown files
|
||||
- `lint-vue`: Formats and checks Vue files
|
||||
- `lint-js`: Formats and checks JavaScript/TypeScript files
|
||||
- `lint-style`: Formats and checks style files
|
||||
- `lint-package`: Formats package.json
|
||||
- `lint-json`: Formats other JSON files
|
||||
|
||||
### lint-staged
|
||||
- `post-merge`: Runs after merge, used for automatic dependency installation
|
||||
|
||||
Used for automatically fixing style issues of committed files. Its configuration file is `.lintstagedrc.mjs`, which can be modified according to project needs.
|
||||
- `install`: Runs `pnpm install` to install new dependencies
|
||||
|
||||
- `commit-msg`: Runs during commit, used for checking commit message format
|
||||
- `commitlint`: Uses commitlint to check commit messages
|
||||
|
||||
#### How to Disable lefthook
|
||||
|
||||
If you want to disable lefthook, there are two ways:
|
||||
|
||||
::: code-group
|
||||
|
||||
```bash [Temporary disable]
|
||||
git commit -m 'feat: add home page' --no-verify
|
||||
```
|
||||
|
||||
```bash [Permanent disable]
|
||||
# Simply delete the lefthook.yml file
|
||||
rm lefthook.yml
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
#### How to Modify lefthook Configuration
|
||||
|
||||
If you want to modify lefthook's configuration, you can edit the `lefthook.yml` file. For example:
|
||||
|
||||
```yaml
|
||||
pre-commit:
|
||||
parallel: true # Execute tasks in parallel
|
||||
jobs:
|
||||
- name: lint-js
|
||||
run: pnpm prettier --cache --ignore-unknown --write {staged_files}
|
||||
glob: '*.{js,jsx,ts,tsx}'
|
||||
```
|
||||
|
||||
Where:
|
||||
|
||||
- `parallel`: Whether to execute tasks in parallel
|
||||
- `jobs`: Defines the list of tasks to execute
|
||||
- `name`: Task name
|
||||
- `run`: Command to execute
|
||||
- `glob`: File pattern to match
|
||||
- `{staged_files}`: Represents the list of staged files
|
||||
|
@@ -98,8 +98,8 @@ npm 脚本是项目常见的配置,用于执行一些常见的任务,比如
|
||||
"postinstall": "pnpm -r run stub --if-present",
|
||||
// 只允许使用pnpm
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
// husky的安装
|
||||
"prepare": "is-ci || husky",
|
||||
// lefthook的安装
|
||||
"prepare": "is-ci || lefthook install",
|
||||
// 预览应用
|
||||
"preview": "turbo-run preview",
|
||||
// 包规范检查
|
||||
|
@@ -339,6 +339,10 @@ interface RouteMeta {
|
||||
| 'success'
|
||||
| 'warning'
|
||||
| string;
|
||||
/**
|
||||
* 路由的完整路径作为key(默认true)
|
||||
*/
|
||||
fullPathKey?: boolean;
|
||||
/**
|
||||
* 当前路由的子级在菜单中不展现
|
||||
* @default false
|
||||
@@ -502,6 +506,13 @@ interface RouteMeta {
|
||||
|
||||
用于配置页面的徽标颜色。
|
||||
|
||||
### fullPathKey
|
||||
|
||||
- 类型:`boolean`
|
||||
- 默认值:`true`
|
||||
|
||||
是否将路由的完整路径作为tab key(默认true)
|
||||
|
||||
### activePath
|
||||
|
||||
- 类型:`string`
|
||||
@@ -602,3 +613,32 @@ const { refresh } = useRefresh();
|
||||
refresh();
|
||||
</script>
|
||||
```
|
||||
|
||||
## 标签页与路由控制
|
||||
|
||||
在某些场景下,需要单个路由打开多个标签页,或者修改路由的query不打开新的标签页
|
||||
|
||||
每个标签页Tab使用唯一的key标识,设置Tab key有三种方式,优先级由高到低:
|
||||
|
||||
- 使用路由query参数pageKey
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import { useRouter } from 'vue-router';
|
||||
// 跳转路由
|
||||
const router = useRouter();
|
||||
router.push({
|
||||
path: 'path',
|
||||
query: {
|
||||
pageKey: 'key',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
- 路由的完整路径作为key
|
||||
|
||||
`meta` 属性中的 `fullPathKey`不为false,则使用路由`fullPath`作为key
|
||||
|
||||
- 路由的path作为key
|
||||
|
||||
`meta` 属性中的 `fullPathKey`为false,则使用路由`path`作为key
|
||||
|
@@ -187,6 +187,7 @@ const defaultPreferences: Preferences = {
|
||||
contentCompact: 'wide',
|
||||
defaultAvatar:
|
||||
'https://unpkg.com/@vbenjs/static-source@0.1.7/source/avatar-v1.webp',
|
||||
defaultHomePath: '/analytics',
|
||||
dynamicTitle: true,
|
||||
enableCheckUpdates: true,
|
||||
enablePreferences: true,
|
||||
@@ -194,7 +195,7 @@ const defaultPreferences: Preferences = {
|
||||
isMobile: false,
|
||||
layout: 'sidebar-nav',
|
||||
locale: 'zh-CN',
|
||||
loginExpiredMode: 'modal',
|
||||
loginExpiredMode: 'page',
|
||||
name: 'Vben Admin',
|
||||
preferencesButtonPosition: 'auto',
|
||||
watermark: false,
|
||||
@@ -213,14 +214,16 @@ const defaultPreferences: Preferences = {
|
||||
enable: true,
|
||||
icp: '',
|
||||
icpLink: '',
|
||||
settingShow: true,
|
||||
},
|
||||
footer: {
|
||||
enable: true,
|
||||
enable: false,
|
||||
fixed: false,
|
||||
},
|
||||
header: {
|
||||
enable: true,
|
||||
hidden: false,
|
||||
menuAlign: 'start',
|
||||
mode: 'fixed',
|
||||
},
|
||||
logo: {
|
||||
@@ -242,23 +245,28 @@ const defaultPreferences: Preferences = {
|
||||
sidebar: {
|
||||
autoActivateChild: false,
|
||||
collapsed: false,
|
||||
collapsedButton: true,
|
||||
collapsedShowTitle: false,
|
||||
enable: true,
|
||||
expandOnHover: true,
|
||||
extraCollapse: true,
|
||||
extraCollapse: false,
|
||||
fixedButton: true,
|
||||
hidden: false,
|
||||
width: 230,
|
||||
width: 224,
|
||||
},
|
||||
tabbar: {
|
||||
draggable: true,
|
||||
enable: true,
|
||||
height: 36,
|
||||
height: 38,
|
||||
keepAlive: true,
|
||||
maxCount: 0,
|
||||
middleClickToClose: false,
|
||||
persist: true,
|
||||
showIcon: true,
|
||||
showMaximize: true,
|
||||
showMore: true,
|
||||
styleType: 'chrome',
|
||||
wheelable: true,
|
||||
},
|
||||
theme: {
|
||||
builtinType: 'default',
|
||||
@@ -269,7 +277,7 @@ const defaultPreferences: Preferences = {
|
||||
mode: 'dark',
|
||||
radius: '0.5',
|
||||
semiDarkHeader: false,
|
||||
semiDarkSidebar: true,
|
||||
semiDarkSidebar: false,
|
||||
},
|
||||
transition: {
|
||||
enable: true,
|
||||
@@ -312,6 +320,8 @@ interface AppPreferences {
|
||||
contentCompact: ContentCompactType;
|
||||
// /** 应用默认头像 */
|
||||
defaultAvatar: string;
|
||||
/** 默认首页地址 */
|
||||
defaultHomePath: string;
|
||||
// /** 开启动态标题 */
|
||||
dynamicTitle: boolean;
|
||||
/** 是否开启检查更新 */
|
||||
@@ -366,6 +376,8 @@ interface CopyrightPreferences {
|
||||
icp: string;
|
||||
/** 备案号链接 */
|
||||
icpLink: string;
|
||||
/** 设置面板是否显示*/
|
||||
settingShow?: boolean;
|
||||
}
|
||||
|
||||
interface FooterPreferences {
|
||||
@@ -380,6 +392,8 @@ interface HeaderPreferences {
|
||||
enable: boolean;
|
||||
/** 顶栏是否隐藏,css-隐藏 */
|
||||
hidden: boolean;
|
||||
/** 顶栏菜单位置 */
|
||||
menuAlign: LayoutHeaderMenuAlignType;
|
||||
/** header显示模式 */
|
||||
mode: LayoutHeaderModeType;
|
||||
}
|
||||
@@ -401,8 +415,12 @@ interface NavigationPreferences {
|
||||
}
|
||||
|
||||
interface SidebarPreferences {
|
||||
/** 点击目录时自动激活子菜单 */
|
||||
autoActivateChild: boolean;
|
||||
/** 侧边栏是否折叠 */
|
||||
collapsed: boolean;
|
||||
/** 侧边栏折叠按钮是否可见 */
|
||||
collapsedButton: boolean;
|
||||
/** 侧边栏折叠时,是否显示title */
|
||||
collapsedShowTitle: boolean;
|
||||
/** 侧边栏是否可见 */
|
||||
@@ -411,6 +429,8 @@ interface SidebarPreferences {
|
||||
expandOnHover: boolean;
|
||||
/** 侧边栏扩展区域是否折叠 */
|
||||
extraCollapse: boolean;
|
||||
/** 侧边栏固定按钮是否可见 */
|
||||
fixedButton: boolean;
|
||||
/** 侧边栏是否隐藏 - css */
|
||||
hidden: boolean;
|
||||
/** 侧边栏宽度 */
|
||||
@@ -439,6 +459,10 @@ interface TabbarPreferences {
|
||||
height: number;
|
||||
/** 开启标签页缓存功能 */
|
||||
keepAlive: boolean;
|
||||
/** 限制最大数量 */
|
||||
maxCount: number;
|
||||
/** 是否点击中键时关闭标签 */
|
||||
middleClickToClose: boolean;
|
||||
/** 是否持久化标签 */
|
||||
persist: boolean;
|
||||
/** 是否开启多标签页图标 */
|
||||
@@ -449,6 +473,8 @@ interface TabbarPreferences {
|
||||
showMore: boolean;
|
||||
/** 标签页风格 */
|
||||
styleType: TabsStyleType;
|
||||
/** 是否开启鼠标滚轮响应 */
|
||||
wheelable: boolean;
|
||||
}
|
||||
|
||||
interface ThemePreferences {
|
||||
|
@@ -58,7 +58,7 @@ git clone https://gitee.com/annsion/vue-vben-admin.git
|
||||
cd vue-vben-admin
|
||||
|
||||
# 使用项目指定的pnpm版本进行依赖安装
|
||||
corepack enable
|
||||
npm i -g corepack
|
||||
|
||||
# 安装依赖
|
||||
pnpm install
|
||||
|
@@ -18,7 +18,7 @@
|
||||
|
||||
## 依赖问题
|
||||
|
||||
在 `Monorepo` 项目下,需要养成每次 `git pull`代码都要执行`pnpm install`的习惯,因为经常会有新的依赖包加入,项目在`.husky/git-merge`已经配置了自动执行`pnpm install`,但是有时候会出现问题,如果没有自动执行,建议手动执行一次。
|
||||
在 `Monorepo` 项目下,需要养成每次 `git pull`代码都要执行`pnpm install`的习惯,因为经常会有新的依赖包加入,项目在`lefthook.yml`已经配置了自动执行`pnpm install`,但是有时候会出现问题,如果没有自动执行,建议手动执行一次。
|
||||
|
||||
## 关于缓存更新问题
|
||||
|
||||
|
@@ -33,8 +33,8 @@
|
||||
- [Prettier](https://prettier.io/) 用于代码格式化
|
||||
- [Commitlint](https://commitlint.js.org/) 用于检查 git 提交信息的规范
|
||||
- [Publint](https://publint.dev/) 用于检查 npm 包的规范
|
||||
- [Lint Staged](https://github.com/lint-staged/lint-staged) 用于在 git 提交前运行代码校验
|
||||
- [Cspell](https://cspell.org/) 用于检查拼写错误
|
||||
- [lefthook](https://github.com/evilmartians/lefthook) 用于管理 Git hooks,在提交前自动运行代码校验和格式化
|
||||
|
||||
## ESLint
|
||||
|
||||
@@ -148,18 +148,66 @@ cspell 配置文件为 `cspell.json`,可以根据项目需求进行修改。
|
||||
|
||||
git hook 一般结合各种 lint,在 git 提交代码的时候进行代码风格校验,如果校验没通过,则不会进行提交。需要开发者自行修改后再次进行提交
|
||||
|
||||
### husky
|
||||
### lefthook
|
||||
|
||||
有一个问题就是校验会校验全部代码,但是我们只想校验我们自己提交的代码,这个时候就可以使用 husky。
|
||||
有一个问题就是校验会校验全部代码,但是我们只想校验我们自己提交的代码,这个时候就可以使用 lefthook。
|
||||
|
||||
最有效的解决方案就是将 Lint 校验放到本地,常见做法是使用 husky 或者 pre-commit 在本地提交之前先做一次 Lint 校验。
|
||||
最有效的解决方案就是将 Lint 校验放到本地,常见做法是使用 lefthook 在本地提交之前先做一次 Lint 校验。
|
||||
|
||||
项目在 `.husky` 内部定义了相应的 hooks
|
||||
项目在 `lefthook.yml` 内部定义了相应的 hooks:
|
||||
|
||||
#### 如何关闭 Husky
|
||||
- `pre-commit`: 在提交前运行,用于代码格式化和检查
|
||||
|
||||
如果你想关闭 Husky,直接删除 `.husky` 目录即可。
|
||||
- `code-workspace`: 更新 VSCode 工作区配置
|
||||
- `lint-md`: 格式化 Markdown 文件
|
||||
- `lint-vue`: 格式化并检查 Vue 文件
|
||||
- `lint-js`: 格式化并检查 JavaScript/TypeScript 文件
|
||||
- `lint-style`: 格式化并检查样式文件
|
||||
- `lint-package`: 格式化 package.json
|
||||
- `lint-json`: 格式化其他 JSON 文件
|
||||
|
||||
### lint-staged
|
||||
- `post-merge`: 在合并后运行,用于自动安装依赖
|
||||
|
||||
用于自动修复提交文件风格问题,其配置文件为 `.lintstagedrc.mjs`,可以根据项目需求进行修改。
|
||||
- `install`: 运行 `pnpm install` 安装新依赖
|
||||
|
||||
- `commit-msg`: 在提交时运行,用于检查提交信息格式
|
||||
- `commitlint`: 使用 commitlint 检查提交信息
|
||||
|
||||
#### 如何关闭 lefthook
|
||||
|
||||
如果你想关闭 lefthook,有两种方式:
|
||||
|
||||
::: code-group
|
||||
|
||||
```bash [临时关闭]
|
||||
git commit -m 'feat: add home page' --no-verify
|
||||
```
|
||||
|
||||
```bash [永久关闭]
|
||||
# 删除 lefthook.yml 文件即可
|
||||
rm lefthook.yml
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
#### 如何修改 lefthook 配置
|
||||
|
||||
如果你想修改 lefthook 的配置,可以编辑 `lefthook.yml` 文件。例如:
|
||||
|
||||
```yaml
|
||||
pre-commit:
|
||||
parallel: true # 并行执行任务
|
||||
jobs:
|
||||
- name: lint-js
|
||||
run: pnpm prettier --cache --ignore-unknown --write {staged_files}
|
||||
glob: '*.{js,jsx,ts,tsx}'
|
||||
```
|
||||
|
||||
其中:
|
||||
|
||||
- `parallel`: 是否并行执行任务
|
||||
- `jobs`: 定义要执行的任务列表
|
||||
- `name`: 任务名称
|
||||
- `run`: 要执行的命令
|
||||
- `glob`: 匹配的文件模式
|
||||
- `{staged_files}`: 表示暂存的文件列表
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/commitlint-config",
|
||||
"version": "5.5.5",
|
||||
"version": "5.5.6",
|
||||
"private": true,
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
|
@@ -70,7 +70,7 @@ export async function perfectionist(): Promise<Linter.Config[]> {
|
||||
},
|
||||
],
|
||||
'perfectionist/sort-objects': [
|
||||
'error',
|
||||
'off',
|
||||
{
|
||||
customGroups: {
|
||||
items: 'items',
|
||||
|
@@ -10,7 +10,15 @@ export async function vue(): Promise<Linter.Config[]> {
|
||||
interopDefault(import('@typescript-eslint/parser')),
|
||||
] as const);
|
||||
|
||||
const flatEssential = pluginVue.configs?.['flat/essential'] || [];
|
||||
const flatStronglyRecommended =
|
||||
pluginVue.configs?.['flat/strongly-recommended'] || [];
|
||||
const flatRecommended = pluginVue.configs?.['flat/recommended'] || [];
|
||||
|
||||
return [
|
||||
...flatEssential,
|
||||
...flatStronglyRecommended,
|
||||
...flatRecommended,
|
||||
{
|
||||
files: ['**/*.vue'],
|
||||
languageOptions: {
|
||||
@@ -43,12 +51,9 @@ export async function vue(): Promise<Linter.Config[]> {
|
||||
plugins: {
|
||||
vue: pluginVue,
|
||||
},
|
||||
processor: pluginVue.processors['.vue'],
|
||||
processor: pluginVue.processors?.['.vue'],
|
||||
rules: {
|
||||
...pluginVue.configs.base.rules,
|
||||
...pluginVue.configs['vue3-essential'].rules,
|
||||
...pluginVue.configs['vue3-strongly-recommended'].rules,
|
||||
...pluginVue.configs['vue3-recommended'].rules,
|
||||
...pluginVue.configs?.base?.rules,
|
||||
|
||||
'vue/attribute-hyphenation': [
|
||||
'error',
|
||||
@@ -131,7 +136,6 @@ export async function vue(): Promise<Linter.Config[]> {
|
||||
'vue/require-default-prop': 'error',
|
||||
'vue/require-explicit-emits': 'error',
|
||||
'vue/require-prop-types': 'off',
|
||||
'vue/script-setup-uses-vars': 'error',
|
||||
'vue/singleline-html-element-content-newline': 'off',
|
||||
'vue/space-infix-ops': 'error',
|
||||
'vue/space-unary-ops': ['error', { nonwords: false, words: true }],
|
||||
|
@@ -28,6 +28,13 @@ const customConfig: Linter.Config[] = [
|
||||
'perfectionist/sort-objects': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['**/**.vue'],
|
||||
ignores: restrictedImportIgnores,
|
||||
rules: {
|
||||
'perfectionist/sort-objects': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
// apps内部的一些基础规则
|
||||
files: ['apps/**/**'],
|
||||
|
@@ -43,6 +43,7 @@ export default {
|
||||
'stylelint-scss',
|
||||
],
|
||||
rules: {
|
||||
'at-rule-no-deprecated': null,
|
||||
'at-rule-no-unknown': [
|
||||
true,
|
||||
{
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/stylelint-config",
|
||||
"version": "5.5.5",
|
||||
"version": "5.5.6",
|
||||
"private": true,
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/node-utils",
|
||||
"version": "5.5.5",
|
||||
"version": "5.5.6",
|
||||
"private": true,
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/tailwind-config",
|
||||
"version": "5.5.5",
|
||||
"version": "5.5.6",
|
||||
"private": true,
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
@@ -12,7 +12,7 @@
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"stub": "pnpm unbuild"
|
||||
"stub": "pnpm unbuild --stub"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
|
@@ -1,6 +1,9 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"extends": "@vben/tsconfig/node.json",
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "bundler"
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/tsconfig",
|
||||
"version": "5.5.5",
|
||||
"version": "5.5.6",
|
||||
"private": true,
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/vite-config",
|
||||
"version": "5.5.5",
|
||||
"version": "5.5.6",
|
||||
"private": true,
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
@@ -47,12 +47,15 @@
|
||||
"@vitejs/plugin-vue-jsx": "catalog:",
|
||||
"dayjs": "catalog:",
|
||||
"dotenv": "catalog:",
|
||||
"electron": "catalog:",
|
||||
"rollup": "catalog:",
|
||||
"rollup-plugin-visualizer": "catalog:",
|
||||
"sass": "catalog:",
|
||||
"vite": "catalog:",
|
||||
"vite-plugin-compression": "catalog:",
|
||||
"vite-plugin-dts": "catalog:",
|
||||
"vite-plugin-electron": "catalog:",
|
||||
"vite-plugin-electron-renderer": "catalog:",
|
||||
"vite-plugin-html": "catalog:",
|
||||
"vite-plugin-lazy-import": "catalog:"
|
||||
}
|
||||
|
40
internal/vite-config/src/plugins/electron.ts
Normal file
40
internal/vite-config/src/plugins/electron.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import type { PluginOption } from 'vite';
|
||||
|
||||
import type { CommonPluginOptions } from '../typing';
|
||||
|
||||
import fs from 'node:fs';
|
||||
|
||||
import electron from 'vite-plugin-electron/simple';
|
||||
|
||||
export const viteElectronPlugin = (
|
||||
options: CommonPluginOptions,
|
||||
): PluginOption => {
|
||||
fs.rmSync('dist-electron', { force: true, recursive: true });
|
||||
|
||||
const isServe = !options.isBuild;
|
||||
const isBuild = options.isBuild;
|
||||
const sourcemap = isServe || !!process.env.VSCODE_DEBUG;
|
||||
return electron({
|
||||
main: {
|
||||
entry: 'electron/main.ts',
|
||||
vite: {
|
||||
build: {
|
||||
minify: isBuild,
|
||||
outDir: 'dist-electron/main',
|
||||
sourcemap,
|
||||
},
|
||||
},
|
||||
},
|
||||
preload: {
|
||||
input: 'electron/preload.ts',
|
||||
vite: {
|
||||
build: {
|
||||
minify: isBuild,
|
||||
outDir: 'dist-electron/preload',
|
||||
sourcemap: sourcemap ? 'inline' : undefined, // #332
|
||||
},
|
||||
},
|
||||
},
|
||||
renderer: {},
|
||||
});
|
||||
};
|
@@ -18,6 +18,7 @@ import { VitePWA } from 'vite-plugin-pwa';
|
||||
import viteVueDevTools from 'vite-plugin-vue-devtools';
|
||||
|
||||
import { viteArchiverPlugin } from './archiver';
|
||||
import { viteElectronPlugin } from './electron';
|
||||
import { viteExtraAppConfigPlugin } from './extra-app-config';
|
||||
import { viteImportMapPlugin } from './importmap';
|
||||
import { viteInjectAppLoadingPlugin } from './inject-app-loading';
|
||||
@@ -97,6 +98,7 @@ async function loadApplicationPlugins(
|
||||
archiverPluginOptions,
|
||||
compress,
|
||||
compressTypes,
|
||||
electron,
|
||||
extraAppConfig,
|
||||
html,
|
||||
i18n,
|
||||
@@ -213,6 +215,10 @@ async function loadApplicationPlugins(
|
||||
return [await viteArchiverPlugin(archiverPluginOptions)];
|
||||
},
|
||||
},
|
||||
{
|
||||
condition: electron,
|
||||
plugins: () => [viteElectronPlugin(commonOptions)],
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
|
@@ -4,148 +4,312 @@ import type { PluginOptions } from 'vite-plugin-dts';
|
||||
import type { Options as PwaPluginOptions } from 'vite-plugin-pwa';
|
||||
|
||||
interface IImportMap {
|
||||
/** 模块导入映射 */
|
||||
imports?: Record<string, string>;
|
||||
/** 作用域特定的导入映射 */
|
||||
scopes?: {
|
||||
[scope: string]: Record<string, string>;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印插件配置选项
|
||||
* @description 用于配置控制台打印信息
|
||||
*/
|
||||
interface PrintPluginOptions {
|
||||
/**
|
||||
* 打印的数据
|
||||
* 打印的数据映射
|
||||
* @description 键值对形式的数据,将在控制台打印
|
||||
* @example
|
||||
* ```typescript
|
||||
* {
|
||||
* 'App Version': '1.0.0',
|
||||
* 'Build Time': '2024-01-01'
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
infoMap?: Record<string, string | undefined>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nitro Mock 插件配置选项
|
||||
* @description 用于配置 Nitro Mock 服务器的行为
|
||||
*/
|
||||
interface NitroMockPluginOptions {
|
||||
/**
|
||||
* mock server 包名
|
||||
* Mock 服务器包名
|
||||
* @default '@vbenjs/nitro-mock'
|
||||
*/
|
||||
mockServerPackage?: string;
|
||||
|
||||
/**
|
||||
* mock 服务端口
|
||||
* Mock 服务端口
|
||||
* @default 3000
|
||||
*/
|
||||
port?: number;
|
||||
|
||||
/**
|
||||
* mock 日志是否打印
|
||||
* 是否打印 Mock 日志
|
||||
* @default false
|
||||
*/
|
||||
verbose?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* 归档插件配置选项
|
||||
* @description 用于配置构建产物的压缩归档
|
||||
*/
|
||||
interface ArchiverPluginOptions {
|
||||
/**
|
||||
* 输出文件名
|
||||
* @default dist
|
||||
* @default 'dist'
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* 输出目录
|
||||
* @default .
|
||||
* @default '.'
|
||||
*/
|
||||
outputDir?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* importmap 插件配置
|
||||
* ImportMap 插件配置
|
||||
* @description 用于配置模块的 CDN 导入
|
||||
*/
|
||||
interface ImportmapPluginOptions {
|
||||
/**
|
||||
* CDN 供应商
|
||||
* @default jspm.io
|
||||
* @default 'jspm.io'
|
||||
* @description 支持 esm.sh 和 jspm.io 两种 CDN 供应商
|
||||
*/
|
||||
defaultProvider?: 'esm.sh' | 'jspm.io';
|
||||
/** importmap 配置 */
|
||||
/**
|
||||
* ImportMap 配置数组
|
||||
* @description 配置需要从 CDN 导入的包
|
||||
* @example
|
||||
* ```typescript
|
||||
* [
|
||||
* { name: 'vue' },
|
||||
* { name: 'pinia', range: '^2.0.0' }
|
||||
* ]
|
||||
* ```
|
||||
*/
|
||||
importmap?: Array<{ name: string; range?: string }>;
|
||||
/** 手动配置importmap */
|
||||
/**
|
||||
* 手动配置 ImportMap
|
||||
* @description 自定义 ImportMap 配置
|
||||
*/
|
||||
inputMap?: IImportMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用于判断是否需要加载插件
|
||||
* 条件插件配置
|
||||
* @description 用于根据条件动态加载插件
|
||||
*/
|
||||
interface ConditionPlugin {
|
||||
// 判断条件
|
||||
/**
|
||||
* 判断条件
|
||||
* @description 当条件为 true 时加载插件
|
||||
*/
|
||||
condition?: boolean;
|
||||
// 插件对象
|
||||
/**
|
||||
* 插件对象
|
||||
* @description 返回插件数组或 Promise
|
||||
*/
|
||||
plugins: () => PluginOption[] | PromiseLike<PluginOption[]>;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用插件配置选项
|
||||
* @description 所有插件共用的基础配置
|
||||
*/
|
||||
interface CommonPluginOptions {
|
||||
/** 是否开启devtools */
|
||||
/**
|
||||
* 是否开启开发工具
|
||||
* @default false
|
||||
*/
|
||||
devtools?: boolean;
|
||||
/** 环境变量 */
|
||||
/**
|
||||
* 环境变量
|
||||
* @description 自定义环境变量
|
||||
*/
|
||||
env?: Record<string, any>;
|
||||
/** 是否注入metadata */
|
||||
/**
|
||||
* 是否注入元数据
|
||||
* @default true
|
||||
*/
|
||||
injectMetadata?: boolean;
|
||||
/** 是否构建模式 */
|
||||
/**
|
||||
* 是否为构建模式
|
||||
* @default false
|
||||
*/
|
||||
isBuild?: boolean;
|
||||
/** 构建模式 */
|
||||
/**
|
||||
* 构建模式
|
||||
* @default 'development'
|
||||
*/
|
||||
mode?: string;
|
||||
/** 开启依赖分析 */
|
||||
/**
|
||||
* 是否开启依赖分析
|
||||
* @default false
|
||||
* @description 使用 rollup-plugin-visualizer 分析依赖
|
||||
*/
|
||||
visualizer?: boolean | PluginVisualizerOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用插件配置选项
|
||||
* @description 用于配置应用构建时的插件选项
|
||||
*/
|
||||
interface ApplicationPluginOptions extends CommonPluginOptions {
|
||||
/** 开启后,会在打包dist同级生成dist.zip */
|
||||
/**
|
||||
* 是否开启压缩归档
|
||||
* @default false
|
||||
* @description 开启后会在打包目录生成 zip 文件
|
||||
*/
|
||||
archiver?: boolean;
|
||||
/** 压缩归档插件配置 */
|
||||
/**
|
||||
* 压缩归档插件配置
|
||||
* @description 配置压缩归档的行为
|
||||
*/
|
||||
archiverPluginOptions?: ArchiverPluginOptions;
|
||||
/** 开启 gzip|brotli 压缩 */
|
||||
/**
|
||||
* 是否开启压缩
|
||||
* @default false
|
||||
* @description 支持 gzip 和 brotli 压缩
|
||||
*/
|
||||
compress?: boolean;
|
||||
/** 压缩类型 */
|
||||
/**
|
||||
* 压缩类型
|
||||
* @default ['gzip']
|
||||
* @description 可选的压缩类型
|
||||
*/
|
||||
compressTypes?: ('brotli' | 'gzip')[];
|
||||
/** 在构建的时候抽离配置文件 */
|
||||
/** 启用electron */
|
||||
electron?: boolean;
|
||||
/**
|
||||
* 是否抽离配置文件
|
||||
* @default false
|
||||
* @description 在构建时抽离配置文件
|
||||
*/
|
||||
extraAppConfig?: boolean;
|
||||
/** 是否开启html插件 */
|
||||
/**
|
||||
* 是否开启 HTML 插件
|
||||
* @default true
|
||||
*/
|
||||
html?: boolean;
|
||||
/** 是否开启i18n */
|
||||
/**
|
||||
* 是否开启国际化
|
||||
* @default false
|
||||
*/
|
||||
i18n?: boolean;
|
||||
/** 是否开启 importmap CDN */
|
||||
/**
|
||||
* 是否开启 ImportMap CDN
|
||||
* @default false
|
||||
*/
|
||||
importmap?: boolean;
|
||||
/** importmap 插件配置 */
|
||||
/**
|
||||
* ImportMap 插件配置
|
||||
*/
|
||||
importmapOptions?: ImportmapPluginOptions;
|
||||
/** 是否注入app loading */
|
||||
/**
|
||||
* 是否注入应用加载动画
|
||||
* @default true
|
||||
*/
|
||||
injectAppLoading?: boolean;
|
||||
/** 是否注入全局scss */
|
||||
/**
|
||||
* 是否注入全局 SCSS
|
||||
* @default true
|
||||
*/
|
||||
injectGlobalScss?: boolean;
|
||||
/** 是否注入版权信息 */
|
||||
/**
|
||||
* 是否注入版权信息
|
||||
* @default true
|
||||
*/
|
||||
license?: boolean;
|
||||
/** 是否开启nitro mock */
|
||||
/**
|
||||
* 是否开启 Nitro Mock
|
||||
* @default false
|
||||
*/
|
||||
nitroMock?: boolean;
|
||||
/** nitro mock 插件配置 */
|
||||
/**
|
||||
* Nitro Mock 插件配置
|
||||
*/
|
||||
nitroMockOptions?: NitroMockPluginOptions;
|
||||
/** 开启控制台自定义打印 */
|
||||
/**
|
||||
* 是否开启控制台打印
|
||||
* @default false
|
||||
*/
|
||||
print?: boolean;
|
||||
/** 打印插件配置 */
|
||||
/**
|
||||
* 打印插件配置
|
||||
*/
|
||||
printInfoMap?: PrintPluginOptions['infoMap'];
|
||||
/** 是否开启pwa */
|
||||
/**
|
||||
* 是否开启 PWA
|
||||
* @default false
|
||||
*/
|
||||
pwa?: boolean;
|
||||
/** pwa 插件配置 */
|
||||
/**
|
||||
* PWA 插件配置
|
||||
*/
|
||||
pwaOptions?: Partial<PwaPluginOptions>;
|
||||
/** 是否开启vxe-table懒加载 */
|
||||
/**
|
||||
* 是否开启 VXE Table 懒加载
|
||||
* @default false
|
||||
*/
|
||||
vxeTableLazyImport?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* 库插件配置选项
|
||||
* @description 用于配置库构建时的插件选项
|
||||
*/
|
||||
interface LibraryPluginOptions extends CommonPluginOptions {
|
||||
/** 开启 dts 输出 */
|
||||
/**
|
||||
* 是否开启 DTS 输出
|
||||
* @default true
|
||||
* @description 生成 TypeScript 类型声明文件
|
||||
*/
|
||||
dts?: boolean | PluginOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用配置选项类型
|
||||
*/
|
||||
type ApplicationOptions = ApplicationPluginOptions;
|
||||
|
||||
/**
|
||||
* 库配置选项类型
|
||||
*/
|
||||
type LibraryOptions = LibraryPluginOptions;
|
||||
|
||||
/**
|
||||
* 应用配置定义函数类型
|
||||
* @description 用于定义应用构建配置
|
||||
*/
|
||||
type DefineApplicationOptions = (config?: ConfigEnv) => Promise<{
|
||||
/** 应用插件配置 */
|
||||
application?: ApplicationOptions;
|
||||
/** Vite 配置 */
|
||||
vite?: UserConfig;
|
||||
}>;
|
||||
|
||||
/**
|
||||
* 库配置定义函数类型
|
||||
* @description 用于定义库构建配置
|
||||
*/
|
||||
type DefineLibraryOptions = (config?: ConfigEnv) => Promise<{
|
||||
/** 库插件配置 */
|
||||
library?: LibraryOptions;
|
||||
/** Vite 配置 */
|
||||
vite?: UserConfig;
|
||||
}>;
|
||||
|
||||
/**
|
||||
* 配置定义类型
|
||||
* @description 应用或库的配置定义
|
||||
*/
|
||||
type DefineConfig = DefineApplicationOptions | DefineLibraryOptions;
|
||||
|
||||
export type {
|
||||
|
76
lefthook.yml
Normal file
76
lefthook.yml
Normal file
@@ -0,0 +1,76 @@
|
||||
# EXAMPLE USAGE:
|
||||
#
|
||||
# Refer for explanation to following link:
|
||||
# https://lefthook.dev/configuration/
|
||||
#
|
||||
# pre-push:
|
||||
# jobs:
|
||||
# - name: packages audit
|
||||
# tags:
|
||||
# - frontend
|
||||
# - security
|
||||
# run: yarn audit
|
||||
#
|
||||
# - name: gems audit
|
||||
# tags:
|
||||
# - backend
|
||||
# - security
|
||||
# run: bundle audit
|
||||
#
|
||||
# pre-commit:
|
||||
# parallel: true
|
||||
# jobs:
|
||||
# - run: yarn eslint {staged_files}
|
||||
# glob: "*.{js,ts,jsx,tsx}"
|
||||
#
|
||||
# - name: rubocop
|
||||
# glob: "*.rb"
|
||||
# exclude:
|
||||
# - config/application.rb
|
||||
# - config/routes.rb
|
||||
# run: bundle exec rubocop --force-exclusion {all_files}
|
||||
#
|
||||
# - name: govet
|
||||
# files: git ls-files -m
|
||||
# glob: "*.go"
|
||||
# run: go vet {files}
|
||||
#
|
||||
# - script: "hello.js"
|
||||
# runner: node
|
||||
#
|
||||
# - script: "hello.go"
|
||||
# runner: go run
|
||||
|
||||
pre-commit:
|
||||
parallel: true
|
||||
commands:
|
||||
code-workspace:
|
||||
run: pnpm vsh code-workspace --auto-commit
|
||||
lint-md:
|
||||
run: pnpm prettier --cache --ignore-unknown --write {staged_files}
|
||||
glob: '*.md'
|
||||
lint-vue:
|
||||
run: pnpm prettier --write {staged_files} && pnpm eslint --cache --fix {staged_files} && pnpm stylelint --fix --allow-empty-input {staged_files}
|
||||
glob: '*.vue'
|
||||
lint-js:
|
||||
run: pnpm prettier --cache --ignore-unknown --write {staged_files} && pnpm eslint --cache --fix {staged_files}
|
||||
glob: '*.{js,jsx,ts,tsx}'
|
||||
lint-style:
|
||||
run: pnpm prettier --cache --ignore-unknown --write {staged_files} && pnpm stylelint --fix --allow-empty-input {staged_files}
|
||||
glob: '*.{scss,less,styl,html,vue,css}'
|
||||
lint-package:
|
||||
run: pnpm prettier --cache --write {staged_files}
|
||||
glob: 'package.json'
|
||||
lint-json:
|
||||
run: pnpm prettier --cache --write --parser json {staged_files}
|
||||
glob: '{!(package)*.json,*.code-snippets,.!(browserslist)*rc}'
|
||||
|
||||
post-merge:
|
||||
commands:
|
||||
install:
|
||||
run: pnpm install
|
||||
|
||||
commit-msg:
|
||||
commands:
|
||||
commitlint:
|
||||
run: pnpm exec commitlint --edit $1
|
13
package.json
13
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vben-admin-monorepo",
|
||||
"version": "5.5.5",
|
||||
"version": "5.5.6",
|
||||
"private": true,
|
||||
"keywords": [
|
||||
"monorepo",
|
||||
@@ -51,14 +51,14 @@
|
||||
"lint": "vsh lint",
|
||||
"postinstall": "pnpm -r run stub --if-present",
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
"prepare": "is-ci || husky",
|
||||
"preview": "turbo-run preview",
|
||||
"publint": "vsh publint",
|
||||
"reinstall": "pnpm clean --del-lock && pnpm install",
|
||||
"test:unit": "vitest run --dom",
|
||||
"test:e2e": "turbo run test:e2e",
|
||||
"update:deps": "npx taze -r -w",
|
||||
"version": "pnpm exec changeset version && pnpm install --no-frozen-lockfile"
|
||||
"version": "pnpm exec changeset version && pnpm install --no-frozen-lockfile",
|
||||
"catalog": "pnpx codemod pnpm/catalog"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@changesets/changelog-github": "catalog:",
|
||||
@@ -81,9 +81,8 @@
|
||||
"cross-env": "catalog:",
|
||||
"cspell": "catalog:",
|
||||
"happy-dom": "catalog:",
|
||||
"husky": "catalog:",
|
||||
"is-ci": "catalog:",
|
||||
"lint-staged": "catalog:",
|
||||
"lefthook": "catalog:",
|
||||
"playwright": "catalog:",
|
||||
"rimraf": "catalog:",
|
||||
"tailwindcss": "catalog:",
|
||||
@@ -99,7 +98,7 @@
|
||||
"node": ">=20.10.0",
|
||||
"pnpm": ">=9.12.0"
|
||||
},
|
||||
"packageManager": "pnpm@9.15.9",
|
||||
"packageManager": "pnpm@10.10.0",
|
||||
"pnpm": {
|
||||
"peerDependencyRules": {
|
||||
"allowedVersions": {
|
||||
@@ -110,7 +109,7 @@
|
||||
"@ast-grep/napi": "catalog:",
|
||||
"@ctrl/tinycolor": "catalog:",
|
||||
"clsx": "catalog:",
|
||||
"esbuild": "0.24.0",
|
||||
"esbuild": "0.25.3",
|
||||
"pinia": "catalog:",
|
||||
"vue": "catalog:"
|
||||
},
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/design",
|
||||
"version": "5.5.5",
|
||||
"version": "5.5.6",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/icons",
|
||||
"version": "5.5.5",
|
||||
"version": "5.5.6",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
@@ -45,6 +45,7 @@ export {
|
||||
Menu,
|
||||
Minimize,
|
||||
Minimize2,
|
||||
Minus,
|
||||
MoonStar,
|
||||
Palette,
|
||||
PanelLeft,
|
||||
@@ -58,6 +59,8 @@ export {
|
||||
Settings,
|
||||
Shrink,
|
||||
Square,
|
||||
SquareArrowDownLeft,
|
||||
SquareArrowUpRight,
|
||||
SquareCheckBig,
|
||||
SquareMinus,
|
||||
Sun,
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/shared",
|
||||
"version": "5.5.5",
|
||||
"version": "5.5.6",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
@@ -98,6 +98,8 @@
|
||||
"@types/lodash.get": "catalog:",
|
||||
"@types/lodash.isequal": "catalog:",
|
||||
"@types/lodash.set": "catalog:",
|
||||
"@types/nprogress": "catalog:"
|
||||
"@types/nprogress": "catalog:",
|
||||
"@vben-core/typings": "workspace:*",
|
||||
"electron": "catalog:"
|
||||
}
|
||||
}
|
||||
|
@@ -1,3 +1,4 @@
|
||||
// eslint-disable-next-line vue/prefer-import-from-vue
|
||||
import { isFunction, isObject, isString } from '@vue/shared';
|
||||
|
||||
/**
|
||||
|
@@ -28,10 +28,11 @@ function openWindow(url: string, options: OpenWindowOptions = {}): void {
|
||||
* @param path
|
||||
*/
|
||||
function openRouteInNewWindow(path: string) {
|
||||
const { hash, origin } = location;
|
||||
// const { hash, origin } = location;
|
||||
const fullPath = path.startsWith('/') ? path : `/${path}`;
|
||||
const url = `${origin}${hash ? '/#' : ''}${fullPath}`;
|
||||
openWindow(url, { target: '_blank' });
|
||||
// const url = `${origin}${hash ? '/#' : ''}${fullPath}`;
|
||||
// openWindow(url, { target: '_blank' });
|
||||
window.ipcRenderer.invoke('open-win', fullPath);
|
||||
}
|
||||
|
||||
export { openRouteInNewWindow, openWindow };
|
||||
|
@@ -1,6 +1,9 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"extends": "@vben/tsconfig/library.json",
|
||||
"compilerOptions": {
|
||||
"types": ["@vben-core/typings/electron"]
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
|
27
packages/@core/base/typings/electron.d.ts
vendored
Normal file
27
packages/@core/base/typings/electron.d.ts
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
import type { IpcRendererEvent } from 'electron';
|
||||
|
||||
export type IpcRendererInvoke =
|
||||
| 'app-close'
|
||||
| 'app-maximize'
|
||||
| 'app-minimize'
|
||||
| 'is-maximized'
|
||||
| 'open-win';
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
ipcRenderer: {
|
||||
invoke: (channel: IpcRendererInvoke, ...args: any[]) => Promise<any>;
|
||||
off: (
|
||||
channel: string,
|
||||
listener: (event: IpcRendererEvent, ...args: any[]) => void,
|
||||
) => void;
|
||||
on: (
|
||||
channel: string,
|
||||
listener: (event: IpcRendererEvent, ...args: any[]) => void,
|
||||
) => void;
|
||||
send: (channel: string, data: any) => Promise<any>;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export {};
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/typings",
|
||||
"version": "5.5.5",
|
||||
"version": "5.5.6",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
@@ -27,6 +27,9 @@
|
||||
},
|
||||
"./vue-router": {
|
||||
"types": "./vue-router.d.ts"
|
||||
},
|
||||
"./electron": {
|
||||
"types": "./electron.d.ts"
|
||||
}
|
||||
},
|
||||
"publishConfig": {
|
||||
|
@@ -1,3 +1,8 @@
|
||||
import type { RouteLocationNormalized } from 'vue-router';
|
||||
|
||||
export type TabDefinition = RouteLocationNormalized;
|
||||
export interface TabDefinition extends RouteLocationNormalized {
|
||||
/**
|
||||
* 标签页的key
|
||||
*/
|
||||
key?: string;
|
||||
}
|
||||
|
@@ -43,6 +43,10 @@ interface RouteMeta {
|
||||
| 'success'
|
||||
| 'warning'
|
||||
| string;
|
||||
/**
|
||||
* 路由的完整路径作为key(默认true)
|
||||
*/
|
||||
fullPathKey?: boolean;
|
||||
/**
|
||||
* 当前路由的子级在菜单中不展现
|
||||
* @default false
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/composables",
|
||||
"version": "5.5.5",
|
||||
"version": "5.5.6",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
@@ -11,6 +11,7 @@ exports[`defaultPreferences immutability test > should not modify the config obj
|
||||
"compact": false,
|
||||
"contentCompact": "wide",
|
||||
"defaultAvatar": "https://unpkg.com/@vbenjs/static-source@0.1.7/source/avatar-v1.webp",
|
||||
"defaultHomePath": "/analytics",
|
||||
"dynamicTitle": true,
|
||||
"enableCheckUpdates": true,
|
||||
"enablePreferences": true,
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/preferences",
|
||||
"version": "5.5.5",
|
||||
"version": "5.5.6",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
@@ -11,6 +11,7 @@ const defaultPreferences: Preferences = {
|
||||
contentCompact: 'wide',
|
||||
defaultAvatar:
|
||||
'https://unpkg.com/@vbenjs/static-source@0.1.7/source/avatar-v1.webp',
|
||||
defaultHomePath: '/analytics',
|
||||
dynamicTitle: true,
|
||||
enableCheckUpdates: true,
|
||||
enablePreferences: true,
|
||||
|
@@ -35,6 +35,8 @@ interface AppPreferences {
|
||||
contentCompact: ContentCompactType;
|
||||
// /** 应用默认头像 */
|
||||
defaultAvatar: string;
|
||||
/** 默认首页地址 */
|
||||
defaultHomePath: string;
|
||||
// /** 开启动态标题 */
|
||||
dynamicTitle: boolean;
|
||||
/** 是否开启检查更新 */
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/form-ui",
|
||||
"version": "5.5.5",
|
||||
"version": "5.5.6",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
@@ -38,6 +38,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@vben-core/composables": "workspace:*",
|
||||
"@vben-core/icons": "workspace:*",
|
||||
"@vben-core/shadcn-ui": "workspace:*",
|
||||
"@vben-core/shared": "workspace:*",
|
||||
"@vben-core/typings": "workspace:*",
|
||||
|
@@ -2,13 +2,18 @@ import type { FormRenderProps } from '../types';
|
||||
|
||||
import { computed, nextTick, onMounted, ref, useTemplateRef, watch } from 'vue';
|
||||
|
||||
import { breakpointsTailwind, useBreakpoints } from '@vueuse/core';
|
||||
import {
|
||||
breakpointsTailwind,
|
||||
useBreakpoints,
|
||||
useElementVisibility,
|
||||
} from '@vueuse/core';
|
||||
|
||||
/**
|
||||
* 动态计算行数
|
||||
*/
|
||||
export function useExpandable(props: FormRenderProps) {
|
||||
const wrapperRef = useTemplateRef<HTMLElement>('wrapperRef');
|
||||
const isVisible = useElementVisibility(wrapperRef);
|
||||
const rowMapping = ref<Record<number, number>>({});
|
||||
// 是否已经计算过一次
|
||||
const isCalculated = ref(false);
|
||||
@@ -31,6 +36,7 @@ export function useExpandable(props: FormRenderProps) {
|
||||
() => props.showCollapseButton,
|
||||
() => breakpoints.active().value,
|
||||
() => props.schema?.length,
|
||||
() => isVisible.value,
|
||||
],
|
||||
async ([val]) => {
|
||||
if (val) {
|
||||
|
@@ -5,6 +5,7 @@ import type { FormSchema, MaybeComponentProps } from '../types';
|
||||
|
||||
import { computed, nextTick, onUnmounted, useTemplateRef, watch } from 'vue';
|
||||
|
||||
import { CircleAlert } from '@vben-core/icons';
|
||||
import {
|
||||
FormControl,
|
||||
FormDescription,
|
||||
@@ -12,6 +13,7 @@ import {
|
||||
FormItem,
|
||||
FormMessage,
|
||||
VbenRenderContent,
|
||||
VbenTooltip,
|
||||
} from '@vben-core/shadcn-ui';
|
||||
import { cn, isFunction, isObject, isString } from '@vben-core/shared/utils';
|
||||
|
||||
@@ -354,6 +356,24 @@ onUnmounted(() => {
|
||||
</template>
|
||||
<!-- <slot></slot> -->
|
||||
</component>
|
||||
<VbenTooltip
|
||||
v-if="compact && isInValid"
|
||||
:delay-duration="300"
|
||||
side="left"
|
||||
>
|
||||
<template #trigger>
|
||||
<slot name="trigger">
|
||||
<CircleAlert
|
||||
:class="
|
||||
cn(
|
||||
'text-foreground/80 hover:text-foreground inline-flex size-5 cursor-pointer',
|
||||
)
|
||||
"
|
||||
/>
|
||||
</slot>
|
||||
</template>
|
||||
<FormMessage />
|
||||
</VbenTooltip>
|
||||
</slot>
|
||||
</FormControl>
|
||||
<!-- 自定义后缀 -->
|
||||
@@ -365,7 +385,7 @@ onUnmounted(() => {
|
||||
</FormDescription>
|
||||
</div>
|
||||
|
||||
<Transition name="slide-up">
|
||||
<Transition name="slide-up" v-if="!compact">
|
||||
<FormMessage class="absolute bottom-1" />
|
||||
</Transition>
|
||||
</div>
|
||||
|
@@ -31,8 +31,8 @@ export function useVbenForm<
|
||||
h(VbenUseForm, { ...props, ...attrs, formApi: extendedApi }, slots);
|
||||
},
|
||||
{
|
||||
inheritAttrs: false,
|
||||
name: 'VbenUseForm',
|
||||
inheritAttrs: false,
|
||||
},
|
||||
);
|
||||
// Add reactivity support
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/layout-ui",
|
||||
"version": "5.5.5",
|
||||
"version": "5.5.6",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
@@ -64,7 +64,7 @@ const logoStyle = computed((): CSSProperties => {
|
||||
<header
|
||||
:class="theme"
|
||||
:style="style"
|
||||
class="border-border bg-header top-0 flex w-full flex-[0_0_auto] items-center border-b pl-2 transition-[margin-top] duration-200"
|
||||
class="app-header border-border bg-header top-0 flex w-full flex-[0_0_auto] items-center border-b pl-2 transition-[margin-top] duration-200"
|
||||
>
|
||||
<div v-if="slots.logo" :style="logoStyle">
|
||||
<slot name="logo"></slot>
|
||||
@@ -75,3 +75,17 @@ const logoStyle = computed((): CSSProperties => {
|
||||
<slot></slot>
|
||||
</header>
|
||||
</template>
|
||||
<style lang="scss" scoped>
|
||||
.bg-header {
|
||||
app-region: drag;
|
||||
user-select: none;
|
||||
|
||||
:deep(.cursor-pointer),
|
||||
:deep(.vben-sub-menu),
|
||||
:deep(.vben-menu-item),
|
||||
:deep(button),
|
||||
:deep(a) {
|
||||
app-region: no-drag;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/menu-ui",
|
||||
"version": "5.5.5",
|
||||
"version": "5.5.6",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
@@ -31,6 +31,7 @@ import {
|
||||
createSubMenuContext,
|
||||
useMenuStyle,
|
||||
} from '../hooks';
|
||||
import { useMenuScroll } from '../hooks/use-menu-scroll';
|
||||
import { flattedChildren } from '../utils';
|
||||
import SubMenu from './sub-menu.vue';
|
||||
|
||||
@@ -44,6 +45,7 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
mode: 'vertical',
|
||||
rounded: true,
|
||||
theme: 'dark',
|
||||
scrollToActive: false,
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
@@ -206,15 +208,19 @@ function handleResize() {
|
||||
isFirstTimeRender = false;
|
||||
}
|
||||
|
||||
function getActivePaths() {
|
||||
const activeItem = activePath.value && items.value[activePath.value];
|
||||
const enableScroll = computed(
|
||||
() => props.scrollToActive && props.mode === 'vertical' && !props.collapse,
|
||||
);
|
||||
|
||||
if (!activeItem || props.mode === 'horizontal' || props.collapse) {
|
||||
return [];
|
||||
}
|
||||
const { scrollToActiveItem } = useMenuScroll(activePath, {
|
||||
enable: enableScroll,
|
||||
delay: 320,
|
||||
});
|
||||
|
||||
return activeItem.parentPaths;
|
||||
}
|
||||
// 监听 activePath 变化,自动滚动到激活项
|
||||
watch(activePath, () => {
|
||||
scrollToActiveItem();
|
||||
});
|
||||
|
||||
// 默认展开菜单
|
||||
function initMenu() {
|
||||
@@ -318,6 +324,16 @@ function removeSubMenu(subMenu: MenuItemRegistered) {
|
||||
function removeMenuItem(item: MenuItemRegistered) {
|
||||
Reflect.deleteProperty(items.value, item.path);
|
||||
}
|
||||
|
||||
function getActivePaths() {
|
||||
const activeItem = activePath.value && items.value[activePath.value];
|
||||
|
||||
if (!activeItem || props.mode === 'horizontal' || props.collapse) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return activeItem.parentPaths;
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<ul
|
||||
@@ -374,10 +390,10 @@ $namespace: vben;
|
||||
var(--menu-item-margin-x);
|
||||
font-size: var(--menu-font-size);
|
||||
color: var(--menu-item-color);
|
||||
text-decoration: none;
|
||||
white-space: nowrap;
|
||||
list-style: none;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
list-style: none;
|
||||
background: var(--menu-item-background-color);
|
||||
border: none;
|
||||
border-radius: var(--menu-item-radius);
|
||||
@@ -701,8 +717,8 @@ $namespace: vben;
|
||||
width: var(--menu-item-icon-size);
|
||||
height: var(--menu-item-icon-size);
|
||||
margin-right: 8px;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -10,7 +10,7 @@ import { VbenIcon } from '@vben-core/shadcn-ui';
|
||||
import { useMenuContext } from '../hooks';
|
||||
|
||||
interface Props extends MenuItemProps {
|
||||
isMenuMore: boolean;
|
||||
isMenuMore?: boolean;
|
||||
isTopLevelMenuSubmenu: boolean;
|
||||
level?: number;
|
||||
}
|
||||
|
46
packages/@core/ui-kit/menu-ui/src/hooks/use-menu-scroll.ts
Normal file
46
packages/@core/ui-kit/menu-ui/src/hooks/use-menu-scroll.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import type { Ref } from 'vue';
|
||||
|
||||
import { watch } from 'vue';
|
||||
|
||||
import { useDebounceFn } from '@vueuse/core';
|
||||
|
||||
interface UseMenuScrollOptions {
|
||||
delay?: number;
|
||||
enable?: boolean | Ref<boolean>;
|
||||
}
|
||||
|
||||
export function useMenuScroll(
|
||||
activePath: Ref<string | undefined>,
|
||||
options: UseMenuScrollOptions = {},
|
||||
) {
|
||||
const { enable = true, delay = 320 } = options;
|
||||
|
||||
function scrollToActiveItem() {
|
||||
const isEnabled = typeof enable === 'boolean' ? enable : enable.value;
|
||||
if (!isEnabled) return;
|
||||
|
||||
const activeElement = document.querySelector(
|
||||
`aside li[role=menuitem].is-active`,
|
||||
);
|
||||
if (activeElement) {
|
||||
activeElement.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
block: 'center',
|
||||
inline: 'center',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const debouncedScroll = useDebounceFn(scrollToActiveItem, delay);
|
||||
|
||||
watch(activePath, () => {
|
||||
const isEnabled = typeof enable === 'boolean' ? enable : enable.value;
|
||||
if (!isEnabled) return;
|
||||
|
||||
debouncedScroll();
|
||||
});
|
||||
|
||||
return {
|
||||
scrollToActiveItem,
|
||||
};
|
||||
}
|
@@ -18,15 +18,9 @@ defineOptions({
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
collapse: false,
|
||||
// theme: 'dark',
|
||||
});
|
||||
|
||||
const forward = useForwardProps(props);
|
||||
|
||||
// const emit = defineEmits<{
|
||||
// 'update:openKeys': [key: Key[]];
|
||||
// 'update:selectedKeys': [key: Key[]];
|
||||
// }>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@@ -42,6 +42,12 @@ interface MenuProps {
|
||||
*/
|
||||
rounded?: boolean;
|
||||
|
||||
/**
|
||||
* @zh_CN 是否自动滚动到激活的菜单项
|
||||
* @default false
|
||||
*/
|
||||
scrollToActive?: boolean;
|
||||
|
||||
/**
|
||||
* @zh_CN 菜单主题
|
||||
* @default dark
|
||||
|
@@ -35,7 +35,7 @@ interface Props extends DrawerProps {
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
appendToMain: false,
|
||||
closeIconPlacement: 'right',
|
||||
destroyOnClose: true,
|
||||
destroyOnClose: false,
|
||||
drawerApi: undefined,
|
||||
submitting: false,
|
||||
zIndex: 1000,
|
||||
@@ -82,17 +82,17 @@ const {
|
||||
zIndex,
|
||||
} = usePriorityValues(props, state);
|
||||
|
||||
watch(
|
||||
() => showLoading.value,
|
||||
(v) => {
|
||||
if (v && wrapperRef.value) {
|
||||
wrapperRef.value.scrollTo({
|
||||
// behavior: 'smooth',
|
||||
top: 0,
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
// watch(
|
||||
// () => showLoading.value,
|
||||
// (v) => {
|
||||
// if (v && wrapperRef.value) {
|
||||
// wrapperRef.value.scrollTo({
|
||||
// // behavior: 'smooth',
|
||||
// top: 0,
|
||||
// });
|
||||
// }
|
||||
// },
|
||||
// );
|
||||
|
||||
function interactOutside(e: Event) {
|
||||
if (!closeOnClickModal.value || submitting.value) {
|
||||
@@ -266,19 +266,13 @@ const getForceMount = computed(() => {
|
||||
ref="wrapperRef"
|
||||
:class="
|
||||
cn('relative flex-1 overflow-y-auto p-3', contentClass, {
|
||||
'overflow-hidden': showLoading,
|
||||
'pointer-events-none': showLoading || submitting,
|
||||
})
|
||||
"
|
||||
>
|
||||
<VbenLoading
|
||||
v-if="showLoading || submitting"
|
||||
class="size-full"
|
||||
spinning
|
||||
/>
|
||||
|
||||
<slot></slot>
|
||||
</div>
|
||||
|
||||
<VbenLoading v-if="showLoading || submitting" spinning />
|
||||
<SheetFooter
|
||||
v-if="showFooter"
|
||||
:class="
|
||||
|
@@ -9,6 +9,7 @@ import {
|
||||
h,
|
||||
inject,
|
||||
nextTick,
|
||||
onDeactivated,
|
||||
provide,
|
||||
reactive,
|
||||
ref,
|
||||
@@ -21,9 +22,7 @@ import VbenDrawer from './drawer.vue';
|
||||
|
||||
const USER_DRAWER_INJECT_KEY = Symbol('VBEN_DRAWER_INJECT');
|
||||
|
||||
const DEFAULT_DRAWER_PROPS: Partial<DrawerProps> = {
|
||||
destroyOnClose: true,
|
||||
};
|
||||
const DEFAULT_DRAWER_PROPS: Partial<DrawerProps> = {};
|
||||
|
||||
export function setDefaultDrawerProps(props: Partial<DrawerProps>) {
|
||||
Object.assign(DEFAULT_DRAWER_PROPS, props);
|
||||
@@ -66,11 +65,20 @@ export function useVbenDrawer<
|
||||
slots,
|
||||
);
|
||||
},
|
||||
// eslint-disable-next-line vue/one-component-per-file
|
||||
{
|
||||
inheritAttrs: false,
|
||||
name: 'VbenParentDrawer',
|
||||
inheritAttrs: false,
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
* 在开启keepAlive情况下 直接通过浏览器按钮/手势等返回 不会关闭弹窗
|
||||
*/
|
||||
onDeactivated(() => {
|
||||
(extendedApi as ExtendedDrawerApi)?.close?.();
|
||||
});
|
||||
|
||||
return [Drawer, extendedApi as ExtendedDrawerApi] as const;
|
||||
}
|
||||
|
||||
@@ -107,9 +115,10 @@ export function useVbenDrawer<
|
||||
return () =>
|
||||
h(VbenDrawer, { ...props, ...attrs, drawerApi: extendedApi }, slots);
|
||||
},
|
||||
// eslint-disable-next-line vue/one-component-per-file
|
||||
{
|
||||
inheritAttrs: false,
|
||||
name: 'VbenDrawer',
|
||||
inheritAttrs: false,
|
||||
},
|
||||
);
|
||||
injectData.extendApi?.(extendedApi);
|
||||
|
@@ -34,7 +34,7 @@ interface Props extends ModalProps {
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
appendToMain: false,
|
||||
destroyOnClose: true,
|
||||
destroyOnClose: false,
|
||||
modalApi: undefined,
|
||||
});
|
||||
|
||||
@@ -123,17 +123,17 @@ watch(
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
watch(
|
||||
() => [showLoading.value, submitting.value],
|
||||
([l, s]) => {
|
||||
if ((s || l) && wrapperRef.value) {
|
||||
wrapperRef.value.scrollTo({
|
||||
// behavior: 'smooth',
|
||||
top: 0,
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
// watch(
|
||||
// () => [showLoading.value, submitting.value],
|
||||
// ([l, s]) => {
|
||||
// if ((s || l) && wrapperRef.value) {
|
||||
// wrapperRef.value.scrollTo({
|
||||
// // behavior: 'smooth',
|
||||
// top: 0,
|
||||
// });
|
||||
// }
|
||||
// },
|
||||
// );
|
||||
|
||||
function handleFullscreen() {
|
||||
props.modalApi?.setState((prev) => {
|
||||
@@ -274,18 +274,13 @@ function handleClosed() {
|
||||
ref="wrapperRef"
|
||||
:class="
|
||||
cn('relative min-h-40 flex-1 overflow-y-auto p-3', contentClass, {
|
||||
'overflow-hidden': showLoading || submitting,
|
||||
'pointer-events-none': showLoading || submitting,
|
||||
})
|
||||
"
|
||||
>
|
||||
<VbenLoading
|
||||
v-if="showLoading || submitting"
|
||||
class="size-full h-auto min-h-full"
|
||||
spinning
|
||||
/>
|
||||
<slot></slot>
|
||||
</div>
|
||||
|
||||
<VbenLoading v-if="showLoading || submitting" spinning />
|
||||
<VbenIconButton
|
||||
v-if="fullscreenButton"
|
||||
class="hover:bg-accent hover:text-accent-foreground text-foreground/80 flex-center absolute right-10 top-3 hidden size-6 rounded-full px-1 text-lg opacity-70 transition-opacity hover:opacity-100 focus:outline-none disabled:pointer-events-none sm:block"
|
||||
|
@@ -5,6 +5,7 @@ import {
|
||||
h,
|
||||
inject,
|
||||
nextTick,
|
||||
onDeactivated,
|
||||
provide,
|
||||
reactive,
|
||||
ref,
|
||||
@@ -17,9 +18,7 @@ import VbenModal from './modal.vue';
|
||||
|
||||
const USER_MODAL_INJECT_KEY = Symbol('VBEN_MODAL_INJECT');
|
||||
|
||||
const DEFAULT_MODAL_PROPS: Partial<ModalProps> = {
|
||||
destroyOnClose: true,
|
||||
};
|
||||
const DEFAULT_MODAL_PROPS: Partial<ModalProps> = {};
|
||||
|
||||
export function setDefaultModalProps(props: Partial<ModalProps>) {
|
||||
Object.assign(DEFAULT_MODAL_PROPS, props);
|
||||
@@ -65,11 +64,20 @@ export function useVbenModal<TParentModalProps extends ModalProps = ModalProps>(
|
||||
slots,
|
||||
);
|
||||
},
|
||||
// eslint-disable-next-line vue/one-component-per-file
|
||||
{
|
||||
inheritAttrs: false,
|
||||
name: 'VbenParentModal',
|
||||
inheritAttrs: false,
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
* 在开启keepAlive情况下 直接通过浏览器按钮/手势等返回 不会关闭弹窗
|
||||
*/
|
||||
onDeactivated(() => {
|
||||
(extendedApi as ExtendedModalApi)?.close?.();
|
||||
});
|
||||
|
||||
return [Modal, extendedApi as ExtendedModalApi] as const;
|
||||
}
|
||||
|
||||
@@ -114,9 +122,10 @@ export function useVbenModal<TParentModalProps extends ModalProps = ModalProps>(
|
||||
slots,
|
||||
);
|
||||
},
|
||||
// eslint-disable-next-line vue/one-component-per-file
|
||||
{
|
||||
inheritAttrs: false,
|
||||
name: 'VbenModal',
|
||||
inheritAttrs: false,
|
||||
},
|
||||
);
|
||||
injectData.extendApi?.(extendedApi);
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/shadcn-ui",
|
||||
"version": "5.5.5",
|
||||
"version": "5.5.6",
|
||||
"#main": "./dist/index.mjs",
|
||||
"#module": "./dist/index.mjs",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
|
@@ -36,7 +36,7 @@ export interface VbenButtonGroupProps
|
||||
btnClass?: any;
|
||||
gap?: number;
|
||||
multiple?: boolean;
|
||||
options?: { label: CustomRenderType; value: ValueType }[];
|
||||
options?: { [key: string]: any; label: CustomRenderType; value: ValueType }[];
|
||||
showIcon?: boolean;
|
||||
size?: 'large' | 'middle' | 'small';
|
||||
}
|
||||
|
@@ -119,7 +119,7 @@ async function onBtnClick(value: ValueType) {
|
||||
<CircleCheckBig v-else-if="innerValue.includes(btn.value)" />
|
||||
<Circle v-else />
|
||||
</div>
|
||||
<slot name="option" :label="btn.label" :value="btn.value">
|
||||
<slot name="option" :label="btn.label" :value="btn.value" :data="btn">
|
||||
<VbenRenderContent :content="btn.label" />
|
||||
</slot>
|
||||
</Button>
|
||||
@@ -127,6 +127,9 @@ async function onBtnClick(value: ValueType) {
|
||||
</template>
|
||||
<style lang="scss" scoped>
|
||||
.vben-check-button-group {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
&:deep(.size-large) button {
|
||||
.icon-wrapper {
|
||||
margin-right: 0.3rem;
|
||||
@@ -159,5 +162,16 @@ async function onBtnClick(value: ValueType) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.no-gap > :deep(button):nth-of-type(1) {
|
||||
border-right-width: 0;
|
||||
}
|
||||
|
||||
&.no-gap {
|
||||
:deep(button + button) {
|
||||
margin-right: -1px;
|
||||
border-left-width: 1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@@ -21,6 +21,7 @@ interface Props extends PopoverRootProps {
|
||||
class?: ClassType;
|
||||
contentClass?: ClassType;
|
||||
contentProps?: PopoverContentProps;
|
||||
triggerClass?: ClassType;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {});
|
||||
@@ -32,6 +33,7 @@ const delegatedProps = computed(() => {
|
||||
class: _cls,
|
||||
contentClass: _,
|
||||
contentProps: _cProps,
|
||||
triggerClass: _tClass,
|
||||
...delegated
|
||||
} = props;
|
||||
|
||||
@@ -43,7 +45,7 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
||||
|
||||
<template>
|
||||
<PopoverRoot v-bind="forwarded">
|
||||
<PopoverTrigger>
|
||||
<PopoverTrigger :class="triggerClass">
|
||||
<slot name="trigger"></slot>
|
||||
|
||||
<PopoverContent
|
||||
|
@@ -10,7 +10,7 @@ import TabsIndicator from './tabs-indicator.vue';
|
||||
|
||||
interface Props {
|
||||
defaultValue?: string;
|
||||
tabs: SegmentedItem[];
|
||||
tabs?: SegmentedItem[];
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
|
@@ -224,15 +224,20 @@ defineExpose({
|
||||
:class="
|
||||
cn('cursor-pointer', getNodeClass?.(item), {
|
||||
'data-[selected]:bg-accent': !multiple,
|
||||
'cursor-not-allowed': disabled,
|
||||
})
|
||||
"
|
||||
v-bind="
|
||||
Object.assign(item.bind, {
|
||||
onfocus: disabled ? 'this.blur()' : undefined,
|
||||
})
|
||||
"
|
||||
v-bind="item.bind"
|
||||
@select="
|
||||
(event) => {
|
||||
if (event.detail.originalEvent.type === 'click') {
|
||||
event.preventDefault();
|
||||
}
|
||||
onSelect(item, event.detail.isSelected);
|
||||
!disabled && onSelect(item, event.detail.isSelected);
|
||||
}
|
||||
"
|
||||
@toggle="
|
||||
@@ -240,7 +245,7 @@ defineExpose({
|
||||
if (event.detail.originalEvent.type === 'click') {
|
||||
event.preventDefault();
|
||||
}
|
||||
onToggle(item);
|
||||
!disabled && onToggle(item);
|
||||
}
|
||||
"
|
||||
class="tree-node focus:ring-grass8 my-0.5 flex items-center rounded px-2 py-1 outline-none focus:ring-2"
|
||||
@@ -262,10 +267,11 @@ defineExpose({
|
||||
<Checkbox
|
||||
v-if="multiple"
|
||||
:checked="isSelected"
|
||||
:disabled="disabled"
|
||||
:indeterminate="isIndeterminate"
|
||||
@click="
|
||||
() => {
|
||||
handleSelect();
|
||||
!disabled && handleSelect();
|
||||
// onSelect(item, !isSelected);
|
||||
}
|
||||
"
|
||||
@@ -276,7 +282,7 @@ defineExpose({
|
||||
(_event) => {
|
||||
// $event.stopPropagation();
|
||||
// $event.preventDefault();
|
||||
handleSelect();
|
||||
!disabled && handleSelect();
|
||||
// onSelect(item, !isSelected);
|
||||
}
|
||||
"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/tabs-ui",
|
||||
"version": "5.5.5",
|
||||
"version": "5.5.6",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
@@ -12,7 +12,6 @@ interface Props extends TabsProps {}
|
||||
|
||||
defineOptions({
|
||||
name: 'VbenTabsChrome',
|
||||
// eslint-disable-next-line perfectionist/sort-objects
|
||||
inheritAttrs: false,
|
||||
});
|
||||
|
||||
@@ -41,14 +40,14 @@ const style = computed(() => {
|
||||
|
||||
const tabsView = computed(() => {
|
||||
return props.tabs.map((tab) => {
|
||||
const { fullPath, meta, name, path } = tab || {};
|
||||
const { fullPath, meta, name, path, key } = tab || {};
|
||||
const { affixTab, icon, newTabTitle, tabClosable, title } = meta || {};
|
||||
return {
|
||||
affixTab: !!affixTab,
|
||||
closable: Reflect.has(meta, 'tabClosable') ? !!tabClosable : true,
|
||||
fullPath,
|
||||
icon: icon as string,
|
||||
key: fullPath || path,
|
||||
key,
|
||||
meta,
|
||||
name,
|
||||
path,
|
||||
|
@@ -12,7 +12,7 @@ interface Props extends TabsProps {}
|
||||
|
||||
defineOptions({
|
||||
name: 'VbenTabs',
|
||||
// eslint-disable-next-line perfectionist/sort-objects
|
||||
|
||||
inheritAttrs: false,
|
||||
});
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
@@ -47,14 +47,14 @@ const typeWithClass = computed(() => {
|
||||
|
||||
const tabsView = computed(() => {
|
||||
return props.tabs.map((tab) => {
|
||||
const { fullPath, meta, name, path } = tab || {};
|
||||
const { fullPath, meta, name, path, key } = tab || {};
|
||||
const { affixTab, icon, newTabTitle, tabClosable, title } = meta || {};
|
||||
return {
|
||||
affixTab: !!affixTab,
|
||||
closable: Reflect.has(meta, 'tabClosable') ? !!tabClosable : true,
|
||||
fullPath,
|
||||
icon: icon as string,
|
||||
key: fullPath || path,
|
||||
key,
|
||||
meta,
|
||||
name,
|
||||
path,
|
||||
|
@@ -15,5 +15,5 @@ pnpm add @vben/constants
|
||||
### 使用
|
||||
|
||||
```ts
|
||||
import { DEFAULT_HOME_PATH } from '@vben/constants';
|
||||
import { LOGIN_PATH } from '@vben/constants';
|
||||
```
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/constants",
|
||||
"version": "5.5.5",
|
||||
"version": "5.5.6",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
@@ -3,11 +3,6 @@
|
||||
*/
|
||||
export const LOGIN_PATH = '/auth/login';
|
||||
|
||||
/**
|
||||
* @zh_CN 默认首页地址
|
||||
*/
|
||||
export const DEFAULT_HOME_PATH = '/analytics';
|
||||
|
||||
export interface LanguageOption {
|
||||
label: string;
|
||||
value: 'en-US' | 'zh-CN';
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user