├── .editorconfig ├── .gitattributes ├── .gitignore ├── .npmrc ├── .vitepress ├── config.ts ├── icon.ts ├── locales │ ├── jp.ts │ └── zh.ts └── theme │ ├── index.ts │ └── style.css ├── .vscode ├── extensions.json ├── launch.json └── settings.json ├── CHANGELOG.md ├── LICENSE ├── README.md ├── eslint.config.js ├── package.json ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── src ├── assets │ ├── VSCode调试指南01.png │ ├── VSCode调试指南02.png │ ├── VSCode调试指南03.png │ ├── loading01.png │ └── router-guard-flow.png ├── awesome │ └── index.md ├── faq │ └── index.md ├── guide │ ├── cli │ │ ├── command.md │ │ ├── git-hooks.md │ │ └── intro.md │ ├── hooks │ │ └── use-table.md │ ├── icon │ │ ├── intro.md │ │ └── usage.md │ ├── intro.md │ ├── quick-start.md │ ├── request │ │ ├── backend.md │ │ ├── intro.md │ │ ├── proxy.md │ │ └── usage.md │ ├── router │ │ ├── cache.md │ │ ├── component.md │ │ ├── create.md │ │ ├── dynamic.md │ │ ├── guard.md │ │ ├── intro.md │ │ ├── push.md │ │ └── structure.md │ ├── sync.md │ └── theme │ │ ├── config.md │ │ ├── intro.md │ │ ├── loading.md │ │ ├── logo.md │ │ ├── tokens.md │ │ ├── ui.md │ │ └── unocss.md ├── index.md ├── jp │ ├── awesome │ │ └── index.md │ ├── cooperate │ │ └── index.md │ ├── faq │ │ └── index.md │ ├── guide │ │ ├── cli │ │ │ ├── command.md │ │ │ ├── git-hooks.md │ │ │ └── intro.md │ │ ├── hooks │ │ │ └── use-table.md │ │ ├── icon │ │ │ ├── intro.md │ │ │ └── usage.md │ │ ├── intro.md │ │ ├── quick-start.md │ │ ├── request │ │ │ ├── backend.md │ │ │ ├── intro.md │ │ │ ├── proxy.md │ │ │ └── usage.md │ │ ├── router │ │ │ ├── cache.md │ │ │ ├── component.md │ │ │ ├── create.md │ │ │ ├── dynamic.md │ │ │ ├── guard.md │ │ │ ├── intro.md │ │ │ ├── push.md │ │ │ └── structure.md │ │ ├── sync.md │ │ └── theme │ │ │ ├── config.md │ │ │ ├── intro.md │ │ │ ├── loading.md │ │ │ ├── logo.md │ │ │ ├── tokens.md │ │ │ ├── ui.md │ │ │ └── unocss.md │ ├── index.md │ ├── other │ │ └── donate.md │ ├── recommend │ │ ├── alova.md │ │ ├── index.md │ │ ├── klona.md │ │ ├── page-spy.md │ │ └── soybean-cli.md │ ├── standard │ │ ├── index.md │ │ ├── lint.md │ │ ├── naming.md │ │ ├── synthesis.md │ │ ├── tools.md │ │ ├── ts.md │ │ └── vue.md │ └── tutorial │ │ ├── debug.md │ │ ├── git.md │ │ ├── index.md │ │ ├── nodejs.md │ │ ├── other.md │ │ └── software.md ├── other │ └── donate.md ├── public │ ├── favicon.ico │ ├── logo.svg │ ├── router-guard-flow.pdf │ └── tencent-qq.svg ├── recommend │ ├── alova.md │ ├── index.md │ ├── klona.md │ ├── page-spy.md │ └── soybean-cli.md ├── standard │ ├── index.md │ ├── lint.md │ ├── naming.md │ ├── synthesis.md │ ├── tools.md │ ├── ts.md │ └── vue.md ├── tutorial │ ├── debug.md │ ├── git.md │ ├── index.md │ ├── nodejs.md │ ├── other.md │ └── software.md └── zh │ ├── awesome │ └── index.md │ ├── cooperate │ └── index.md │ ├── faq │ └── index.md │ ├── guide │ ├── cli │ │ ├── command.md │ │ ├── git-hooks.md │ │ └── intro.md │ ├── hooks │ │ └── use-table.md │ ├── icon │ │ ├── intro.md │ │ └── usage.md │ ├── intro.md │ ├── quick-start.md │ ├── request │ │ ├── backend.md │ │ ├── intro.md │ │ ├── proxy.md │ │ └── usage.md │ ├── router │ │ ├── cache.md │ │ ├── component.md │ │ ├── create.md │ │ ├── dynamic.md │ │ ├── guard.md │ │ ├── intro.md │ │ ├── push.md │ │ └── structure.md │ ├── sync.md │ └── theme │ │ ├── config.md │ │ ├── intro.md │ │ ├── loading.md │ │ ├── logo.md │ │ ├── tokens.md │ │ ├── ui.md │ │ └── unocss.md │ ├── index.md │ ├── other │ └── donate.md │ ├── recommend │ ├── alova.md │ ├── index.md │ ├── klona.md │ ├── page-spy.md │ └── soybean-cli.md │ ├── standard │ ├── index.md │ ├── lint.md │ ├── naming.md │ ├── synthesis.md │ ├── tools.md │ ├── ts.md │ └── vue.md │ └── tutorial │ ├── debug.md │ ├── git.md │ ├── index.md │ ├── nodejs.md │ ├── other.md │ └── software.md └── tsconfig.json /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | indent_style = space 8 | indent_size = 2 9 | end_of_line = lf 10 | trim_trailing_whitespace = true 11 | insert_final_newline = true 12 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | "*.vue" eol=lf 2 | "*.js" eol=lf 3 | "*.ts" eol=lf 4 | "*.jsx" eol=lf 5 | "*.tsx" eol=lf 6 | "*.cjs" eol=lf 7 | "*.cts" eol=lf 8 | "*.mjs" eol=lf 9 | "*.mts" eol=lf 10 | "*.json" eol=lf 11 | "*.html" eol=lf 12 | "*.css" eol=lf 13 | "*.less" eol=lf 14 | "*.scss" eol=lf 15 | "*.sass" eol=lf 16 | "*.styl" eol=lf 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | .DS_Store 12 | dist 13 | dist-ssr 14 | coverage 15 | *.local 16 | 17 | /cypress/videos/ 18 | /cypress/screenshots/ 19 | 20 | # Editor directories and files 21 | .vscode/* 22 | !.vscode/extensions.json 23 | !.vscode/settings.json 24 | !.vscode/launch.json 25 | .idea 26 | *.suo 27 | *.ntvs* 28 | *.njsproj 29 | *.sln 30 | *.sw? 31 | 32 | package-lock.json 33 | yarn.lock 34 | 35 | .VSCodeCounter 36 | **/.vitepress/cache 37 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | registry=https://registry.npmmirror.com/ 2 | shamefully-hoist=true 3 | ignore-workspace-root-check=true -------------------------------------------------------------------------------- /.vitepress/icon.ts: -------------------------------------------------------------------------------- 1 | export const qqSvg = ` 2 | 3 | 7 | 10 | 14 | 18 | 21 | 25 | 26 | 27 | 30 | 31 | 32 | `; 33 | -------------------------------------------------------------------------------- /.vitepress/theme/index.ts: -------------------------------------------------------------------------------- 1 | import Theme from 'vitepress/theme'; 2 | import './style.css'; 3 | 4 | export default Theme; 5 | -------------------------------------------------------------------------------- /.vitepress/theme/style.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Customize default theme styling by overriding CSS variables: 3 | * https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css 4 | */ 5 | 6 | /** 7 | * Colors 8 | * -------------------------------------------------------------------------- */ 9 | 10 | :root { 11 | --vp-c-brand: #646cff; 12 | --vp-c-brand-light: #747bff; 13 | --vp-c-brand-lighter: #9499ff; 14 | --vp-c-brand-lightest: #bcc0ff; 15 | --vp-c-brand-dark: #535bf2; 16 | --vp-c-brand-darker: #454ce1; 17 | --vp-c-brand-dimm: rgba(100, 108, 255, 0.08); 18 | } 19 | 20 | /** 21 | * Component: Button 22 | * -------------------------------------------------------------------------- */ 23 | 24 | :root { 25 | --vp-button-brand-border: var(--vp-c-brand-light); 26 | --vp-button-brand-text: var(--vp-c-white); 27 | --vp-button-brand-bg: var(--vp-c-brand); 28 | --vp-button-brand-hover-border: var(--vp-c-brand-light); 29 | --vp-button-brand-hover-text: var(--vp-c-white); 30 | --vp-button-brand-hover-bg: var(--vp-c-brand-light); 31 | --vp-button-brand-active-border: var(--vp-c-brand-light); 32 | --vp-button-brand-active-text: var(--vp-c-white); 33 | --vp-button-brand-active-bg: var(--vp-button-brand-bg); 34 | } 35 | 36 | /** 37 | * Component: Home 38 | * -------------------------------------------------------------------------- */ 39 | 40 | :root { 41 | --vp-home-hero-name-color: transparent; 42 | --vp-home-hero-name-background: -webkit-linear-gradient( 43 | 120deg, 44 | var(--vp-c-brand-lightest) 30%, 45 | var(--vp-c-brand-darker) 46 | ); 47 | 48 | --vp-home-hero-image-background-image: linear-gradient(-45deg, var(--vp-c-brand-lightest) 30%, var(--vp-c-brand) 50%); 49 | --vp-home-hero-image-filter: blur(40px); 50 | } 51 | 52 | @media (min-width: 640px) { 53 | :root { 54 | --vp-home-hero-image-filter: blur(56px); 55 | } 56 | } 57 | 58 | @media (min-width: 960px) { 59 | :root { 60 | --vp-home-hero-image-filter: blur(72px); 61 | } 62 | } 63 | 64 | /** 65 | * Component: Custom Block 66 | * -------------------------------------------------------------------------- */ 67 | 68 | :root { 69 | --vp-custom-block-tip-border: var(--vp-c-brand); 70 | --vp-custom-block-tip-text: var(--vp-c-brand-darker); 71 | --vp-custom-block-tip-bg: var(--vp-c-brand-dimm); 72 | } 73 | 74 | .dark { 75 | --vp-custom-block-tip-border: var(--vp-c-brand); 76 | --vp-custom-block-tip-text: var(--vp-c-brand-lightest); 77 | --vp-custom-block-tip-bg: var(--vp-c-brand-dimm); 78 | } 79 | 80 | /** 81 | * Component: Algolia 82 | * -------------------------------------------------------------------------- */ 83 | 84 | .DocSearch { 85 | --docsearch-primary-color: var(--vp-c-brand) !important; 86 | } 87 | 88 | /** 89 | * Version Badge 90 | * -------------------------------------------------------------------------- */ 91 | 92 | .vt-badge { 93 | display: inline-block; 94 | border-radius: 6px; 95 | font-size: 0.65em; 96 | line-height: 1; 97 | font-weight: 600; 98 | letter-spacing: 2px; 99 | padding: 0.35em 0.4em 0.3em; 100 | position: relative; 101 | top: -0.65em; 102 | margin-left: 0.5em; 103 | color: #ffffff; 104 | transition: color 0.5s; 105 | background-color: var(--vp-c-brand); 106 | } 107 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "antfu.unocss", 4 | "dbaeumer.vscode-eslint", 5 | "editorconfig.editorconfig", 6 | "esbenp.prettier-vscode", 7 | "kisstkondoros.vscode-gutter-preview", 8 | "mariusalchimavicius.json-to-ts", 9 | "mhutchie.git-graph", 10 | "sdras.vue-vscode-snippets", 11 | "vue.volar" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "type": "chrome", 6 | "request": "launch", 7 | "name": "Vue debugger", 8 | "url": "http://localhost:9527", 9 | "webRoot": "${workspaceFolder}" 10 | }, 11 | { 12 | "type": "node", 13 | "request": "launch", 14 | "name": "TS debugger", 15 | "skipFiles": ["/**"], 16 | "runtimeArgs": ["--loader", "tsx"], 17 | "program": "${relativeFile}" 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.codeActionsOnSave": { 3 | "source.fixAll.eslint": "explicit", 4 | "source.organizeImports": "never" 5 | }, 6 | "eslint.experimental.useFlatConfig": true, 7 | "editor.formatOnSave": false, 8 | "eslint.validate": ["html", "css", "scss", "json", "jsonc"], 9 | "prettier.enable": false, 10 | "unocss.root": ["./"] 11 | } 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Soybean 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SoybeanAdmin Documentation 2 | 3 | [![github stars](https://img.shields.io/github/stars/soybeanjs/soybean-admin-docs)](https://github.com/soybeanjs/soybean-admin-docs) 4 | [![github forks](https://img.shields.io/github/forks/soybeanjs/soybean-admin-docs)](https://github.com/soybeanjs/soybean-admin-docs) 5 | [![gitee stars](https://gitee.com/honghuangdc/soybean-admin-docs/badge/star.svg)](https://gitee.com/honghuangdc/soybean-admin-docs) 6 | [![gitcode star](https://gitcode.com/soybeanjs/soybean-admin-docs/star/badge.svg)](https://gitcode.com/soybeanjs/soybean-admin-docs) 7 | 8 | ## 简介 9 | 10 | 这是 [SoybeanAdmin](https://github.com/honghuangdc/soybean-admin) 项目的官方文档。本文档使用 [VitePress](https://vitepress.dev/) 构建,提供多语言支持(中文和日语)。 11 | 12 | ## SoybeanAdmin 仓库 13 | 14 | - **NaiveUI 版本:** 15 | - [预览地址](https://naive.soybeanjs.cn/) 16 | - [Github 仓库](https://github.com/soybeanjs/soybean-admin) 17 | - [Gitee 仓库](https://gitee.com/honghuangdc/soybean-admin) 18 | - [Gitcode 仓库](https://gitcode.com/soybeanjs/soybean-admin) 19 | - **AntDesignVue 版本:** 20 | - [预览地址](https://antd.soybeanjs.cn/) 21 | - [Github 仓库](https://github.com/soybeanjs/soybean-admin-antd) 22 | - [Gitee 仓库](https://gitee.com/honghuangdc/soybean-admin-antd) 23 | - [Gitcode 仓库](https://gitcode.com/soybeanjs/soybean-admin-antd) 24 | - **ElementPlus 版本:** 25 | - [预览地址](https://elp.soybeanjs.cn/) 26 | - [Github 仓库](https://github.com/soybeanjs/soybean-admin-element-plus) 27 | - [Gitee 仓库](https://gitee.com/honghuangdc/soybean-admin-element-plus) 28 | - [Gitcode 仓库](https://gitcode.com/soybeanjs/soybean-admin-element-plus) 29 | - **旧版:** 30 | 31 | - [预览地址](https://legacy.soybeanjs.cn/) 32 | - [Github 仓库](https://github.com/soybeanjs/soybean-admin/tree/legacy) 33 | - [Gitee 仓库](https://gitee.com/honghuangdc/soybean-admin/tree/legacy) 34 | - [Gitcode 仓库](https://gitcode.com/soybeanjs/soybean-admin/tree/legacy) 35 | 36 | - **文档仓库:** 37 | - [Github 仓库](https://github.com/soybeanjs/soybean-admin-docs) 38 | - [Gitee 仓库](https://gitee.com/honghuangdc/soybean-admin-docs) 39 | - [Gitcode 仓库](https://gitcode.com/soybeanjs/soybean-admin-docs) 40 | 41 | ## 克隆 42 | 43 | ```bash 44 | # github 45 | git clone https://github.com/soybeanjs/soybean-admin-docs.git 46 | # gitee 47 | git clone https://gitee.com/honghuangdc/soybean-admin-docs.git 48 | # gitcode 49 | git clone https://gitcode.com/soybeanjs/soybean-admin-docs.git 50 | ``` 51 | 52 | ## 安装 53 | 54 | ```bash 55 | # 安装依赖 56 | pnpm install 57 | ``` 58 | 59 | ## 开发 60 | 61 | ```bash 62 | # 启动开发服务器 63 | pnpm dev 64 | ``` 65 | 66 | ## 构建 67 | 68 | ```bash 69 | # 构建文档 70 | pnpm build 71 | ``` 72 | 73 | ## 预览构建结果 74 | 75 | ```bash 76 | # 预览构建后的文档 77 | pnpm preview 78 | ``` 79 | 80 | ## 项目结构 81 | 82 | - [`.vitepress`](.vitepress) - VitePress 配置和主题文件 83 | - `config.ts` - 主要配置文件 84 | - `locales/` - 多语言支持文件 85 | - [`src`](src) - 文档内容 86 | - `zh/` - 中文文档 87 | - `jp/` - 日语文档 88 | - `guide/` - 指南 89 | - `tutorial/` - 教程 90 | - `awesome/` - 精选资源 91 | - `standard/` - 规范 92 | - `faq/` - 常见问题 93 | - `recommend/` - 推荐内容 94 | 95 | ## 贡献指南 96 | 97 | 欢迎为 SoybeanAdmin 文档做出贡献,请参考以下步骤: 98 | 99 | 1. Fork 本仓库 100 | 2. 创建您的特性分支 (`git checkout -b feature/amazing-feature`) 101 | 3. 提交您的更改 (`git commit -m 'Add some amazing feature'`) 102 | 4. 推送到分支 (`git push origin feature/amazing-feature`) 103 | 5. 打开一个 Pull Request 104 | 105 | ## 许可证 106 | 107 | 本项目使用 MIT 许可证 进行许可。 108 | -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from '@soybeanjs/eslint-config'; 2 | 3 | export default defineConfig({ 4 | formatter: { 5 | markdown: true 6 | } 7 | }); 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "soybean-admin-docs", 3 | "type": "module", 4 | "version": "1.0.0", 5 | "description": "The documentation of SoybeanAdmin", 6 | "author": { 7 | "name": "Soybean", 8 | "email": "soybeanjs@outlook.com", 9 | "url": "https://github.com/soybeanjs" 10 | }, 11 | "license": "MIT", 12 | "homepage": "https://github.com/soybeanjs/soybean-admin-docs", 13 | "repository": { 14 | "url": "https://github.com/soybeanjs/soybean-admin-docs.git" 15 | }, 16 | "bugs": { 17 | "url": "https://github.com/soybeanjs/soybean-admin-docs/issues" 18 | }, 19 | "engines": { 20 | "node": ">=18.12.0", 21 | "pnpm": ">=8.7.0" 22 | }, 23 | "scripts": { 24 | "build": "vitepress build", 25 | "cleanup": "soy cleanup", 26 | "commit": "soy git-commit", 27 | "commit:zh": "soy git-commit -l=zh-cn", 28 | "dev": "vitepress dev --port 1026", 29 | "lint": "eslint . --fix", 30 | "preview": "vitepress serve", 31 | "release": "soy release", 32 | "typecheck": "vue-tsc --noEmit --skipLibCheck", 33 | "update-pkg": "soy ncu" 34 | }, 35 | "devDependencies": { 36 | "@soybeanjs/cli": "1.3.0", 37 | "@soybeanjs/eslint-config": "1.6.1", 38 | "@types/node": "22.15.19", 39 | "eslint": "9.27.0", 40 | "typescript": "5.8.3", 41 | "vitepress": "1.6.3" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | onlyBuiltDependencies: 2 | - unrs-resolver 3 | -------------------------------------------------------------------------------- /src/assets/VSCode调试指南01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soybeanjs/soybean-admin-docs/de47ce6a2600a0422e0992fc27188b5c36d0dade/src/assets/VSCode调试指南01.png -------------------------------------------------------------------------------- /src/assets/VSCode调试指南02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soybeanjs/soybean-admin-docs/de47ce6a2600a0422e0992fc27188b5c36d0dade/src/assets/VSCode调试指南02.png -------------------------------------------------------------------------------- /src/assets/VSCode调试指南03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soybeanjs/soybean-admin-docs/de47ce6a2600a0422e0992fc27188b5c36d0dade/src/assets/VSCode调试指南03.png -------------------------------------------------------------------------------- /src/assets/loading01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soybeanjs/soybean-admin-docs/de47ce6a2600a0422e0992fc27188b5c36d0dade/src/assets/loading01.png -------------------------------------------------------------------------------- /src/assets/router-guard-flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soybeanjs/soybean-admin-docs/de47ce6a2600a0422e0992fc27188b5c36d0dade/src/assets/router-guard-flow.png -------------------------------------------------------------------------------- /src/guide/cli/command.md: -------------------------------------------------------------------------------- 1 | # Command Line 2 | 3 | ## Overview 4 | 5 | The `sa` command line tool in the project provides some commonly used functions 6 | 7 | - `cleanup`: Delete directories: node_modules, dist, etc. 8 | - `update-pkg`: Update package.json dependency versions 9 | - `git-commit`: Generate commit messages that comply with the Conventional Commits standard 10 | - `git-commit-verify`: Verify git commit messages to ensure compliance with the Conventional Commits standard 11 | - `changelog`: Generate changelog 12 | - `release`: Release, update version, generate changelog, commit code 13 | - `gen-route`: Generate routes 14 | 15 | > The `sa` command is provided by `packages/scripts` 16 | -------------------------------------------------------------------------------- /src/guide/cli/git-hooks.md: -------------------------------------------------------------------------------- 1 | # Git Hooks 2 | 3 | ::: tip 4 | This document was generated by machine translation. If there are any errors, please inform us 5 | ::: 6 | 7 | ## Write in the front 8 | 9 | > Most code written in JS is used to using the runtime to determine if there is a problem with the code or not. 10 | > 11 | > For example, using JS development to interface with the back-end is such a process, when the interface is good, tune the interface, get the data, and then figure out how to stuff the data into the page inside the 12 | > 13 | > If it's a very simple page, this process seems to be fine. But for a slightly more complex one, the code written through this process would be the foundation of a mountain of shit, making it extremely headache-inducing to troubleshoot various issues in the later stage. 14 | 15 | TypeScript is a great tool to write high-quality code, the process of defining data types is the process of defining the front-end data model, once the data model has been determined, the data model of the various operations can be achieved using pure functions, and then the data combined with the responsive, you only need to introduce the corresponding pure functions to do a simple secondary packaging can be, most people do not adapt to the TS Most people are not comfortable with the type of TS, mainly because they haven't switched to the development mode. You can try to use this mode for a few sections to experience the charm of TypeScript, and then decide whether or not to remove the `git-hooks`. 16 | 17 | Using `git-hooks` for pre-commit checksums not only helps you improve your own code, but also reduces the cost of maintaining your project, and helps you take over other people's code. The few downsides to all of this are the small amount of time it takes to learn (SoybeanAdmin's project has 100% type coverage, which is best practice and the best time to get started with TypeScript) and get used to it, so you can try it out for a while (feel free to discuss this with the community) before deciding to remove it. You can try it out for a while (feel free to discuss it with us in the community) before deciding whether to remove `git-hooks`. 18 | 19 | ## Remove git-hooks 20 | 21 | ::: details Option 1: Temporary closure of checksums 22 | It is recommended to follow the well-established type checks as fully as possible initially, only skipping them slightly a few times by temporarily cancelling the submission checks when needed. 23 | 24 | ```shell 25 | git add . 26 | 27 | git commit -m "commit message" # [!code --] 28 | git commit -m "commit message" --no-verify # [!code ++] 29 | 30 | git push 31 | ``` 32 | 33 | ::: 34 | 35 | ::: details Option 2: Permanently disable checksums 36 | 37 | > [!CAUTION] not recommended 38 | > 1、Remove the commands from `simple-git-hooks` in `package.json 39 | > 40 | > 2、Execute the `simple-git-hooks` command. 41 | > 42 | > ::: 43 | -------------------------------------------------------------------------------- /src/guide/cli/intro.md: -------------------------------------------------------------------------------- 1 | # Commands 2 | 3 | ## cleanup 4 | 5 | Delete directories: node_modules, dist, etc. 6 | 7 | ```bash 8 | sa cleanup 9 | ``` 10 | 11 | ## update-pkg 12 | 13 | Update package.json dependency versions 14 | 15 | ```bash 16 | sa update-pkg 17 | ``` 18 | 19 | ## git-commit 20 | 21 | Generate commit messages that conform to the Conventional Commits standard 22 | 23 | ```bash 24 | sa git-commit 25 | ``` 26 | 27 | ## git-commit-verify 28 | 29 | Verify git commit messages to ensure they conform to the Conventional Commits standard 30 | 31 | ```bash 32 | sa git-commit-verify 33 | ``` 34 | 35 | ## changelog 36 | 37 | Generate changelog 38 | 39 | ```bash 40 | sa changelog 41 | ``` 42 | 43 | ## release 44 | 45 | Release, update version, generate changelog, commit code 46 | 47 | ```bash 48 | sa release 49 | ``` 50 | 51 | ## gen-route 52 | 53 | Generate routes 54 | 55 | ```bash 56 | sa gen-route 57 | ``` 58 | -------------------------------------------------------------------------------- /src/guide/icon/intro.md: -------------------------------------------------------------------------------- 1 | # System Icons 2 | 3 | ## Icon Rendering Principle 4 | 5 | Based on the svg json data of iconify, the svg data is converted into vue components through the unplugin-icons plugin. 6 | 7 | - [unplugin-icons](https://github.com/antfu/unplugin-icons) 8 | - [iconify](https://github.com/iconify/iconify) 9 | - [Journey with Icons Continues](https://antfu.me/posts/journey-with-icons-continues) 10 | 11 | ## Local svg icon rendering principle 12 | 13 | By using the `unplugin-icons` plugin and `vite-plugin-svg-icons` plugin, local svg files are converted into vue components 14 | 15 | > Local svg icons need to be placed in the src/assets/svg-icon directory 16 | 17 | ## Related configuration 18 | 19 | **.env configuration file** 20 | 21 | - VITE_ICON_PREFIX: iconify icon prefix 22 | - VITE_ICON_LOCAL_PREFIX: local svg icon prefix, the format follows {VITE_ICON_PREFIX}-{local icon name} 23 | 24 | ## Note 25 | 26 | Based on the rendering mechanism of svg icons, once the svg files are loaded and transformed into components, they become a part of your project and will not automatically detect and update any changes made to the source files. Therefore, if you modify an svg file and want to see the changes in your project, you need to restart the project. 27 | -------------------------------------------------------------------------------- /src/guide/icon/usage.md: -------------------------------------------------------------------------------- 1 | # Icon Tutorial 2 | 3 | ## I. Static Usage: Directly written in the template 4 | 5 | - **iconify** 6 | 7 | - Install the vscode smart prompt plugin: [Iconify IntelliSense](https://marketplace.visualstudio.com/items?itemName=antfu.iconify) 8 | 9 | - Find the icon: URL [https://icones.js.org/](https://icones.js.org/) or install vscode - [Icônes](https://marketplace.visualstudio.com/items?itemName=afzalsayed96.icones) 10 | 11 | - Determine the icon name: After finding the icon, copy the name such as: 'mdi:emoticon' or 'mdi-emoticon', the corresponding vue template is 12 | 13 | ```html 14 |
15 | 16 | 17 |
18 | ``` 19 | 20 | ::: tip Tip 21 | 'icon-' is a preset prefix, set the variable VITE_ICON_PREFIX in .env 22 | ::: 23 | 24 | - Set the style: Apply the style attribute or class attribute directly like the html tag; set the corresponding color and size by setting the color and font-size attributes 25 | 26 | - **Local svg icon** 27 | 28 | - Choose an svg in the src/assets/svg-icon directory, take its filename, for example: 'custom-icon.svg' 29 | 30 | - The corresponding vue template is 31 | 32 | ```html 33 | 34 | ``` 35 | 36 | ::: tip Tip 37 | 'icon-local' is a preset prefix, set the variable VITE_ICON_LOCAL_PREFIX in .env 38 | ::: 39 | 40 | ## II. Dynamic Rendering: Render corresponding icon based on the icon name 41 | 42 | - **iconify** 43 | 44 | - Determine the icon name, such as: 'mdi-emoticon' 45 | 46 | - Dynamic rendering 47 | 48 | ```html 49 | 50 | ``` 51 | 52 | - Dynamic rendering of multiple icons 53 | 54 | ```html 55 | 56 | ``` 57 | 58 | - **Local svg icons** 59 | 60 | - Determine the svg file name, for example: 'custom-icon.svg' 61 | 62 | - Dynamic rendering 63 | 64 | ```html 65 | 66 | ``` 67 | 68 | ::: tip Tip 69 | svg-icon is a global component that has been registered, directly applied in the template, the icon attribute is the iconify icon name, and local-icon is the file name of the local svg icon 70 | ::: 71 | 72 | ## III. Rendering through the render function: Suitable for NaiveUI icon rendering 73 | 74 | - Determine the icon name, such as: iconify: **'mdi-emoticon'**, or local svg icon 'custom-icon.svg' 75 | 76 | - Use **useSvgIconRender** 77 | 78 | ::: tip Code location 79 | packages/hooks/src/use-svg-icon-render.ts 80 | ::: 81 | 82 | ```typescript 83 | import { useSvgIconRender } from '@sa/hooks'; 84 | import SvgIcon from '@/components/custom/svg-icon.vue'; 85 | 86 | const { SvgIconVNode } = useSvgIconRender(SvgIcon); 87 | 88 | SvgIconVNode({ icon: 'ant-design:close-outlined', fontSize: 18 }); // iconify 89 | 90 | SvgIconVNode({ localIcon: 'custom-icon' }); // Local svg icon 91 | ``` 92 | 93 | ## IV. Offline Loading: Adding Specified Offline Iconify Icon Collections 94 | 95 | - **Usage Steps** 96 | 97 | - Install dependencies 98 | 99 | ```bash 100 | ## Include icon component data 101 | pnpm add @iconify/vue 102 | 103 | ## Include offline icon data 104 | pnpm add @iconify/json 105 | ``` 106 | 107 | ::: tip Tip 108 | The project has already imported the relevant dependencies, so you can directly reference them in the component. 109 | ::: 110 | 111 | - Prepare offline icon collection data 112 | 113 | For example, if we need to use the `Ant Design` icon library in our project, we can introduce offline icons as follows 114 | 115 | ```typescript 116 | import AntDesign from '@iconify/json/json/ant-design.json'; 117 | ``` 118 | 119 | - Use the `addCollection` method to add offline icons in the page 120 | 121 | ```typescript 122 | import { addCollection } from '@iconify/vue'; 123 | ``` 124 | 125 | - **Code Example** 126 | 127 | ```vue 128 | 134 | 135 | 138 | ``` 139 | -------------------------------------------------------------------------------- /src/guide/request/backend.md: -------------------------------------------------------------------------------- 1 | # Backend Integration 2 | 3 | ## Confirm the data structure type of the backend return result 4 | 5 | The default is as follows: 6 | 7 | `App.Service.Response`: 8 | 9 | ```ts 10 | type Response = { 11 | /** Business status code */ 12 | code: string; 13 | /** Response message */ 14 | msg: string; 15 | /** Response data */ 16 | data: T; 17 | }; 18 | ``` 19 | 20 | > Please modify according to the data type returned by your own backend 21 | 22 | ## Configure the success code of backend request 23 | 24 | Change the configuration `VITE_SERVICE_SUCCESS_CODE` in `.env` 25 | 26 | > The configuration loaded by the environment file is of string type. If the code returned by the backend is of numeric type, it needs to be converted to the same type for comparison. 27 | 28 | ## Configure other codes related to backend requests 29 | 30 | Refer to the [configuration items](./intro.md#request-related-configuration-introduction) in the request introduction 31 | -------------------------------------------------------------------------------- /src/guide/request/intro.md: -------------------------------------------------------------------------------- 1 | # Request 2 | 3 | ## Multiple Request Environments 4 | 5 | Development projects often use multiple request environment addresses: such as the backend address for the user development environment, the backend address for the test environment, the backend address for the pre-production environment, and the address for the production environment, etc. 6 | 7 | Configure multiple request addresses in the environment file, and then determine which request address to use in the request function based on the environment variable. 8 | 9 | The current project's environment files are 10 | 11 | `.env.prod`, `.env.test` 12 | 13 | ## Introduction to Request Related Configuration 14 | 15 | Configuration items in the `.env` file 16 | 17 | - `VITE_SERVICE_SUCCESS_CODE`: The code for successful backend requests 18 | - `VITE_SERVICE_LOGOUT_CODES`: The code for backend request failures that require the user to log out, multiple codes are separated by `,` 19 | - `VITE_SERVICE_MODAL_LOGOUT_CODES`: The code for backend request failures that require the user to log out (reminded by popup), multiple codes are separated by `,` 20 | - `VITE_SERVICE_EXPIRED_TOKEN_CODES`: The code for backend request failures and refresh token, multiple codes are separated by `,` 21 | 22 | Configuration items in the `.env.test` or `.env.prod` file 23 | 24 | - `VITE_SERVICE_BASE_URL`: The base address for requests 25 | - `VITE_OTHER_SERVICE_BASE_URL`: The base address for other requests 26 | 27 | ### Introduction to Request Functions 28 | 29 | 1. **Request functions: createRequest and createFlatRequest** 30 | 31 | `createRequest`: The returned request instance directly returns Axios response data (convertible) 32 | 33 | `createFlatRequest`: The returned request instance will wrap the response data and error information in a flat object, and return the result in a unified format. 34 | 35 | 2. **Parameters for createRequest/createFlatRequest** 36 | 37 | `axiosConfig`: axios configuration, input baseUrl, define some other configurations: such as: request timeout, request header, etc. 38 | 39 | `options`: Configure input validation and other logic (see `RequestOption` below) 40 | 41 | ```ts 42 | interface RequestOption { 43 | /** 44 | * Execute before sending the request to modify the request configuration, for example: add request header token 45 | */ 46 | onRequest: (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig | Promise; 47 | /** 48 | * Determine whether the backend response is successful by comparing the code returned by the backend 49 | */ 50 | isBackendSuccess: (response: AxiosResponse) => boolean; 51 | /** 52 | * The asynchronous function called when the backend request indicates failure in business, for example: handle token expiration 53 | */ 54 | onBackendFail: ( 55 | response: AxiosResponse, 56 | instance: AxiosInstance 57 | ) => Promise | Promise; 58 | /** 59 | * When responseType is json, convert the backend response data 60 | */ 61 | transformBackendResponse(response: AxiosResponse): any | Promise; 62 | /** 63 | * The function called when the request fails (including request failure and backend business failure request), for example: handle error information 64 | */ 65 | onError: (error: AxiosError) => void | Promise; 66 | } 67 | ``` 68 | -------------------------------------------------------------------------------- /src/guide/request/proxy.md: -------------------------------------------------------------------------------- 1 | # Proxy 2 | 3 | ## Outlined 4 | 5 | The project creates the base path of the service and a string to match the proxy through the `createServiceConfig` function. 6 | 7 | ::: tip Code Location 8 | @/utils/service.ts 9 | ::: 10 | 11 | The proxy is then created in the `createViteProxy` function based on the configuration obtained above. 12 | 13 | ## Enable/disable 14 | 15 | Enable or disable proxies via `VITE_HTTP_PROXY` in the `env` file. 16 | 17 | ::: tip Code Location 18 | ~.env 19 | ::: 20 | 21 | In `@/service/request/index.ts`, you decide whether the URL needs to handle proxies by passing `isHttpProxy` to the second parameter of `getServiceBaseURL`, which is determined based on the environment in which the code is running in conjunction with `VITE_HTTP_PROXY`. You can deconstruct the request URL here by passing different parameters. 22 | 23 | ``` 24 | const isHttpProxy = import.meta.env.DEV && import.meta.env.VITE_HTTP_PROXY === 'Y'; 25 | const { baseURL } = getServiceBaseURL(import.meta.env, isHttpProxy); 26 | const { otherBaseURL } = getServiceBaseURL(import.meta.env, false); 27 | ``` 28 | 29 | ## Principle 30 | 31 | SoybeanAdmin simplifies the process of configuring proxies by setting the matching string to `/proxy-default/` (other requests use `proxy-{key}`). This way, when configuring the proxy, you only need to replace `/proxy-default/` in the request address with the actual request address, thus achieving the proxy configuration. 32 | 33 | ```ts 34 | { 35 | '/proxy-default': { 36 | target: 'https://default.com', 37 | changeOrigin: true, 38 | rewrite: (path) => path.replace(/^\/proxy-default/, ''), 39 | }, 40 | '/proxy-demo': { 41 | target: 'https://demo.com', 42 | changeOrigin: true, 43 | rewrite: (path) => path.replace(/^\/proxy-demo/, ''), 44 | } 45 | } 46 | ``` 47 | 48 | ### Note 49 | 50 | Here are 2 configurations that are easily confused: 51 | 52 | 1. Suppose the path of a request is `https://example.com/api/user`, most would configure the proxy like this: 53 | 54 | ```ts 55 | 56 | { 57 | '/api': { 58 | target: 'https://example.com', 59 | changeOrigin: true, 60 | } 61 | } 62 | 63 | ``` 64 | 65 | > In this case, `/api` serves both as the matching string and the request path. Therefore, there is no rewrite configuration needed because the request path and the matching string are the same. 66 | 67 | 2. Suppose the path of a request is `https://example.com/user`, but the matching string for the proxy configuration is `/api` 68 | 69 | ```ts 70 | { 71 | '/api': { 72 | target: 'https://example.com', 73 | changeOrigin: true, 74 | rewrite: (path) => path.replace(/^\/api/, ''), 75 | } 76 | } 77 | ``` 78 | 79 | > In this case, `/api` serves as the matching string, and user serves as the request path. Therefore, a rewrite configuration is needed to remove the matching string. 80 | 81 | In SoybeanAdmin, the second configuration with `rewrite` is used. This is to support proxies for multiple services and avoid conflicts where multiple services contain the same `/api` path. Therefore, SoybeanAdmin chooses to create matching strings like `/proxy-*` to separate the matching string from the request path, avoiding conflicts. 82 | -------------------------------------------------------------------------------- /src/guide/router/cache.md: -------------------------------------------------------------------------------- 1 | # Route Caching 2 | 3 | ## Principle 4 | 5 | Route caching is implemented through the `keep-alive` component of `vue-router`. The `keep-alive` component caches the state of the component. When the component is visited again, it will directly take the component from the cache, instead of creating a new component. 6 | Since the `keep-alive` component uses the `name` attribute of the component as the key for caching, the page components in the project have been automatically injected with the `name` attribute through the `@elegant-router/vue` plugin, so you only need to set the `keepAlive` field of the `meta` attribute in the route data. 7 | The multi-level route caching of `vue-router` has problems, so the route data in the project has been converted into two-level routes to ensure that each route can be cached normally. 8 | 9 | 10 | ## Usage 11 | 12 | By setting the `keepAlive` field in the `meta` attribute of the route data, you can control whether the route is cached. 13 | 14 | ```js 15 | { 16 | name: 'about', 17 | path: '/about', 18 | component: 'layout.base$view.about', 19 | meta: { 20 | title: 'about', 21 | keepAlive: true 22 | } 23 | } 24 | ``` 25 | -------------------------------------------------------------------------------- /src/guide/router/component.md: -------------------------------------------------------------------------------- 1 | # Routing component 2 | 3 | ## Layout components 4 | 5 | - **layout.base**: Layout with common parts, such as global header, sidebar, footer, etc. 6 | 7 | - **layout.blank**: Blank layout 8 | 9 | ## Page components 10 | 11 | - **view.[RouteKey]**: Page components 12 | > For example: `view.home`, `view.multi-menu_first_child` 13 | 14 | ## Mixed components of layout and page 15 | 16 | - **layout.base$view.[RouteKey]**: Mixed components of layout and page 17 | > For example: `layout.base$view.home`, `layout.base$view.multi-menu_first_child` 18 | 19 | ::: tip Tip 20 | This type of component represents a single-level route 21 | ::: 22 | -------------------------------------------------------------------------------- /src/guide/router/create.md: -------------------------------------------------------------------------------- 1 | # Route Creation 2 | 3 | ## Command Creation 4 | 5 | By executing the `pnpm gen-route` command, you can quickly create route files. 6 | 7 | **Naming rules for route names** 8 | 9 | - First-level route: `demo`, `demo-page`, `route1` 10 | > The name is in the form of lowercase with hyphen `-` 11 | - Second-level route: `demo2_child`, `demo2-page_child`, `route2_child` 12 | > The level of the route is separated by an underscore `_`, and both sides still follow the naming rules of the first-level route 13 | - Third-level and above routes: `demo3_child_child`, `demo3-page_child_child_child` 14 | 15 | ## Manual Creation 16 | 17 | **When manually creating route files, the following rules need to be followed:** 18 | The name of the folder for each level of route is the route name, and the index.vue or [id].vue under the folder is the route component. 19 | -------------------------------------------------------------------------------- /src/guide/router/dynamic.md: -------------------------------------------------------------------------------- 1 | # Route Permissions 2 | 3 | ::: tip 4 | This document was generated by machine translation. If there are any errors, please inform us 5 | ::: 6 | 7 | ## Guide 8 | 9 | ### Fixed Routes (Routes Accessible Without Permission) 10 | 11 | In static route mode, route permissions are controlled by `meta.constant`. Routes with `constant` set to `true` can be accessed without logging in; 12 | In dynamic route mode, routes accessible without logging in need to be returned in the `fetchGetConstantRoutes` interface. In other words, routes with `constant` set to `true` returned in `fetchGetUserRoutes` will not take effect and still require login to access; 13 | 14 | ### Permission Routes 15 | 16 | In static route mode, by default, routes require login to access. To configure permissions, you can add the `meta.roles` field. This field's type is `string[]`, configured in `UserInfo`. If a matching role is found, access is allowed, otherwise not. Matching occurs in the pre-route guard phase; 17 | In dynamic route mode, `meta.roles` can still be used, but it's generally preferred to let the backend control the route table return based on role permissions, excluding unauthorized routes; 18 | 19 | ## Dynamic Routes 20 | 21 | Modify the source of routes. The route table for static routes comes from `./src/router/elegant/routes.ts`, while the route table for dynamic routes comes from the `fetchGetConstantRoutes` and `fetchGetUserRoutes` interfaces. 22 | 23 | > [!WARNING] Note 24 | > The type of the route table returned by the interface must be consistent with the frontend's static route table type. Before attempting modifications, it is advisable to familiarize yourself with the project's unique route plugin and route table structure 25 | 26 | ### Enable/Disable 27 | 28 | Enable/disable dynamic route mode by configuring the `VITE_AUTH_ROUTE_MODE` variable in the `.env` file. 29 | 30 | ::: tip Code Location 31 | .env 32 | ::: 33 | 34 | ```dotenv:line-numbers=14 35 | # auth route mode: static | dynamic 36 | VITE_AUTH_ROUTE_MODE=dynamic 37 | ``` 38 | -------------------------------------------------------------------------------- /src/guide/router/guard.md: -------------------------------------------------------------------------------- 1 | # Router Guard 2 | 3 | ## Router guard flow 4 | 5 | ![](../../assets/router-guard-flow.png) 6 | 7 | [HD PDF](/router-guard-flow.pdf) 8 | -------------------------------------------------------------------------------- /src/guide/router/intro.md: -------------------------------------------------------------------------------- 1 | # System Routing 2 | 3 | The routing of this system is based on the plugin [Elegant Router](https://github.com/soybeanjs/elegant-router). For detailed usage, please refer to the plugin documentation. 4 | 5 | ::: danger 6 | Since the `` tag is used to support page transition animations, there can only be one root element in the `template` of the `.vue` file, and neither annotations nor plain text can be used, there must be only one root element. 7 | Related Documents: [Transition | Vue.js (vuejs.org)](https://cn.vuejs.org/guide/built-ins/transition.html#the-transition-component) 8 | ::: 9 | 10 | ## Auto-generation 11 | 12 | After starting the project, the plugin will automatically generate the src/router/elegant directory. The files in this directory are automatically generated files for route import, route definition, and route conversion. 13 | 14 | > [!IMPORTANT] 15 | > Routing is a byproduct of files, so deleting a route is deleting a file, and the route will disappear along with the file.
The only content that can be modified by routing is the `component` and `meta` information, and the automatically generated operation will not affect these two properties. 16 | 17 | ## Configuration properties 18 | 19 | ### 1. type RouteKey 20 | 21 | **Explanation:** 22 | 23 | The union type RouteKey declares all route keys for easy unified management of routes. This type is automatically generated by the plugin [Elegant Router](https://github.com/soybeanjs/elegant-router) based on the page files under views. 24 | 25 | ::: tip Code location 26 | src/typings/elegant-router.d.ts 27 | ::: 28 | 29 | ### 2. type RoutePath 30 | 31 | **Explanation:** 32 | 33 | The path of the route, this type corresponds one-to-one with RouteKey 34 | 35 | ### 3. type RouteMeta 36 | 37 | ```typescript 38 | // Route meta information interface 39 | interface RouteMeta { 40 | /** 41 | * Route title 42 | * 43 | * Can be used in the document title 44 | */ 45 | title: string; 46 | /** 47 | * The internationalization key of the route 48 | * 49 | * If set, it will be used for i18n, and the title will be ignored at this time 50 | */ 51 | i18nKey?: App.I18n.I18nKey; 52 | /** 53 | * The role list of the route 54 | * 55 | * When the current user has at least one role, the route is allowed to be accessed. When the role list is empty, it means no permission is required 56 | */ 57 | roles?: string[]; 58 | /** Whether to cache this route */ 59 | keepAlive?: boolean; 60 | /** 61 | * Whether it is a constant route 62 | * 63 | * No login is required, and the route is defined on the front end 64 | */ 65 | constant?: boolean; 66 | /** 67 | * Iconify icon 68 | * 69 | * Can be used in the menu or breadcrumbs 70 | */ 71 | icon?: string; 72 | /** 73 | * Local icon 74 | * 75 | * Located in the "src/assets/svg-icon" directory, if set, the icon property will be ignored 76 | */ 77 | localIcon?: string; 78 | /** Route sorting order */ 79 | order?: number; 80 | /** The external link of the route */ 81 | href?: string; 82 | /** Whether to hide this route in the menu */ 83 | hideInMenu?: boolean; 84 | /** 85 | * The menu key activated when entering this route 86 | * 87 | * This route is not in the menu 88 | * 89 | * @example 90 | * Suppose the route is "user_detail", if set to "user_list", the "User List" menu item will be activated 91 | */ 92 | activeMenu?: import('@elegant-router/types').RouteKey; 93 | /** By default, routes with the same path share a tab. If set to true, multiple tabs are used */ 94 | multiTab?: boolean; 95 | /** If set, the route will be displayed fixed in the tab, and its value represents the order of the fixed tab.(The home page is special, it will automatically stay fixed) */ 96 | fixedIndexInTab?: number; 97 | /** if set query parameters, it will be automatically carried when entering the route */ 98 | query?: { key: string; value: string }[] | null; 99 | } 100 | ``` 101 | 102 | ::: tip Tip 103 | Get the icon value from here: [https://icones.js.org/](https://icones.js.org/) 104 | ::: 105 | 106 | ## Note 107 | 108 | If you create a route page in views, call it elsewhere but do not show it in the menu, then you need to set `hideInMenu: true` in meta 109 | 110 | ```typescript 111 | { 112 | name: '403', 113 | path: '/403', 114 | component: 'layout.blank$view.403', 115 | meta: { 116 | title: '403', 117 | i18nKey: 'route.403', 118 | hideInMenu: true 119 | } 120 | } 121 | ``` 122 | -------------------------------------------------------------------------------- /src/guide/router/push.md: -------------------------------------------------------------------------------- 1 | # Router Push 2 | 3 | ::: tip 4 | This document was generated by machine translation. If there are any errors, please inform us 5 | ::: 6 | 7 | In the project, you can use normal `router.push` and other conventional ways to route jump, you can also use the project provides `useRouterPush` to jump (recommended), this article mainly introduces `useRouterPush`. 8 | 9 | ## Introduce 10 | 11 | This hook encapsulates `router.push` and is intended to be used in place of `router.push` to make jumping easier. `useRouterPush` returns an object containing the following properties and methods: 12 | 13 | - routerPush: The push method of the Vue Router. 14 | - routerBack: The back method of the Vue Router. 15 | - routerPushByKey: The method to push based on the route key. 16 | - toLogin: method to jump to the login page. 17 | - toggleLoginModule: Method to toggle the login module. 18 | - redirectFromLogin: method to redirect from login page. 19 | 20 | ::: warning 21 | Pass `false` to `useRouterPush` when used outside of `setup`. 22 | ::: 23 | 24 | ## explanation 25 | 26 | `routerPush` and `routerBack` are all original attributes, so I won't go into them again, but I'll focus on the latter ones here. 27 | 28 | ### routerPushByKey 29 | 30 | The `key` here refers to the `name` attribute of the route, e.g. a route configured as: 31 | 32 | ```json 33 | { 34 | "name": "soybean", 35 | "path": "/soybean-page", 36 | "component": "layout.base$view.soybean-page" 37 | } 38 | ``` 39 | 40 | Then the code to jump to that route is: 41 | 42 | ```ts 43 | import { useRouterPush } from '@/hooks/common/router'; 44 | 45 | const { routerPushByKey } = useRouterPush(); 46 | 47 | routerPushByKey('soybean'); 48 | ``` 49 | 50 | It supports passing optional parameters `query` or `params`. 51 | 52 | ### toLogin 53 | 54 | Literally, quickly jump to the login page, note that before jumping to clear the login information, otherwise in the route guard will be intercepted back to the home page of the same. 55 | 56 | ### toggleLoginModule 57 | 58 | The method passes in parameters of type is: 59 | 60 | ```ts 61 | /** 62 | * The login module 63 | * 64 | * - pwd-login: password login 65 | * - code-login: phone code login 66 | * - register: register 67 | * - reset-pwd: reset password 68 | * - bind-wechat: bind wechat 69 | */ 70 | type LoginModule = 'pwd-login' | 'code-login' | 'register' | 'reset-pwd' | 'bind-wechat'; 71 | ``` 72 | 73 | The function is to change the login module mounted on the login page based on the `LoginModule` passed in, you can remove or extend it yourself, just make sure it's of the right type. 74 | 75 | ### redirectFromLogin 76 | 77 | In the case of a successful login, it's better to see the name than to manually `push` it to the homepage. 78 | It will decide which route to redirect to based on the `redirect` query parameter of the login page, if there is no `redirect` parameter, it will jump to the home page by default. 79 | 80 | ## Use 81 | 82 | ```vue 83 | 84 | 89 | 90 | 95 | ``` 96 | 97 | ```ts 98 | 99 | import { useRouterPush } from '@/hooks/common/router'; 100 | 101 | // Note that passing in false 102 | const { routerPushByKey } = useRouterPush(false); 103 | 104 | function backToRoot() { 105 | routerPushByKey('root') 106 | } 107 | ``` 108 | -------------------------------------------------------------------------------- /src/guide/sync.md: -------------------------------------------------------------------------------- 1 | # Sync code 2 | 3 | 1. Add the `soybean-admin` git address to your own repository 4 | 5 | ```bash 6 | git remote add otherOrigin https://github.com/soybeanjs/soybean-admin.git 7 | ``` 8 | 9 | 2. Pull the code 10 | 11 | ```bash 12 | git fetch otherOrigin 13 | ``` 14 | 15 | 3. Pick the git commit that needs to be updated through `cherry-pick` 16 | 17 | ```bash 18 | git cherry-pick [commit id] 19 | ``` 20 | 21 | 4. When there is a conflict in the code, resolve the conflict, then excute the following command, and then execute `vim` to save 22 | 23 | ```bash 24 | git cherry-pick --continue 25 | ``` 26 | 27 | > `vim` save operation: `esc`, `:`, `wq`, `enter` 28 | -------------------------------------------------------------------------------- /src/guide/theme/config.md: -------------------------------------------------------------------------------- 1 | # Theme Config 2 | 3 | ## Typedef 4 | 5 | Reference `App.Theme.ThemeSetting` 6 | 7 | ::: tip source file 8 | src/typings/app.d.ts 9 | ::: 10 | 11 | ## Initial Config 12 | 13 | ```ts 14 | export const themeSettings: App.Theme.ThemeSetting = { 15 | //default config 16 | }; 17 | ``` 18 | 19 | ::: tip source file 20 | src/theme/settings.ts 21 | ::: 22 | 23 | ## Override Update 24 | 25 | When a new version is released, the theme config can be updated by configuring the override update method. 26 | 27 | ```ts 28 | export const overrideThemeSettings: Partial = { 29 | //override config 30 | }; 31 | ``` 32 | 33 | ::: tip source file 34 | src/theme/settings.ts 35 | ::: 36 | 37 | ## About Environment 38 | 39 | - When the project is in `dev`, the theme config will not be cached, but you can update the theme config by updating the`themeSettings` in`src/theme/settings.ts` 40 | 41 | > To see the changes in the theme config in real-time during the development stage, the theme config will not be cached. 42 | 43 | - When the project is in `prod`, the theme config will be cached in `localStorage` 44 | 45 | > Each time a new version is released, the theme config can be overridden by updating the `overrideThemeSettings` in `src/theme/settings.ts`. 46 | -------------------------------------------------------------------------------- /src/guide/theme/intro.md: -------------------------------------------------------------------------------- 1 | # System Theme 2 | 3 | The implementation of the system theme is divided into two parts, one part is the theme configuration of the component library, and the other part is the theme configuration of UnoCSS. In order to unify the theme configuration of the two parts, some theme configurations are maintained on this, which control the theme configuration of the component library and UnoCSS respectively through these theme configurations. 4 | 5 | ## Principle 6 | 7 | - Define some variables of theme configuration, including various theme colors, layout parameter configuration, etc. 8 | - Produce theme variables that conform to the component library through these configurations 9 | - Produce some theme tokens through these configurations and derive corresponding css variables, and then pass these css variables to UnoCSS 10 | -------------------------------------------------------------------------------- /src/guide/theme/loading.md: -------------------------------------------------------------------------------- 1 | # System Loading 2 | 3 | ![](../../assets/loading01.png) 4 | 5 | ## Style 6 | 7 | - The loading style during system initialization is implemented through HTML code 8 | 9 | ::: tip Component location 10 | src/plugins/loading.ts 11 | ::: 12 | 13 | - The system's Logo is implemented using the SystemLogo component 14 | 15 | [System Logo](./logo.md) 16 | 17 | ## Rendering Principle 18 | 19 | Create a setupLoading function, its main function is to set the animation effect when the page is loading. 20 | This loading animation includes a system Logo, a rotating dot matrix animation, and title text, and all element colors are dynamically generated based on the theme color themeColor obtained from local storage. 21 | And find the element with ID 'app' in the DOM as the mounting point for the loading animation. If this element is found, its internal HTML will be replaced with the just constructed loading animation HTML structure 22 | 23 | ```ts 24 | export function setupLoading() { 25 | const themeColor = localStg.get('themeColor') || '#DB5A6B'; 26 | 27 | const { r, g, b } = getRgbOfColor(themeColor); 28 | 29 | const primaryColor = `--primary-color: ${r} ${g} ${b}`; 30 | 31 | const loadingClasses = [ 32 | 'left-0 top-0', 33 | 'left-0 bottom-0 animate-delay-500', 34 | 'right-0 top-0 animate-delay-1000', 35 | 'right-0 bottom-0 animate-delay-1500' 36 | ]; 37 | 38 | const logoWithClass = systemLogo.replace(' { 42 | return `
`; 43 | }) 44 | .join('\n'); 45 | 46 | const loading = ` 47 |
48 | ${logoWithClass} 49 |
50 |
51 | ${dot} 52 |
53 |
54 |

${$t('system.title')}

55 |
`; 56 | 57 | const app = document.getElementById('app'); 58 | 59 | if (app) { 60 | app.innerHTML = loading; 61 | } 62 | } 63 | ``` 64 | 65 | ::: tip Code location 66 | src/plugins/loading.ts 67 | ::: 68 | 69 | Finally, the setupLoading function needs to be registered in main.ts 70 | 71 | ```typescript 72 | async function setupApp() { 73 | setupLoading(); 74 | app.mount('#app'); 75 | } 76 | ``` 77 | -------------------------------------------------------------------------------- /src/guide/theme/logo.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | System Logo is implemented using the SystemLogo component, which is an SFC component that can be styled through props. 4 | 5 | ```vue 6 | 9 | 10 | 13 | 14 | 15 | ``` 16 | 17 | ::: tip Code location 18 | src/components/common/system-logo.vue 19 | ::: 20 | 21 | > The specific implementation principle refers to [Local Icon](/guide/icon/intro) 22 | -------------------------------------------------------------------------------- /src/guide/theme/tokens.md: -------------------------------------------------------------------------------- 1 | # Theme Tokens 2 | 3 | ## Typedef 4 | 5 | ```ts 6 | type ThemeToken = { 7 | colors: ThemeTokenColor; 8 | boxShadow: { 9 | header: string; 10 | sider: string; 11 | tab: string; 12 | }; 13 | }; 14 | ``` 15 | 16 | ::: tip source file 17 | src/typings/app.d.ts 18 | ::: 19 | 20 | ## Tokens-based CSS variables 21 | 22 | Initialization generates some css variables on the html, which are based on theme tokens. 23 | 24 | ```ts 25 | /** Theme vars */ 26 | export const themeVars: App.Theme.ThemeToken = { 27 | colors: { 28 | ...colorPaletteVars, 29 | nprogress: 'rgb(var(--nprogress-color))', 30 | container: 'rgb(var(--container-bg-color))', 31 | layout: 'rgb(var(--layout-bg-color))', 32 | inverted: 'rgb(var(--inverted-bg-color))', 33 | base_text: 'rgb(var(--base-text-color))' 34 | }, 35 | boxShadow: { 36 | header: 'var(--header-box-shadow)', 37 | sider: 'var(--sider-box-shadow)', 38 | tab: 'var(--tab-box-shadow)' 39 | } 40 | }; 41 | ``` 42 | 43 | ::: tip source file 44 | src/theme/vars.ts 45 | ::: 46 | 47 | ## Initial Tokens 48 | 49 | ```ts 50 | /** 51 | * Create theme token 52 | * 53 | * @param colors Theme colors 54 | */ 55 | export function createThemeToken(colors: App.Theme.ThemeColor) { 56 | const paletteColors = createThemePaletteColors(colors); 57 | 58 | const themeTokens: App.Theme.ThemeToken = { 59 | colors: { 60 | ...paletteColors, 61 | nprogress: paletteColors.primary, 62 | container: 'rgb(255, 255, 255)', 63 | layout: 'rgb(247, 250, 252)', 64 | inverted: 'rgb(0, 20, 40)', 65 | base_text: 'rgb(31, 31, 31)' 66 | }, 67 | boxShadow: { 68 | header: '0 1px 2px rgb(0, 21, 41, 0.08)', 69 | sider: '2px 0 8px 0 rgb(29, 35, 41, 0.05)', 70 | tab: '0 1px 2px rgb(0, 21, 41, 0.08)' 71 | } 72 | }; 73 | 74 | const darkThemeTokens: App.Theme.ThemeToken = { 75 | colors: { 76 | ...themeTokens.colors, 77 | container: 'rgb(28, 28, 28)', 78 | layout: 'rgb(18, 18, 18)', 79 | base_text: 'rgb(224, 224, 224)' 80 | }, 81 | boxShadow: { 82 | ...themeTokens.boxShadow 83 | } 84 | }; 85 | 86 | return { 87 | themeTokens, 88 | darkThemeTokens 89 | }; 90 | } 91 | ``` 92 | 93 | ::: tip source file 94 | src/store/modules/theme/shared.ts 95 | ::: 96 | -------------------------------------------------------------------------------- /src/guide/theme/ui.md: -------------------------------------------------------------------------------- 1 | # UI Theme 2 | 3 | ## NaiveUI Theme Configuration 4 | 5 | **Get UI theme variables based on theme colors** 6 | 7 | ```ts 8 | /** 9 | * Get naive theme 10 | * 11 | * @param colors Theme colors 12 | */ 13 | function getNaiveTheme(colors: App.Theme.ThemeColor) { 14 | const { primary: colorLoading } = colors; 15 | 16 | const theme: GlobalThemeOverrides = { 17 | common: { 18 | ...getNaiveThemeColors(colors) 19 | }, 20 | LoadingBar: { 21 | colorLoading 22 | } 23 | }; 24 | 25 | return theme; 26 | } 27 | 28 | /** Naive theme */ 29 | const naiveTheme = computed(() => getNaiveTheme(themeColors.value)); 30 | ``` 31 | 32 | ::: tip Code location 33 | src/store/modules/theme/shared.ts 34 | 35 | src/store/modules/theme/index.ts 36 | ::: 37 | 38 | **Apply theme variables** 39 | 40 | ```vue 41 | 54 | ``` 55 | 56 | ::: tip Code location 57 | src/App.vue 58 | ::: 59 | 60 | ## AntDesignVue Theme Configuration 61 | 62 | **Get UI theme variables based on theme colors** 63 | 64 | ```ts 65 | /** 66 | * Get antd theme 67 | * 68 | * @param colors Theme colors 69 | * @param darkMode Is dark mode 70 | */ 71 | function getAntdTheme(colors: App.Theme.ThemeColor, darkMode: boolean) { 72 | const { defaultAlgorithm, darkAlgorithm } = antdTheme; 73 | 74 | const { primary, info, success, warning, error } = colors; 75 | 76 | const theme: ConfigProviderProps['theme'] = { 77 | token: { 78 | colorPrimary: primary, 79 | colorInfo: info, 80 | colorSuccess: success, 81 | colorWarning: warning, 82 | colorError: error 83 | }, 84 | algorithm: [darkMode ? darkAlgorithm : defaultAlgorithm], 85 | components: { 86 | Menu: { 87 | colorSubItemBg: 'transparent' 88 | } 89 | } 90 | }; 91 | 92 | return theme; 93 | } 94 | 95 | /** Antd theme */ 96 | const antdTheme = computed(() => getAntdTheme(themeColors.value, darkMode.value)); 97 | ``` 98 | 99 | ::: tip Code location 100 | src/store/modules/theme/shared.ts 101 | 102 | src/store/modules/theme/index.ts 103 | ::: 104 | 105 | **Apply theme variables** 106 | 107 | ```vue 108 | 115 | ``` 116 | -------------------------------------------------------------------------------- /src/guide/theme/unocss.md: -------------------------------------------------------------------------------- 1 | # UnoCSS Theme 2 | 3 | By inject [Theme Tokens](/guide/theme/tokens) into UnoCSS theme configuration, you can use UnoCSS's ability to use class names like `text-primary bg-primary` to unify the application of theme colors in the component library and UnoCSS. 4 | 5 | ```ts 6 | import { themeVars } from './src/theme/vars'; 7 | 8 | export default defineConfig({ 9 | theme: { 10 | ...themeVars 11 | } 12 | }); 13 | ``` 14 | 15 | ::: tip Code location 16 | ./uno.config.ts 17 | ::: 18 | 19 | ## UnoCSS Dark Mode 20 | 21 | By using the dark mode solution provided by UnoCSS, as long as the class="dark" is added to the html, the class like `dark:text-#000 dark:bg-#333` in the project will take effect, thus achieving the effect of dark mode. 22 | 23 | ```ts 24 | export default defineConfig({ 25 | presets: [presetUno({ dark: 'class' })] 26 | }); 27 | ``` 28 | 29 | ::: tip Code location 30 | ./uno.config.ts 31 | ::: 32 | -------------------------------------------------------------------------------- /src/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: home 3 | 4 | title: SoybeanAdmin 5 | titleTemplate: A fresh and elegant admin template 6 | 7 | hero: 8 | name: SoybeanAdmin 9 | text: Fresh and elegant 10 | tagline: Based on Vue3,Vite6,TypeScript and UnoCSS 11 | image: 12 | src: /logo.svg 13 | alt: SoybeanAdmin 14 | actions: 15 | - theme: brand 16 | text: Start 17 | link: /guide/quick-start 18 | - theme: alt 19 | text: Introduction 20 | link: /guide/intro 21 | - theme: alt 22 | text: View on GitHub 23 | link: https://github.com/soybeanjs/soybean-admin 24 | - theme: alt 25 | text: React Version Docs -> 26 | link: https://react-docs.soybeanjs.cn/ 27 | 28 | features: 29 | - icon: 🆕 30 | title: The latest technology stack popular in the community. 31 | details: Vue3, Vite6, TypeScript, Pinia, UnoCSS. 32 | - icon: 🔄 33 | title: Multi-framework Support 34 | details: Simultaneously supports Vue3 and React, allowing you to flexibly choose your front-end tech stack. 35 | - icon: 🎨 36 | title: Integration of Multiple Component Libraries 37 | details: Adapts to various component libraries such as Element Plus, Naive UI, Ant Design, and Ant Design Vue to meet diverse UI needs. 38 | - icon: 🦋 39 | title: Clean Structure 40 | details: Use pnpm monorepo, clean and elegant structure, easy to maintain. Very high code specification. 41 | - icon: 🛠️ 42 | title: TypeScript 43 | details: Strictly typed, easy for team development and maintenance. 44 | - icon: 🔩 45 | title: Theme 46 | details: Built-in rich theme configuration, easily integrate with UnoCSS. 47 | - icon: 🔗 48 | title: File routing System 49 | details: Automatic, intelligent file routing system. 50 | - icon: 🔑 51 | title: Auth Router 52 | details: Support front-end static routing and back-end dynamic routing. 53 | - icon: ⚙️ 54 | title: Extended Script Tools 55 | details: Provides multiple scripting capabilities, including one-click dependency upgrades, automatic generation of ChangeLogs, commit messages, etc., greatly improving development efficiency. 56 | --- 57 | 58 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 149 | 150 | 151 | -------------------------------------------------------------------------------- /src/jp/awesome/index.md: -------------------------------------------------------------------------------- 1 | # 周辺エコシステム 2 | 3 | ## オープンソースプロジェクト・作品 4 | 5 | | プロジェクト名 | 説明 | リンク | 6 | | ----------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- | 7 | | react-soybean-admin | Soybean をベースにした React バージョン!React18 / Redux-toolkit / Antd / Vite5 / TypeScript を採用し、シンプルかつエレガントな UI と、明快で分かりやすいバックエンドを備えた強力な管理システムです。ぜひお試しください! | https://github.com/mufeng889/react-soybean-admin | 8 | | RuoYi-Plus-Soybean | RuoYi-Plus-Soybeanは、RuoYi-Vue-Plusの強力なバックエンド機能とSoybean Adminの近代的なフロントエンド特性を組み合わせた近代的なエンタープライズクラスのマルチテナント管理システムであり、開発者に完全なエンタープライズ管理ソリューションを提供しています. | https://gitee.com/xlsea/ruoyi-plus-soybean | 9 | | pea | SpringBoot3.2 + JDK21、MyBatis-Plus、SpringSecurity を採用し、soybean-admin に適応したシンプルな権限管理システム | https://github.com/haitang1894/pea | 10 | | electron-mock-admin | フロントエンド開発者向けの Mock API 管理システム。API のモックを簡単に実現できます | https://github.com/lixin59/electron-mock-api | 11 | | T-Shell | カスタマイズ可能なコマンドプロンプトを備えたターミナルエミュレーターおよび SSH クライアント | https://github.com/TheBlindM/T-Shell | 12 | | MalusAdmin | Vue3 / TypeScript / NaiveUI & NET7 & Sqlsugar をベースにした管理システムフレームワーク。シンプルな UI、高い拡張性、明確な構造を備えた強力な管理システムを提供します | https://github.com/pridejoy/MalusAdmin | 13 | | PanisAdmin | SpringBoot3、SaToken、MySQL を採用し、soybean-admin をベースに動的メニューやボタンレベルの権限管理を追加。オリジナルの美しさと使いやすさをそのままに、管理システムのスキャフォールドとして活用できます | https://github.com/paynezhuang/panis-admin | 14 | | snail-job | 「高性能・高デザイン・高アクティブ」な分散ジョブリトライ & 分散ジョブスケジューリングプラットフォーム | https://github.com/aizuda/snail-job | 15 | | SuperApi | アイデアをすぐにオンライン製品に!エンティティレスの DB 操作、15種類の条件検索、ページング、ツリーリスト、API ドキュメント、Auth 認証、レート制限、高度なキャッシュ機能、ダイナミック API など、多機能 API デプロイを提供。 | https://github.com/TmmTop/SuperApi | 16 | | FastSoyAdmin | FastAPI + Vue3 + Naive UI をベースにした軽量の管理システム | https://github.com/sleep1223/fast-soy-admin | 17 | | web-firewall | Golang + Vue3 を採用した Linux 向け Web 防火壁。SoybeanAdmin をフロントエンドフレームワークに、バックエンドには goframe2 を使用し、sqlite3 (デフォルト) / PostgreSQL に対応。Linux で nfatables を活用し、firewalld の代替として利用可能 | https://github.com/moreKing/web-firewall | 18 | | soybean-admin-nestjs | NestJS と CQRS を基盤とした管理システムスキャフォールド。DDD (ドメイン駆動設計) と NestJS monorepo 構造を統合し、基本的な権限管理を内蔵。柔軟でモジュール化された開発をサポート。 | https://github.com/soybeanjs/soybean-admin-nestjs | 19 | | soybean-admin-quarkus | Kotlin & Quarkus を基盤とした管理システムスキャフォールド。DDD、CQRS、イベントソーシングを統合し、Gradle ベースで軽量かつ高性能な管理システム開発フレームワークを提供。 | https://github.com/soybeanjs/soybean-admin-quarkus | 20 | | jzero-admin | Golang の [go-zero](https://github.com/zeromicro/go-zero) フレームワークを拡張した [jzero](https://github.com/jzero-io/jzero) の管理システムスキャフォールド。サーバー/DB/クライアント SDK の自動生成やプラグイン化をサポート | 21 | | 基于 golang [go-zero](https://github.com/zeromicro/go-zero) | https://github.com/jzero-io/jzero-admin | 22 | | soybean-admin-go | GinおよびGORM+Genフレームワークに基づいて開発されたGoバックエンドサービスで、Soybean Adminのexampleブランチと統合されています。動的ルーティングとAPI権限認証をサポートしています。 | https://github.com/WgoW/soybean-admin-go | 23 | -------------------------------------------------------------------------------- /src/jp/cooperate/index.md: -------------------------------------------------------------------------------- 1 | # 協力事項 2 | 3 | SoybeanAdmin をご支援いただき、誠にありがとうございます! 4 | コミュニティへのさらなる貢献と、企業および開発者のニーズに応えるため、様々な協力サービスを提供しております。 5 | 共に成長し、成功を築いていけることを楽しみにしています。 6 | 7 | ## 1、カスタム管理システム開発 8 | 9 | 企業や開発者の特定の業務ニーズに応じて、[`SoybeanAdmin`](https://github.com/soybeanjs/soybean-admin) をベースとしたカスタム管理システム開発を提供いたします。 10 | 経験豊富なチームが迅速に要件を理解し、高効率で柔軟かつ安全なカスタムソリューションを実現します。 11 | 12 | - **カスタム開発**:要件分析、UIデザイン、機能実装まで、一貫したサービスを提供し、プロジェクトの迅速な納品を保証します。 13 | - **機能拡張**:[`SoybeanAdmin`](https://github.com/soybeanjs/soybean-admin) をベースに、ご希望の機能モジュールを追加し、管理システムの利便性とユーザー体験を向上させます。 14 | 15 | ## 2、企業向けアウトソーシングサービス 16 | 17 | 管理システムの開発、統合、運用を中心とした企業向けアウトソーシングサービスを承ります。高品質とスピードを重視し、確実な技術支援を提供します。 18 | 19 | - **プロジェクト開発**:新規プロジェクトの開発はもちろん、既存システムの最適化や統合も対応可能です。 20 | - **システム統合・保守**:[`SoybeanAdmin`](https://github.com/soybeanjs/soybean-admin) を活用したシステム統合および長期的な運用保守サービスを提供し、安定的で安全なシステム環境を実現します。 21 | 22 | ## 3、お問い合わせ 23 | 24 | 協力のご相談やプロジェクトに関するお問い合わせは、以下の方法でご連絡ください。 25 | 26 | - **Email**: [soybeanjs@outlook.com](mailto:soybeanjs@outlook.com) 27 | - **GitHub Issues**: 欢迎通过 [GitHub Issues](https://github.com/soybeanjs/soybean-admin/issues/new) 联系我们,进行初步的合作洽谈。 28 | - **ビジネス連絡用**: honghuangdc 29 | 30 | SoybeanAdmin のさらなる発展と、より多くの分野での成功に向け、皆様との協力を楽しみにしております! 31 | -------------------------------------------------------------------------------- /src/jp/guide/cli/command.md: -------------------------------------------------------------------------------- 1 | # コマンド 2 | 3 | ## cleanup 4 | 5 | ディレクトリを削除(node_modules、dist など) 6 | 7 | ```bash 8 | sa cleanup 9 | ``` 10 | 11 | ## update-pkg 12 | 13 | package.json の依存関係を更新 14 | 15 | ```bash 16 | sa update-pkg 17 | ``` 18 | 19 | ## git-commit 20 | 21 | Conventional Commits 規約に準拠したコミットメッセージを生成 22 | 23 | ```bash 24 | sa git-commit 25 | ``` 26 | 27 | ## git-commit-verify 28 | 29 | Git のコミットメッセージを検証し、Conventional Commits 規約に準拠しているか確認 30 | 31 | ```bash 32 | sa git-commit-verify 33 | ``` 34 | 35 | ## changelog 36 | 37 | 変更履歴(changelog)を生成 38 | 39 | ```bash 40 | sa changelog 41 | ``` 42 | 43 | ## release 44 | 45 | リリース処理(バージョン更新、changelog 生成、コードのコミット) 46 | 47 | ```bash 48 | sa release 49 | ``` 50 | 51 | ## gen-route 52 | 53 | ルーティングを生成 54 | 55 | ```bash 56 | sa gen-route 57 | ``` 58 | -------------------------------------------------------------------------------- /src/jp/guide/cli/git-hooks.md: -------------------------------------------------------------------------------- 1 | # Git Hooks 2 | 3 | ## はじめに 4 | 5 | > JavaScript で書かれたコードのほとんどは、実行時に問題がないか判断することに慣れています。 6 | 7 | > 例えば、JavaScript でバックエンドの API を連携する際、通常は API が完成した後にデータを取得し、それをページに反映させるという流れになります。 8 | 9 | > シンプルなページであればこの方法でも問題ありませんが、少し複雑なプロジェクトになると、このような開発フローで書かれたコードは技術的負債の温床となり、後々のデバッグが非常に困難になります。 10 | 11 | TypeScript は高品質なコードを書くための強力なツールです。データ型を定義する過程でフロントエンドのデータモデルを確立し、一度モデルが決まれば、純粋関数を活用してデータ操作をシンプルに実装できます。そして、リアクティブなデータと組み合わせる際には、純粋関数をラップするだけで簡単に適用できます。TypeScript の型に慣れていない人は、開発スタイルの切り替えができていないことが主な原因です。この開発スタイルを試してみて、TypeScript の魅力を実感した上で `git-hooks` を削除するかどうかを決めても遅くはありません。 12 | 13 | `git-hooks` を使用してコミット前のチェックを行うことで、コードの品質を向上させ、プロジェクトの保守コストを削減できるだけでなく、他の人のコードを引き継ぐ際の負担も軽減できます。多くのメリットがある一方で、唯一のデメリットは短期間の学習と適応が必要なことですが(SoybeanAdmin プロジェクトの型カバレッジは 100% であり、TypeScript を習得するための最適な教材です)、一定期間試してみてから `git-hooks` を削除するかどうか判断してもよいでしょう。(ぜひ、コミュニティでのディスカッションにご参加ください) 14 | 15 | ## git-hooks を無効化する方法 16 | 17 | ::: details 方法1: 一時的にチェックを無効化する 18 | 初期段階では、可能な限り完全な型チェックを遵守することを推奨します。ただし、必要に応じて一時的にコミット前のチェックを無効化することで、一部のチェックをスキップできます。 19 | 20 | ```shell 21 | git add . 22 | 23 | git commit -m "commit message" # [!code --] 24 | git commit -m "commit message" --no-verify # [!code ++] 25 | 26 | git push 27 | ``` 28 | 29 | ::: 30 | 31 | ::: details 方法2: 永久にチェックを無効化する 32 | 33 | > [!CAUTION] 推奨しません 34 | > 1、`package.json` の `simple-git-hooks` 内のコマンドを削除する 35 | > 36 | > 2、`simple-git-hooks` コマンドを実行する 37 | -------------------------------------------------------------------------------- /src/jp/guide/cli/intro.md: -------------------------------------------------------------------------------- 1 | # コマンドライン 2 | 3 | ## 概述 4 | 5 | プロジェクトの `sa` コマンドラインツールは、以下のような一般的な機能を提供します。 6 | 7 | - `cleanup`: ディレクトリを削除(node_modules、dist など) 8 | - `update-pkg`: package.json の依存関係を更新 9 | - `git-commit`: Conventional Commits 規約に準拠したコミットメッセージを生成 10 | - `git-commit-verify`: Git のコミットメッセージを検証し、Conventional Commits 規約に準拠しているか確認 11 | - `changelog`: 変更履歴(changelog)を生成 12 | - `release`: リリース処理(バージョン更新、changelog 生成、コードのコミット) 13 | - `gen-route`: ルーティングを生成 14 | 15 | > `sa` コマンドは `packages/scripts` によって提供されます。 16 | -------------------------------------------------------------------------------- /src/jp/guide/icon/intro.md: -------------------------------------------------------------------------------- 1 | # システムアイコン 2 | 3 | ## iconify アイコンのレンダリング原理 4 | 5 | iconify の svg の json データを基に、unplugin-icons プラグインを使用して svg データを Vue コンポーネントに変換します。 6 | 7 | - [unplugin-icons](https://github.com/antfu/unplugin-icons) 8 | - [iconify](https://github.com/iconify/iconify) 9 | - [Journey with Icons Continues](https://antfu.me/posts/journey-with-icons-continues) 10 | 11 | ## ローカル svg アイコンのレンダリング原理 12 | 13 | `unplugin-icons` プラグインと `vite-plugin-svg-icons` プラグインを使用して、ローカル svg ファイルを Vue コンポーネントに変換します。 14 | 15 | > ローカル svg アイコンは src/assets/svg-icon ディレクトリに配置してください 16 | 17 | ## 関連設定 18 | 19 | **.env 設定ファイル** 20 | 21 | - VITE_ICON_PREFIX: iconify アイコンのプレフィックス 22 | - VITE_ICON_LOCAL_PREFIX: ローカル svg アイコンのプレフィックス ({VITE_ICON_PREFIX}-{local icon name} の形式を遵守) 23 | 24 | ## 注意事項 25 | 26 | > svg アイコンのレンダリング原理上、一度変換されると静的リソースになります。そのため、一旦 svg ファイルが Vue コンポーネントに変換されると、プロジェクトの一部となり、ソースファイルの変更を自動で検出・更新しません。svg ファイルを変更した場合は、プロジェクトを再起動する必要があります。 27 | -------------------------------------------------------------------------------- /src/jp/guide/icon/usage.md: -------------------------------------------------------------------------------- 1 | # アイコンチュートリアル 2 | 3 | ## 一、静的な使用方法:template 内で直接記述する 4 | 5 | - **iconify** 6 | 7 | - VSCode の IntelliSense プラグインをインストール: [Iconify IntelliSense](https://marketplace.visualstudio.com/items?itemName=antfu.iconify) 8 | 9 | - アイコンを検索する:ウェブサイト [https://icones.js.org/](https://icones.js.org/) または VSCode 拡張機能 - [Icônes](https://marketplace.visualstudio.com/items?itemName=afzalsayed96.icones) 10 | 11 | - 名前をコピーします(例: ‘mdi:emoticon’ または ‘mdi-emoticon’)。それに対応する Vue の template は以下のようになります。 12 | 13 | ```html 14 |
15 | 16 | 17 |
18 | ``` 19 | 20 | ::: tip ヒント 21 | 'icon-' はプレフィックスとして .env で VITE_ICON_PREFIX に設定できます。 22 | ::: 23 | 24 | - スタイルの設定:style 属性または class 属性を使用; color や font-size を設定して色やサイズを調整 25 | 26 | - **ローカル svg アイコン** 27 | 28 | - src/assets/svg-icon ディレクトリに svg を配置,取它的文件名,例: 'custom-icon.svg' 29 | 30 | - を使用する場合の Vue の template 記述 31 | 32 | ```html 33 | 34 | ``` 35 | 36 | ::: tip ヒント 37 | 'icon-local' はプレフィックスとして .env で VITE_ICON_LOCAL_PREFIX に設定できます。 38 | ::: 39 | 40 | ## 二、動的レンダリング:アイコン名に応じて適切なアイコンをレンダリング 41 | 42 | - **iconify** 43 | 44 | - アイコン名を決定,如:'mdi-emoticon' 45 | 46 | - 動的レンダリング 47 | 48 | ```html 49 | 50 | ``` 51 | 52 | - 複数アイコンを動的レンダリング 53 | 54 | ```html 55 | 56 | ``` 57 | 58 | - **ローカル svg アイコン** 59 | 60 | - アイコン名を決定,例如: 'custom-icon.svg' 61 | 62 | - 動的レンダリング 63 | 64 | ```html 65 | 66 | ``` 67 | 68 | ::: tip ヒント 69 | svg-icon はグローバルコンポーネントとして登録済みです。 70 | icon は iconify のアイコン名、local-icon はローカル svg アイコンのファイル名を指定します。 71 | ::: 72 | 73 | ## 三、render 関数を使用してレンダリング:NaiveUI のアイコン表示向け 74 | 75 | - アイコン名を決定,例:iconify: **'mdi-emoticon'**, またはローカル svg アイコン: 'custom-icon.svg' 76 | 77 | - useSvgIcon を使用 78 | 79 | ```typescript 80 | import { useSvgIcon } from '@/hooks/common/icon'; 81 | 82 | const { SvgIconVNode } = useSvgIcon(); 83 | 84 | SvgIconVNode({ icon: 'ant-design:close-outlined', fontSize: 18 }); // iconify 85 | 86 | SvgIconVNode({ localIcon: 'custom-icon' }); // ローカル svg アイコン 87 | ``` 88 | 89 | ## 四、オフラインロード:指定した iconify アイコンコレクションを追加 90 | 91 | - **使用手順** 92 | 93 | - 依存関係をインストール 94 | 95 | ```bash 96 | ## アイコンコンポーネントデータ 97 | pnpm add @iconify/vue 98 | 99 | ## オフラインアイコンデータ 100 | pnpm add @iconify/json 101 | ``` 102 | 103 | ::: tip ヒント 104 | プロジェクトにはすでに必要な依存関係が含まれているため、コンポーネント内で直接利用できます。 105 | ::: 106 | 107 | - オフラインアイコンコレクションデータを準備 108 | 109 | 例: Ant Design のアイコンライブラリをプロジェクトに追加する場合: 110 | 111 | ```typescript 112 | import AntDesign from '@iconify/json/json/ant-design.json'; 113 | ``` 114 | 115 | - `addCollection` メソッドでオフラインアイコンを追加 116 | 117 | ```typescript 118 | import { addCollection } from '@iconify/vue'; 119 | ``` 120 | 121 | - **コードサンプル** 122 | 123 | ```vue 124 | 130 | 131 | 134 | ``` 135 | -------------------------------------------------------------------------------- /src/jp/guide/request/backend.md: -------------------------------------------------------------------------------- 1 | # バックエンドとの連携 2 | 3 | ## バックエンドのレスポンスデータ構造の確認 4 | 5 | デフォルトは以下の通りです: 6 | 7 | `App.Service.Response`: 8 | 9 | ```ts 10 | type Response = { 11 | /** ビジネスステータスコード */ 12 | code: string; 13 | /** レスポンスメッセージ */ 14 | msg: string; 15 | /** レスポンスデータ */ 16 | data: T; 17 | }; 18 | ``` 19 | 20 | > ご自身のバックエンドから返されるデータの型に応じて変更してください。 21 | 22 | ## バックエンドリクエスト成功時の code の設定 23 | 24 | `.env` の設定 `VITE_SERVICE_SUCCESS_CODE` を変更します。 25 | 26 | > 環境ファイルから読み込まれる設定は文字列型です。バックエンドから返される code が数値型の場合、比較時に型を一致させてから比較する必要があります。 27 | 28 | ## その他のバックエンドリクエストに関連する code の設定 29 | 30 | リクエストの紹介にある[設定項目](./intro.md#请求相关配置介绍)を参照してください 31 | -------------------------------------------------------------------------------- /src/jp/guide/request/intro.md: -------------------------------------------------------------------------------- 1 | # リクエスト 2 | 3 | ## 複数のリクエスト環境 4 | 5 | 開発プロジェクトでは、複数のリクエスト環境アドレスを使用することがよくあります。例えば、ユーザー開発環境のバックエンドアドレス、テスト環境のバックエンドアドレス、予備生産環境のバックエンドアドレス、そして本番環境のバックエンドアドレスなどです。 6 | 7 | 環境ファイルで複数のリクエストアドレスを設定し、リクエスト関数内で環境変数に基づいてどのリクエストアドレスを使用するかを判断します。 8 | 9 | 現在、プロジェクトの環境ファイルには以下があります。 10 | 11 | `.env.prod`, `.env.test` 12 | 13 | ## リクエスト関連の設定紹介 14 | 15 | `.env` ファイルの設定項目 16 | 17 | - `VITE_SERVICE_SUCCESS_CODE`: バックエンドリクエストが成功した際の code 18 | - `VITE_SERVICE_LOGOUT_CODES`: バックエンドリクエストが失敗し、ユーザーがログアウトする必要がある code。複数の code は `, `で区切ります 19 | - `VITE_SERVICE_MODAL_LOGOUT_CODES`: バックエンドリクエストが失敗し、ポップアップでユーザーにログアウトを促す必要がある code。複数の code は `, `で区切ります 20 | - `VITE_SERVICE_EXPIRED_TOKEN_CODES`: バックエンドリクエストが失敗し、トークンをリフレッシュする必要がある code。複数の code は , で区切ります 21 | 22 | `.env.test` または `.env.prod` ファイルの設定項目 23 | 24 | - `VITE_SERVICE_BASE_URL`: リクエストのベースURL 25 | - `VITE_OTHER_SERVICE_BASE_URL`: その他のリクエストのベースURL 26 | 27 | ### リクエスト関数の紹介 28 | 29 | 1. **リクエスト関数:createRequest と createFlatRequest** 30 | 31 | `createRequest`: 戻り値のリクエストインスタンスは、Axiosのレスポンスデータを直接返します(変換可能) 32 | 33 | `createFlatRequest`: 戻り値のリクエストインスタンスは、レスポンスデータとエラーメッセージを1つの平坦なオブジェクトとしてラップし、統一フォーマットで結果を返します。 34 | 35 | 2. **createRequest/createFlatRequest 参数** 36 | 37 | `axiosConfig`: axios の設定、baseUrl を渡し、リクエストのタイムアウトやリクエストヘッダーなどの設定を定義します。 38 | 39 | `options`: 引数のバリデーションなどのロジック(下記の `RequestOption` を参照) 40 | 41 | ```ts 42 | interface RequestOption { 43 | /** 44 | * リクエスト送信前に実行され、リクエスト設定を変更するために使用されます。例:リクエストヘッダーにトークンを追加する 45 | */ 46 | onRequest: (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig | Promise; 47 | /** 48 | * バックエンドのレスポンスが成功かどうかを判断します。バックエンドが返した code と照らし合わせて判断します 49 | */ 50 | isBackendSuccess: (response: AxiosResponse) => boolean; 51 | /** 52 | * バックエンドリクエストがビジネス上失敗した場合に呼び出される非同期関数。例:トークンの期限切れ処理 53 | */ 54 | onBackendFail: ( 55 | response: AxiosResponse, 56 | instance: AxiosInstance 57 | ) => Promise | Promise; 58 | /** 59 | * responseType が json の場合、バックエンドのレスポンスデータを変換します 60 | */ 61 | transformBackendResponse(response: AxiosResponse): any | Promise; 62 | /** 63 | * リクエストが失敗したときに呼び出される関数(リクエストの失敗やバックエンドビジネスの失敗リクエストを含む)。例:エラーメッセージの処理 64 | */ 65 | onError: (error: AxiosError) => void | Promise; 66 | } 67 | ``` 68 | -------------------------------------------------------------------------------- /src/jp/guide/request/proxy.md: -------------------------------------------------------------------------------- 1 | # プロキシ 2 | 3 | ## 概要 4 | 5 | プロジェクト内で、createServiceConfig 関数を使用してサービスの基本パスとマッチングプロキシの文字列を作成します。 6 | 7 | ::: tip コード位置 8 | @/utils/service.ts 9 | ::: 10 | 11 | 次に、createViteProxy 関数内で、上記で取得した設定に基づいてプロキシを作成します。 12 | 13 | ## 有効化/無効化 14 | 15 | `env` ファイルの `VITE_HTTP_PROXY` を使ってプロキシを有効または無効にできます。 16 | 17 | ::: tip コード位置 18 | ~.env 19 | ::: 20 | 21 | `@/service/request/index.ts` `では、getServiceBaseURL` の第二引数にコード実行環境と `VITE_HTTP_PROXY` を基にした `isHttpProxy` を渡して、URLがプロキシを通すべきかどうかを判断します。ここで、異なるパラメータを渡して、必要なリクエストURLを取得できます。 22 | 23 | ``` 24 | const isHttpProxy = import.meta.env.DEV && import.meta.env.VITE_HTTP_PROXY === 'Y'; 25 | const { baseURL } = getServiceBaseURL(import.meta.env, isHttpProxy); 26 | const { otherBaseURL } = getServiceBaseURL(import.meta.env, false); 27 | ``` 28 | 29 | ## 原理 30 | 31 | SoybeanAdmin は、プロキシ設定を簡素化するために、マッチング文字列として `/proxy-default/` (その他のリクエストは `proxy-{key}`)を設定しています。これにより、プロキシ設定時にはリクエストのURL内の `/proxy-default/` を実際のリクエストURLに置き換えるだけで、プロキシ設定が実現できます。 32 | 33 | ```ts 34 | { 35 | '/proxy-default': { 36 | target: 'https://default.com', 37 | changeOrigin: true, 38 | rewrite: (path) => path.replace(/^\/proxy-default/, ''), 39 | }, 40 | '/proxy-demo': { 41 | target: 'https://demo.com', 42 | changeOrigin: true, 43 | rewrite: (path) => path.replace(/^\/proxy-demo/, ''), 44 | } 45 | } 46 | ``` 47 | 48 | ### 注意 49 | 50 | ここで紹介する2つの混乱しやすい設定について説明します: 51 | 52 | 1. リクエストのパスが https://example.com/api/user の場合、多くの場合、以下のようにプロキシを設定します。 53 | 54 | ```ts 55 | 56 | { 57 | '/api': { 58 | target: 'https://example.com', 59 | changeOrigin: true, 60 | } 61 | } 62 | 63 | ``` 64 | 65 | > この場合、`/api` はマッチング文字列であり、リクエストのパスでもあります。したがって、`rewrite`設定は不要です。リクエストパスとマッチング文字列が同じだからです。 66 | 67 | 2. リクエストのパスが `https://example.com/user` で、プロキシ設定時にマッチング文字列が `/api` の場合、以下のように設定します。 68 | 69 | ```ts 70 | 71 | { 72 | '/api': { 73 | target: 'https://example.com', 74 | changeOrigin: true, 75 | rewrite: (path) => path.replace(/^\/api/, ''), 76 | } 77 | } 78 | 79 | ``` 80 | 81 | > この場合、`/api` はマッチング文字列として使用され、`user` がリクエストのパスです。したがって、`rewrite` 設定が必要です。マッチング文字列を取り除くためです。 82 | 83 | SoybeanAdmin では、複数のサービスのプロキシをサポートするため、また、複数のサービスで同じ /api パスを含む可能性を避けるため、rewrite 設定を含む第二の方法を使用しています。そのため、SoybeanAdmin はマッチング文字列とリクエストパスを分けるために、/proxy-\* のような形式で設定を作成し、衝突を回避しています。 84 | -------------------------------------------------------------------------------- /src/jp/guide/router/cache.md: -------------------------------------------------------------------------------- 1 | # ルートキャッシュ 2 | 3 | ## 原理 4 | 5 | ルートキャッシュは、`vue-router` の `keep-alive` コンポーネントを使用して実現されています。`keep-alive` コンポーネントは、コンポーネントの状態をキャッシュし、コンポーネントが再度アクセスされたときに、新しいコンポーネントを再作成するのではなく、キャッシュからコンポーネントを直接取得します。 6 | `keep-alive` コンポーネントは、コンポーネントの `name` プロパティをキャッシュのキーとして使用するため、プロジェクト内のページコンポーネントはすべて `@elegant-router/vue` プラグインを介して `name` プロパティが自動的に注入されているので、ルートデータの `meta` プロパティにある `keepAlive` フィールドを設定するだけで済みます。 7 | `vue-router` の多階層ルートキャッシュには問題があるため、プロジェクト内のルートデータはすべて二階層ルートに変換され、各ルートが正常にキャッシュされるように保証されています。 8 | 9 | ## 使い方 10 | 11 | ルートデータの `meta` プロパティにある `keepAlive` フィールドを設定することで、ルートがキャッシュされるかどうかを制御できます。 12 | 13 | ```ts 14 | { 15 | name: 'about', 16 | path: '/about', 17 | component: 'layout.base$view.about', 18 | meta: { 19 | title: 'about', 20 | keepAlive: true 21 | } 22 | } 23 | ``` 24 | -------------------------------------------------------------------------------- /src/jp/guide/router/component.md: -------------------------------------------------------------------------------- 1 | # ルートコンポーネント 2 | 3 | ## レイアウトコンポーネント 4 | 5 | - **layout.base**: 共通部分を持つレイアウト、例えばグローバルヘッダー、サイドバー、フッターなど 6 | 7 | - **layout.blank**: 空白レイアウト 8 | 9 | ## ページコンポーネント 10 | 11 | - **view.[RouteKey]**: ページコンポーネント 12 | > 例如:`view.home`, `view.multi-menu_first_child` 13 | 14 | ## レイアウトとページの混合コンポーネント 15 | 16 | - **layout.base$view.[RouteKey]**: レイアウトとページの混合コンポーネント 17 | > 例如:`layout.base$view.home`, `layout.base$view.multi-menu_first_child` 18 | 19 | ::: tip ヒント 20 | このタイプのコンポーネントは単一レベルルートを表します 21 | ::: 22 | -------------------------------------------------------------------------------- /src/jp/guide/router/create.md: -------------------------------------------------------------------------------- 1 | # ルートの作成 2 | 3 | ## コマンドで作成 4 | 5 | `pnpm gen-route` コマンドを実行すると、ルートファイルを素早く作成できます。 6 | 7 | **ルート名の命名規則** 8 | 9 | - **第1階層のルート**: `demo`, `demo-page`, `route1` 10 | > 小文字+ハイフン `-` の形式で命名 11 | - **第2階層のルート**: `demo2_child`, `demo2-page_child`, `route2_child` 12 | > ルートの階層をアンダースコア `_` で区切り、左右は第1階層の命名規則に従う 13 | - **第3階層以上のルート**: `demo3_child_child`, `demo3-page_child_child_child` 14 | 15 | ## 手動で作成 16 | 17 | **手動でルートファイルを作成する場合、以下のルールに従う必要があります:** 18 | 各ルート階層のフォルダ名はルート名とし、そのフォルダ内の `index.vue` または `[id].vue` をルートコンポーネントとする。 19 | -------------------------------------------------------------------------------- /src/jp/guide/router/dynamic.md: -------------------------------------------------------------------------------- 1 | # ルート権限 2 | 3 | ## ガイド 4 | 5 | ### 固定ルート(権限不要でアクセス可能なルート) 6 | 7 | 静的ルートモードでは、ルートの権限は `meta.constant` で制御されます。`constant` が `true` のルートはログインなしでアクセスできます。 8 |
9 | 一方、動的ルートモードでは、ログインなしでアクセス可能なルートは `fetchGetConstantRoutes` API で返す必要があります。つまり、`fetchGetUserRoutes` で `constant` を true に設定しても無効であり、ログインが必要になります。 10 | 11 | ### 権限ルート 12 | 13 | 静的ルートモードでは、デフォルトで全てのルートにログインが必要です。特定の権限を設定する場合は、`meta.roles` フィールドを追加できます。このフィールドの型は `string[]` で、`UserInfo` に設定されます。指定されたロールと一致する場合のみアクセスが許可され、それ以外は許可されません。マッチングは前置ルートガードの段階で行われます。 14 |
15 | 動的ルートモードでは、引き続き `meta.roles` を使用できますが、通常はバックエンドがロールに基づいてルートテーブルを制御し、権限のないルートを返さない方法が一般的です。 16 | 17 | ## 動的ルート 18 | 19 | ルートの取得元を変更できます。静的ルートのルートテーブルは `./src/router/elegant/routes.ts` にあります。動的ルートのルートテーブルは `fetchGetConstantRoutes` および `fetchGetUserRoutes` API から取得されます。 20 | 21 | > [!WARNING] 注意 22 | > 接口返回的路由表的类型必须与前端静态的路由表类型一致,在尝试修改前建议先熟悉本项目的特色路由插件与路由表结构 23 | 24 | ### 有効化/無効化 25 | 26 | `env` ファイル内の `VITE_AUTH_ROUTE_MODE` 変数を設定することで、動的ルートモードを有効化/無効化できます。 27 | 28 | ::: tip コードの場所 29 | .env 30 | ::: 31 | 32 | ```dotenv:line-numbers=14 33 | # 認証ルートモード: static | dynamic 34 | VITE_AUTH_ROUTE_MODE=dynamic 35 | ``` 36 | -------------------------------------------------------------------------------- /src/jp/guide/router/guard.md: -------------------------------------------------------------------------------- 1 | # ルートガード 2 | 3 | ## ルートガードのフローチャート 4 | 5 | ![](../../../assets/router-guard-flow.png) 6 | 7 | [高解像度PDF](/router-guard-flow.pdf) 8 | -------------------------------------------------------------------------------- /src/jp/guide/router/intro.md: -------------------------------------------------------------------------------- 1 | # システムルート 2 | 3 | 本システムのルートはプラグイン [Elegant Router](https://github.com/soybeanjs/elegant-router) に基づいています。詳細な使用方法はプラグインドキュメントをご確認ください。 4 | 5 | ::: danger 警告 6 | `` タグを使用してページの移行アニメーションを対応しているため、`.vue` ファイルの `template` 内には根要素が1つだけ必要です。注釈や純文字は含めてはいけません。必ず1つの根タグのみにしてください。 7 | 関連文書: [Transition | Vue.js (vuejs.org)](https://cn.vuejs.org/guide/built-ins/transition.html#the-transition-component) 8 | ::: 9 | 10 | ## 自動生成 11 | 12 | プロジェクトを起動すると、プラグインは `src/router/elegant` ディレクトリを自動生成します。このディレクトリ下のファイルは、自動生成されたルートの読み込み、ルート定義、ルート変換を含むファイルです。 13 | 14 | > [!IMPORTANT] 15 | > ルートはファイルの副産物のため、ルートを削除する場合はファイルを削除してください。
ルートがファイルと共に消えます。
ルートの変更が可能なのは `component` と `meta` の情報のみです。自動生成エンジンはこれらの属性に影響を与えません。 16 | 17 | ## 設定プロパティ 18 | 19 | ### 1. type RouteKey 20 | 21 | **解説:** 22 | 23 | 連合型 `RouteKey` はすべてのルートキーを売っています。これによりルートを統一的に管理できます。この型は [Elegant Router](https://github.com/soybeanjs/elegant-router) が `views` 配下のファイルを元に自動生成します。 24 | 25 | ::: tip コード位置 26 | src/typings/elegant-router.d.ts 27 | ::: 28 | 29 | ### 2. type RoutePath 30 | 31 | **解説:** 32 | 33 | ルートのパス (`path`)の型。 `RouteKey` と一一寸で対応しています。 34 | 35 | ### 3. type RouteMeta 36 | 37 | ```typescript 38 | // ルート元情報インタフェース 39 | interface RouteMeta { 40 | /** 41 | * ルートタイトル 42 | * 43 | * 文書タイトルとして使用可能 44 | */ 45 | title: string; 46 | /** 47 | * ルートの国際化キー 48 | * 49 | * i18n の値が設定された場合、title は無視されます 50 | */ 51 | i18nKey?: App.I18n.I18nKey; 52 | /** 53 | * ルートのロールリスト 54 | */ 55 | roles?: string[]; 56 | /** 57 | * このルートをキャッシュす 58 | */ 59 | keepAlive?: boolean; 60 | /** 61 | * 定数ルートかどうか 62 | * 63 | * ログイン不要であり、かつこのルートはフロントエンドで定義される 64 | */ 65 | constant?: boolean; 66 | /** 67 | * Iconify アイコン 68 | * 69 | * メニューまたはパンくずリストで使用可能 70 | */ 71 | icon?: string; 72 | /** 73 | * ローカルアイコン 74 | * 75 | * "src/assets/svg-icon" ディレクトリに存在し、設定された場合は icon プロパティが無視される 76 | */ 77 | localIcon?: string; 78 | /** ルートのソート順 */ 79 | order?: number; 80 | /** ルートの外部リンク */ 81 | href?: string; 82 | /** メニューにこのルートを非表示にするかどうか */ 83 | hideInMenu?: boolean; 84 | /** 85 | * このルートに入った際にアクティブになるメニューキー 86 | * 87 | * このルートがメニューに存在しない場合 88 | * 89 | * @example 90 | * 例えばルートが "user_detail" の場合、"user_list" に設定すると「ユーザーリスト」メニュー項目がアクティブになる 91 | */ 92 | activeMenu?: import('@elegant-router/types').RouteKey; 93 | /** デフォルトでは同じパスのルートはタブを共有するが、true に設定すると複数のタブを使用 */ 94 | multiTab?: boolean; 95 | /** 設定すると、ルートはタブに固定表示され、その値は固定タブの順序を示す(ホームは特別で、自動的に固定される) */ 96 | fixedIndexInTab?: number; 97 | /** ルートのクエリパラメータ。設定すると、メニューからこのルートに入る際に自動で query パラメータを付与 */ 98 | query?: { key: string; value: string }[] | null; 99 | } 100 | ``` 101 | 102 | ::: tip ヒント 103 | icon 图标值从这里获取:[https://icones.js.org/](https://icones.js.org/) 104 | ::: 105 | 106 | ## 注意 107 | 108 | views フォルダ内にルートページを作成し、他の場所で呼び出すがメニューには表示しない場合、meta の `hideInMenu: true` を設定する必要があります。 109 | 110 | ```typescript 111 | { 112 | name: '403', 113 | path: '/403', 114 | component: 'layout.blank$view.403', 115 | meta: { 116 | title: '403', 117 | i18nKey: 'route.403', 118 | hideInMenu: true 119 | } 120 | } 121 | ``` 122 | -------------------------------------------------------------------------------- /src/jp/guide/router/push.md: -------------------------------------------------------------------------------- 1 | # ルート遷移 2 | 3 | プロジェクト内では、通常の `router.push` などの方法を使用してルート遷移を行うことができますが、プロジェクト内で提供されている `useRouterPush` を使用して遷移することもできます(推奨)。このセクションでは、主に `useRouterPush` を紹介します。 4 | 5 | ## 介绍 6 | 7 | このhookは、`router.push` を二重にラップしています。主な目的は `router.push` の代わりに使用することで、遷移をより簡便に行うことができる点です。`useRouterPush` はオブジェクトを返し、以下のプロパティとメソッドが含まれています: 8 | 9 | - routerPush: Vue Router の push メソッド。 10 | - routerBack: Vue Router の back メソッド。 11 | - routerPushByKey: ルートキーに基づいて遷移するメソッド。 12 | - toLogin: ログインページに遷移するメソッド。 13 | - toggleLoginModule: ログインモジュールを切り替えるメソッド。 14 | - redirectFromLogin: ログインページからリダイレクトするメソッド。 15 | 16 | ::: warning 注意 17 | `setup` 外で使用する場合は、`useRouterPush` に `false` を渡す必要があります。 18 | ::: 19 | 20 | ## 詳細説明 21 | 22 | `routerPush` と `routerBack` は元々のプロパティなので、ここでは詳しく説明しません。主に以下のメソッドを紹介します。 23 | 24 | ### routerPushByKey 25 | 26 | ここでの `key` はルートの `name` プロパティを指します。例えば、あるルートの設定が以下のようになっている場合: 27 | 28 | ```json 29 | { 30 | "name": "soybean", 31 | "path": "/soybean-page", 32 | "component": "layout.base$view.soybean-page" 33 | } 34 | ``` 35 | 36 | このルートに遷移するコードは以下のようになります: 37 | 38 | ```ts 39 | import { useRouterPush } from '@/hooks/common/router'; 40 | 41 | const { routerPushByKey } = useRouterPush(); 42 | 43 | routerPushByKey('soybean'); 44 | ``` 45 | 46 | このメソッドは、オプションで `query` や `params` を渡すことができます。 47 | 48 | ### toLogin 49 | 50 | 文字通り、ログインページに素早く遷移するメソッドです。遷移前にログイン情報を削除することを忘れないでください。さもないと、ルートガードでホームページにリダイレクトされてしまいます。 51 | 52 | ### toggleLoginModule 53 | 54 | このメソッドの引数の型は次のようになります: 55 | 56 | ```ts 57 | /** 58 | * The login module 59 | * 60 | * - pwd-login: パスワードログイン 61 | * - code-login: 電話番号コードログイン 62 | * - register: 登録 63 | * - reset-pwd: パスワードリセット 64 | * - bind-wechat: WeChat バインド 65 | */ 66 | type LoginModule = 'pwd-login' | 'code-login' | 'register' | 'reset-pwd' | 'bind-wechat'; 67 | ``` 68 | 69 | このメソッドは、渡された `LoginModule` に基づいてログインページにマウントされるログイン機能モジュールを変更します。必要に応じてモジュールを削除または拡張できますが、型が正しいことを確認すれば問題ありません。 70 | 71 | ### redirectFromLogin 72 | 73 | ログイン成功後に使用されます。手動でホームページに遷移するよりも直感的です。 74 | このメソッドは、ログインページの `redirect` クエリパラメータを使用してどのルートにリダイレクトするかを決定します。もし `redirect` パラメータがない場合は、デフォルトでホームページに遷移します。 75 | 76 | ## 使用方法 77 | 78 | ```vue 79 | 80 | 85 | 86 | 91 | ``` 92 | 93 | ```ts 94 | 95 | import { useRouterPush } from '@/hooks/common/router'; 96 | 97 | // 注意して false を渡す 98 | const { routerPushByKey } = useRouterPush(false); 99 | 100 | function backToRoot() { 101 | routerPushByKey('root') 102 | } 103 | ``` 104 | -------------------------------------------------------------------------------- /src/jp/guide/sync.md: -------------------------------------------------------------------------------- 1 | # コードの同期 2 | 3 | 1. 自分のリポジトリに `soybean-admin` の Git リポジトリを追加する 4 | 5 | ```bash 6 | git remote add otherOrigin https://github.com/soybeanjs/soybean-admin.git 7 | ``` 8 | 9 | 2. コードを取得する 10 | 11 | ```bash 12 | git fetch otherOrigin 13 | ``` 14 | 15 | 3. `cherry-pick` を使用して、更新が必要な Git コミットを選択する 16 | 17 | ```bash 18 | git cherry-pick [commit id] 19 | ``` 20 | 21 | 4. コードにコンフリクトが発生した場合は、まずコンフリクトを解決し、以下のコマンドを実行した後、`vim` で保存する 22 | 23 | ```bash 24 | git cherry-pick --continue 25 | ``` 26 | 27 | > `vim`の保存方法: `esc`,`:`, `wq`, `enter` 28 | -------------------------------------------------------------------------------- /src/jp/guide/theme/config.md: -------------------------------------------------------------------------------- 1 | # テーマ設定 2 | 3 | ## 型定義 4 | 5 | App.Theme.ThemeSetting を参照 6 | 7 | ::: tip コードの場所 8 | src/typings/app.d.ts 9 | ::: 10 | 11 | ## 初期設定 12 | 13 | ```ts 14 | export const themeSettings: App.Theme.ThemeSetting = { 15 | // デフォルト設定 16 | }; 17 | ``` 18 | 19 | ::: tip コードの場所 20 | src/theme/settings.ts 21 | ::: 22 | 23 | ## 設定の上書き更新 24 | 25 | 新しいバージョンをリリースする際、設定の上書き更新を利用してテーマ設定を更新できます。 26 | 27 | ```ts 28 | export const overrideThemeSettings: Partial = { 29 | // 上書き設定 30 | }; 31 | ``` 32 | 33 | ::: tip コードの場所 34 | src/theme/settings.ts 35 | ::: 36 | 37 | 環境説明 38 | 39 | - プロジェクトが 開発モード の場合、テーマ設定はキャッシュされません。`src/theme/settings.ts` 内の `themeSettings` を更新することで、テーマ設定を変更できます。 40 | 41 | > 開発段階ではテーマ設定の変更をリアルタイムで確認できるようにするため、キャッシュしません。 42 | 43 | - プロジェクトが `本番モード` の場合、テーマ設定は localStorage にキャッシュされます。 44 | > 新しいバージョンをリリースする際は、`src/theme/settings.ts`内の `overrideThemeSettings` を更新することで、テーマ設定を上書きできます。 45 | -------------------------------------------------------------------------------- /src/jp/guide/theme/intro.md: -------------------------------------------------------------------------------- 1 | # システムテーマ 2 | 3 | システムテーマの実装は、コンポーネントライブラリのテーマ設定 と UnoCSS のテーマ設定 の2つの部分に分かれています。 4 | この2つのテーマ設定を統一するために、共通のテーマ設定を管理し、それを使用してコンポーネントライブラリと UnoCSS のテーマを制御します。 5 | 6 | ## 原理 7 | 8 | - 各種テーマカラーやレイアウトのパラメータ設定など、テーマ設定用の変数を定義する 9 | - これらの設定を基に、コンポーネントライブラリ用のテーマ変数を生成する 10 | - これらの設定を基に、テーマトークンを生成し、それに対応する CSS 変数を作成し、その CSS 変数を UnoCSS に渡す 11 | -------------------------------------------------------------------------------- /src/jp/guide/theme/loading.md: -------------------------------------------------------------------------------- 1 | # システムロード 2 | 3 | ![](../../../assets/loading01.png) 4 | 5 | ## 样式 6 | 7 | - システム初期化時のロードスタイルはHTMLコードで実装されています 8 | 9 | ::: tip 组件位置 10 | src/plugins/loading.ts 11 | ::: 12 | 13 | - システムのロゴは SystemLogo コンポーネントで実現されています。 14 | 15 | [系统Logo](./logo.md) 16 | 17 | ## 描画原理 18 | 19 | setupLoading 関数を作成し、その主な機能はページ読み込み時のアニメーション効果を設定することです。このロードアニメーションには、システムロゴ、回転するドットアニメーション、そしてタイトル文字が含まれます。すべての要素の色は、ローカルストレージから取得したテーマカラー themeColor を基に動的に生成されます。さらに、DOM内でIDが app の要素を探し、見つかった場合はその内部HTMLを先程構築したロードアニメーションのHTML構造に置き換えます。 20 | 21 | ```ts 22 | export function setupLoading() { 23 | const themeColor = localStg.get('themeColor') || '#DB5A6B'; 24 | 25 | const { r, g, b } = getRgbOfColor(themeColor); 26 | 27 | const primaryColor = `--primary-color: ${r} ${g} ${b}`; 28 | 29 | const loadingClasses = [ 30 | 'left-0 top-0', 31 | 'left-0 bottom-0 animate-delay-500', 32 | 'right-0 top-0 animate-delay-1000', 33 | 'right-0 bottom-0 animate-delay-1500' 34 | ]; 35 | 36 | const logoWithClass = systemLogo.replace(' { 40 | return `
`; 41 | }) 42 | .join('\n'); 43 | 44 | const loading = ` 45 |
46 | ${logoWithClass} 47 |
48 |
49 | ${dot} 50 |
51 |
52 |

${$t('system.title')}

53 |
`; 54 | 55 | const app = document.getElementById('app'); 56 | 57 | if (app) { 58 | app.innerHTML = loading; 59 | } 60 | } 61 | ``` 62 | 63 | ::: tip コードの位置 64 | src/plugins/loading.ts 65 | ::: 66 | 67 | 最後に setupLoading 関数を main.ts に登録します。 68 | 69 | ```typescript 70 | async function setupApp() { 71 | setupLoading(); 72 | app.mount('#app'); 73 | } 74 | ``` 75 | -------------------------------------------------------------------------------- /src/jp/guide/theme/logo.md: -------------------------------------------------------------------------------- 1 | # 概要 2 | 3 | システムロゴは `SystemLogo` コンポーネントによって実装されており、これは `SFC` コンポーネントです。`props` を使用してスタイルを設定できます。 4 | 5 | ```vue 6 | 9 | 10 | 13 | 14 | 15 | ``` 16 | 17 | ::: tip コードの位置 18 | src/components/common/system-logo.vue 19 | ::: 20 | 21 | > 詳しい実装原理については [本地Icon](/zh/guide/icon/intro) を参照してください。 22 | -------------------------------------------------------------------------------- /src/jp/guide/theme/tokens.md: -------------------------------------------------------------------------------- 1 | # テーマ tokens 2 | 3 | ## 型定義 4 | 5 | ```ts 6 | type ThemeToken = { 7 | colors: ThemeTokenColor; 8 | boxShadow: { 9 | header: string; 10 | sider: string; 11 | tab: string; 12 | }; 13 | }; 14 | ``` 15 | 16 | ::: tip コードの場所 17 | src/typings/app.d.ts 18 | ::: 19 | 20 | ## トークン(tokens)に基づく CSS 変数 21 | 22 | 初期化時に HTML にいくつかの CSS 変数が生成されます。これらの CSS 変数はテーマトークン(tokens)に基づいて作成されます。 23 | 24 | ```ts 25 | /** Theme vars */ 26 | export const themeVars: App.Theme.ThemeToken = { 27 | colors: { 28 | ...colorPaletteVars, 29 | nprogress: 'rgb(var(--nprogress-color))', 30 | container: 'rgb(var(--container-bg-color))', 31 | layout: 'rgb(var(--layout-bg-color))', 32 | inverted: 'rgb(var(--inverted-bg-color))', 33 | base_text: 'rgb(var(--base-text-color))' 34 | }, 35 | boxShadow: { 36 | header: 'var(--header-box-shadow)', 37 | sider: 'var(--sider-box-shadow)', 38 | tab: 'var(--tab-box-shadow)' 39 | } 40 | }; 41 | ``` 42 | 43 | ::: tip コードの場所 44 | src/theme/vars.ts 45 | ::: 46 | 47 | ## トークン(tokens)の初期化 48 | 49 | ```ts 50 | /** 51 | * Create theme token 52 | * 53 | * @param colors Theme colors 54 | */ 55 | export function createThemeToken(colors: App.Theme.ThemeColor) { 56 | const paletteColors = createThemePaletteColors(colors); 57 | 58 | const themeTokens: App.Theme.ThemeToken = { 59 | colors: { 60 | ...paletteColors, 61 | nprogress: paletteColors.primary, 62 | container: 'rgb(255, 255, 255)', 63 | layout: 'rgb(247, 250, 252)', 64 | inverted: 'rgb(0, 20, 40)', 65 | base_text: 'rgb(31, 31, 31)' 66 | }, 67 | boxShadow: { 68 | header: '0 1px 2px rgb(0, 21, 41, 0.08)', 69 | sider: '2px 0 8px 0 rgb(29, 35, 41, 0.05)', 70 | tab: '0 1px 2px rgb(0, 21, 41, 0.08)' 71 | } 72 | }; 73 | 74 | const darkThemeTokens: App.Theme.ThemeToken = { 75 | colors: { 76 | ...themeTokens.colors, 77 | container: 'rgb(28, 28, 28)', 78 | layout: 'rgb(18, 18, 18)', 79 | base_text: 'rgb(224, 224, 224)' 80 | }, 81 | boxShadow: { 82 | ...themeTokens.boxShadow 83 | } 84 | }; 85 | 86 | return { 87 | themeTokens, 88 | darkThemeTokens 89 | }; 90 | } 91 | ``` 92 | 93 | ::: tip コードの場所 94 | src/store/modules/theme/shared.ts 95 | ::: 96 | -------------------------------------------------------------------------------- /src/jp/guide/theme/ui.md: -------------------------------------------------------------------------------- 1 | # コンポーネントライブラリのテーマ 2 | 3 | ## NaiveUI のテーマ設定 4 | 5 | **テーマカラーに基づいてコンポーネントライブラリのテーマ変数を生成する** 6 | 7 | ```ts 8 | /** 9 | * Get naive theme 10 | * 11 | * @param colors Theme colors 12 | */ 13 | function getNaiveTheme(colors: App.Theme.ThemeColor) { 14 | const { primary: colorLoading } = colors; 15 | 16 | const theme: GlobalThemeOverrides = { 17 | common: { 18 | ...getNaiveThemeColors(colors) 19 | }, 20 | LoadingBar: { 21 | colorLoading 22 | } 23 | }; 24 | 25 | return theme; 26 | } 27 | 28 | /** Naive theme */ 29 | const naiveTheme = computed(() => getNaiveTheme(themeColors.value)); 30 | ``` 31 | 32 | ::: tip 代码位置 33 | src/store/modules/theme/shared.ts 34 | 35 | src/store/modules/theme/index.ts 36 | ::: 37 | 38 | **テーマ変数を適用する** 39 | 40 | ```vue 41 | 54 | ``` 55 | 56 | ::: tip 代码位置 57 | src/App.vue 58 | ::: 59 | 60 | ## AntDesignVue のテーマ設定 61 | 62 | **テーマカラーに基づいてコンポーネントライブラリのテーマ変数を生成する** 63 | 64 | ```ts 65 | /** 66 | * Get antd theme 67 | * 68 | * @param colors Theme colors 69 | * @param darkMode Is dark mode 70 | */ 71 | function getAntdTheme(colors: App.Theme.ThemeColor, darkMode: boolean) { 72 | const { defaultAlgorithm, darkAlgorithm } = antdTheme; 73 | 74 | const { primary, info, success, warning, error } = colors; 75 | 76 | const theme: ConfigProviderProps['theme'] = { 77 | token: { 78 | colorPrimary: primary, 79 | colorInfo: info, 80 | colorSuccess: success, 81 | colorWarning: warning, 82 | colorError: error 83 | }, 84 | algorithm: [darkMode ? darkAlgorithm : defaultAlgorithm], 85 | components: { 86 | Menu: { 87 | colorSubItemBg: 'transparent' 88 | } 89 | } 90 | }; 91 | 92 | return theme; 93 | } 94 | 95 | /** Antd theme */ 96 | const antdTheme = computed(() => getAntdTheme(themeColors.value, darkMode.value)); 97 | ``` 98 | 99 | ::: tip 代码位置 100 | src/store/modules/theme/shared.ts 101 | 102 | src/store/modules/theme/index.ts 103 | ::: 104 | 105 | **テーマ変数を適用する** 106 | 107 | ```vue 108 | 115 | ``` 116 | -------------------------------------------------------------------------------- /src/jp/guide/theme/unocss.md: -------------------------------------------------------------------------------- 1 | # UnoCSS テーマ 2 | 3 | [Theme Tokens](/zh/guide/theme/tokens) を UnoCSS のテーマ設定に注入し、UnoCSS の機能を活用することで、`text-primary` や `bg-primary` などのクラス名を使用できるようになり、コンポーネントライブラリと UnoCSS のテーマカラーを統一して適用できます。 4 | 5 | ```ts 6 | import { themeVars } from './src/theme/vars'; 7 | 8 | export default defineConfig({ 9 | theme: { 10 | ...themeVars 11 | } 12 | }); 13 | ``` 14 | 15 | ::: tip コードの場所 16 | ./uno.config.ts 17 | ::: 18 | 19 | ## UnoCSS のダークモード 20 | 21 | UnoCSS が提供するプリセットのダークモード機能を利用し、HTML に class="dark" を追加するだけで、`dark:text-#000` `dark:bg-#333` のようなクラスが有効になり、ダークモードの効果を実現できます。 22 | 23 | ``` 24 | export default defineConfig({ 25 | presets: [presetUno({ dark: 'class' })] 26 | }); 27 | ``` 28 | 29 | ::: tip コードの場所 30 | ./uno.config.ts 31 | ::: 32 | -------------------------------------------------------------------------------- /src/jp/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: home 3 | title: SoybeanAdmin 4 | titleTemplate: 洗練されたエレガントなバックエンドテンプレート 5 | 6 | hero: 7 | name: SoybeanAdmin 8 | text: 洗練されたエレガントなバックエンドテンプレート 9 | tagline: Vue3、Vite6、TypeScript、UnoCSS に基づいて 10 | image: 11 | src: /logo.svg 12 | alt: SoybeanAdmin 13 | actions: 14 | - theme: brand 15 | text: 開始 16 | link: /jp/guide/quick-start 17 | - theme: alt 18 | text: 紹介 19 | link: /jp/guide/intro 20 | - theme: alt 21 | text: GitHubで見る 22 | link: https://github.com/soybeanjs/soybean-admin 23 | - theme: alt 24 | text: React版ドキュメント -> 25 | link: https://react-docs.soybeanjs.cn/ 26 | 27 | features: 28 | - icon: 🆕 29 | title: 最新の人気技術スタック 30 | details: Vue3、Vite6、TypeScript、UnoCSS 31 | - icon: 🔄 32 | title: マルチフレームワーク対応 33 | details: Vue3とReactの両方をサポートし、フロントエンド技術スタックを柔軟に選択可能 34 | - icon: 🎨 35 | title: 多様なコンポーネントライブラリ統合 36 | details: Element Plus、Naive UI、Ant Design、Ant Design Vue など複数のコンポーネントライブラリに対応し、多様なUIニーズを満たす 37 | - icon: 🦋 38 | title: 明確なプロジェクト構造 39 | details: pnpm monorepoを採用し、構造が明確でエレガント、保守が容易。コードの規範性も非常に高い 40 | - icon: 🛠️ 41 | title: TypeScript 42 | details: 厳格な型チェックにより、チーム開発と保守が容易 43 | - icon: 🔩 44 | title: テーマ設定 45 | details: 豊富なテーマ設定が組み込まれており、UnoCSSと簡単に組み合わせて拡張可能 46 | - icon: 🔗 47 | title: ファイルルーティングシステム 48 | details: 自動化・インテリジェントなファイルルーティングシステム 49 | - icon: 🔑 50 | title: 権限ルーティング 51 | details: フロントエンドの静的ルーティングとバックエンドの動的ルーティングをサポート 52 | - icon: ⚙️ 53 | title: 拡張スクリプト 54 | details: 依存関係のワンクリックアップグレード、ChangeLogの自動生成、コミットメッセージの生成などのスクリプト機能を提供し、開発効率を大幅に向上。 55 | --- 56 | 57 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /src/jp/recommend/alova.md: -------------------------------------------------------------------------------- 1 | # Alova 2 | 3 | ## 関連リンク 4 | 5 | - [ドキュメント](https://alova.js.org/zh-CN) 6 | - [GitHub](https://github.com/alovajs/alova) 7 | 8 | ## 紹介 9 | 10 | Alova は、API 統合のワークフローを 7 ステップから 1 ステップに簡略化する次世代リクエストツールです。API を選択するだけで簡単に使用できます。 11 | 12 | @tanstack/react-request、swrjs、ahooks の useRequest などのライブラリとは異なり、Alova は完全なリクエストソリューションを提供します。Alova はリクエストの統合を非常に簡単にし、より効率的なクライアントとサーバー間のデータ通信を維持します。また、Alova はクライアントサイドおよびサーバーサイド環境(SSR を含む)でも使用できます。 13 | 14 | さらに、Alova には以下の特長があります: 15 | 16 | - axios に似た API デザインで、学習コストが低い; 17 | - 高パフォーマンスなクライアントサイドおよびサーバーサイドのリクエスト戦略で、アプリケーションがよりスムーズに動作; 18 | - 高い柔軟性で、Alova は任意の JavaScript 環境で使用でき、任意の UI フレームワークと連携可能で、統一された使用体験と完璧なコード移行を提供; 19 | - 多段階キャッシュモードとリクエスト共有メカニズムで、リクエストのパフォーマンスを向上させ、サーバーへの負荷を軽減; 20 | - API コードの高い凝縮性を持ち、各 API のリクエストパラメータ、キャッシュ挙動、レスポンスデータの変換などが同一のコードブロックにまとめられており、大量の API を管理する際に大きな利点があります; 21 | -------------------------------------------------------------------------------- /src/jp/recommend/index.md: -------------------------------------------------------------------------------- 1 | # 前書き 2 | 3 | このドキュメントでは、私たちが興味深いと感じたさまざまな技術をご紹介します。これらの技術は現時点ではまだ私たちのプロジェクトで採用されていないかもしれませんが、それでも非常に価値のあるものだと考えています。この紹介を通じて、少しでも皆さんのお役に立てれば幸いです。 4 | 5 | 技術の進歩は日進月歩であり、新しい技術が次々と登場しています。本ドキュメントで紹介する技術がすべてのプロジェクトに適用できるとは限りませんが、参考としてご活用いただけることでしょう。これらの技術に興味がある方や、新たなソリューションをプロジェクトに導入したいと考えている方にとって、有益な情報となることを願っています。 6 | 7 | この後の内容では、それぞれの技術について詳しくご紹介します。もし内容に誤りがあった場合や、ご不明な点がございましたら、お気軽にご連絡ください。皆さんのフィードバックをお待ちしております。 8 | 9 | それでは、お楽しみください! 10 | -------------------------------------------------------------------------------- /src/jp/recommend/klona.md: -------------------------------------------------------------------------------- 1 | # klona 2 | 3 | ## 関連リンク 4 | 5 | - [GitHub](https://github.com/lukeed/klona) 6 | 7 | ## 紹介 8 | 9 | `klona` は、JavaScriptのオブジェクト、配列、日付、正規表現など、さまざまなデータ型をディープコピーするための、非常に小型(240B~501B)で効率的なユーティリティライブラリです。 10 | 11 | ### 特徴 12 | 13 | - 超小型で高性能 14 | - ディープコピー/再帰的なコピー 15 | - `Array`、`Date`、`Map`、`Object`、`RegExp`、`Set`、`TypedArray` など、複雑なデータ型を安全に処理します。 16 | 17 | 浅いコピー(例:`Object.assign`)とは異なり、ディープコピーはソース入力を再帰的にたどり、その _値_(参照ではなく)を新しいインスタンスにコピーします。その結果、元のソースから独立して動作し、独自の値を制御する、構造的に同等なクローンが得られます。 18 | 19 | > **なぜ "klona"?** スウェーデン語で "clone" という意味です。 20 | 21 | ## インストール 22 | 23 | ```bash 24 | npm install --save klona 25 | ``` 26 | 27 | ## モード 28 | 29 | `klona` には複数の「バージョン」があり、必要な機能だけを取り込むことができます! 30 | 31 | #### `klona/json` 32 | 33 | > **サイズ (gzip):** 240 バイト 34 | > **利用可能性:** CommonJS, ES Module, UMD 35 | > **機能:** JSON データ型 36 | 37 | ```javascript 38 | import { klona } from 'klona/json'; 39 | ``` 40 | 41 | #### `klona/lite` 42 | 43 | > **サイズ (gzip):** 354 バイト 44 | > **利用可能性:** CommonJS, ES Module, UMD 45 | > **機能:** `klona/json` を拡張し、カスタムクラス、Date、RegExp のサポートを追加。 46 | 47 | ```javascript 48 | import { klona } from 'klona/lite'; 49 | ``` 50 | 51 | #### `klona` (デフォルト) 52 | 53 | > **サイズ (gzip):** 451 バイト 54 | > **利用可能性:** CommonJS, ES Module, UMD 55 | > **機能:** `klona/lite` を拡張し、Map, Set, DataView, ArrayBuffer, TypedArray のサポートを追加。 56 | 57 | ```javascript 58 | import { klona } from 'klona'; 59 | ``` 60 | 61 | #### `klona/full` 62 | 63 | > **サイズ (gzip):** 501 バイト 64 | > **利用可能性:** CommonJS, ES Module, UMD 65 | > **機能:** `klona` を拡張し、Symbol プロパティと列挙不可能なプロパティのサポートを追加。 66 | 67 | ```javascript 68 | import { klona } from 'klona/full'; 69 | ``` 70 | 71 | ## 使用方法 72 | 73 | ```javascript 74 | import { klona } from 'klona'; 75 | 76 | const input = { 77 | foo: 1, 78 | bar: { 79 | baz: 2, 80 | bat: { 81 | hello: 'world' 82 | } 83 | } 84 | }; 85 | 86 | const output = klona(input); 87 | 88 | // 元のオブジェクトと完全に同じ 89 | // assert.deepStrictEqual(input, output); // Node.js 環境でのアサーション 90 | 91 | // ディープアップデート... 92 | output.bar.bat.hola = 'mundo'; 93 | output.bar.baz = 99; 94 | 95 | // ...ソースオブジェクトには影響しません! 96 | console.log(JSON.stringify(input, null, 2)); 97 | // { 98 | // "foo": 1, 99 | // "bar": { 100 | // "baz": 2, 101 | // "bat": { 102 | // "hello": "world" 103 | // } 104 | // } 105 | // } 106 | ``` 107 | 108 | ## API 109 | 110 | ### `klona(input)` 111 | 112 | 戻り値: `typeof input` 113 | 114 | 入力値のディープコピー/クローンを返します。 115 | -------------------------------------------------------------------------------- /src/jp/recommend/page-spy.md: -------------------------------------------------------------------------------- 1 | # PageSpy 2 | 3 | ## 関連リンク 4 | 5 | - [GitHub](https://github.com/HuolalaTech/page-spy-web) 6 | - [官方文档](https://pagespy.org) 7 | - [Bilibili 视频](https://space.bilibili.com/3493272492181886/) 8 | 9 | ## 紹介 10 | 11 | ### 背景 12 | 13 | コンソールは日常の開発において欠かせない効率的なツールです。プロジェクトの問題は常に最初にコンソールを通じて調査されます。しかし、場合によってはコンソールが使用できないため、問題の調査に多くの時間と労力がかかることがあります。これが PageSpy が解決しようとしている問題です。 14 | 15 | 以下のシーンに遭遇したことはありませんか?: 16 | 17 | - **実機での H5 デバッグ**:以前は H5 で情報を表示できるパネルが提供されていましたが、実機の画面は小さく操作が不便で、表示が不親切でデータが切り捨てられることがありました; 18 | 19 | - **リモートワーク、遠隔コラボレーション**:従来のコミュニケーション手段(メール、電話、ビデオ会議など)は、コミュニケーションの周期が長く、効率が悪く、障害情報が不完全で、誤解や誤判断が生じやすい; 20 | 21 | - **ユーザーのデバイスでのホワイトスクリーン**:問題のあるユーザー情報を事前に把握する必要があり、問題の特定方法はデータ監視、ログ分析、さらには顧客現場に赴くことなどです。これらの方法は、障害担当者がビジネスシーンや技術実装を理解していることに依存しています; 22 | 23 | - **グローバルな「問題フィードバック」コンポーネント**:ユーザー体験を重視したほとんどのサイトでは、製品に障害が発生した場合にフィードバックを受け取って迅速に解決するため、製品側でユーザーにフィードバック用のフォームコンポーネントを提供しています。ユーザーの視点からは確かに好感度が増しますが、ユーザーが提出する内容は問題調査にあまり役立たないことが多いです。根本的な理由は、ユーザーが提出するのは主に文字での概要やスクリーンショット、時にはユーザー情報も含まれますが、開発者が求めているのは以下のような内容です: 24 | 25 | - ユーザーの操作履歴; 26 | - 操作に伴うプログラムの実行時のデータ。例えば、ログの出力、発行されたネットワークリクエストおよび応答データなど; 27 | 28 | ローカル開発では私たちはまさにこのようにコンソールを使っていませんか? 29 | 30 | ### 機能 31 | 32 | PageSpy は使用シーンに基づき、`オンラインリアルタイムデバッグ` と `オフラインログ再生` の 2 つのモードに分かれており、Console、Network、Page、Storage、System の情報パネルを提供します。また、コードをプロジェクト端に送信して実行することも可能です。これにより、開発者は障害対応の効率を向上させ、コミュニケーションの時間を短縮できます。 33 | 34 | 現在、PageSpy は Web / ミニプログラム / ReactNative / OpenHarmony プラットフォームで安定した SDK を提供しています。 35 | -------------------------------------------------------------------------------- /src/jp/recommend/soybean-cli.md: -------------------------------------------------------------------------------- 1 | # @soybeanjs/cli 2 | 3 | ## 関連リンク 4 | 5 | - [ドキュメント](https://github.com/soybeanjs/cli/blob/main/README.md) 6 | - [GitHub](https://github.com/soybeanjs/cli) 7 | 8 | ## 紹介 9 | 10 | SoybeanJS のコマンドラインツールで、6種類の便利なコマンドが含まれています: 11 | 12 | | コマンド | 役割 | 13 | | ----------------- | ---------------------------------------------------------------------------------------------------------- | 14 | | git-commit | Angular の規約に従った git コミットメッセージを生成(コミットメッセージに`!`を追加すると破壊的更新を示す) | 15 | | git-commit-verify | git コミットメッセージが Angular の規約に従っているか確認する | 16 | | cleanup | 依存関係とビルド成果物を素早く、完全にクリーンアップする | 17 | | ncu | コマンド、依存関係をアップグレードする | 18 | | changelog | 2つのタグに基づいて changelog を生成する(–total: すべてのタグに基づいて changelog を生成する) | 19 | | release | リリース:バージョン番号の更新、changelog の生成、コードのコミット | 20 | -------------------------------------------------------------------------------- /src/jp/standard/index.md: -------------------------------------------------------------------------------- 1 | # コーディング規約 2 | 3 | フロントエンド開発において、コードの規則化は可読性や保守性を向上させるだけでなく、チームでの協力による摩擦を減らし、開発効率を高めることにもつながります。本規約は、フロントエンド開発における統一された基準を提供することを目的とし、コードフォーマットのチェック、命名規則、Vueの記述規約、TypeScriptの記述規約などの内容を含んでいます。 4 | 5 | 本規約を遵守することで、開発者はコードの一貫性を保ち、スタイルの違いによるコードレビューの問題を減らし、プロジェクトの長期的な保守において大きなメリットを得ることができます。本規約が皆様の開発業務に役立つガイドとなることを願っています。 6 | -------------------------------------------------------------------------------- /src/jp/standard/lint.md: -------------------------------------------------------------------------------- 1 | # フォーマットチェック 2 | 3 | ## ESLint と Prettier を使用したコードフォーマット 4 | 5 | SoybeanJS チームは @soybeanjs/eslint-config を使用してコードフォーマットを行います。この設定には、ESLint と Prettier の設定、およびいくつかのカスタムルールが含まれています。 6 | 7 | ## コードチェック 8 | 9 | ### lint-staged 10 | 11 | `lint-staged`をインストール: 12 | 13 | ```bash 14 | pnpm i lint-staged -D 15 | ``` 16 | 17 | `package.json` に追加: 18 | 19 | ```json 20 | { 21 | "lint-staged": { 22 | "*": "eslint --fix" 23 | } 24 | } 25 | ``` 26 | 27 | ### simple-git-hooks 28 | 29 | `simple-git-hooks` をインストール: 30 | 31 | ```bash 32 | pnpm i simple-git-hooks -D 33 | ``` 34 | 35 | `package.json` に Git フックを追加: 36 | 37 | ```json 38 | { 39 | "simple-git-hooks": { 40 | "commit-msg": "pnpm sa git-commit-verify", 41 | "pre-commit": "pnpm typecheck && pnpm lint-staged" 42 | } 43 | } 44 | ``` 45 | 46 | `package.json` にスクリプトを追加: 47 | 48 | ```json 49 | { 50 | "scripts": { 51 | "prepare": "simple-git-hooks" 52 | } 53 | } 54 | ``` 55 | 56 | ::: tip ヒント 57 | `simple-git-hooks` の設定を変更または解除する場合は、まず `package.json` の `simple-git-hooks` の設定を変更し、その後 `pnpm run prepare` を実行して反映させてください。 58 | ::: 59 | -------------------------------------------------------------------------------- /src/jp/standard/naming.md: -------------------------------------------------------------------------------- 1 | # 命名規約 2 | 3 | - ファイルおよびフォルダの命名:小文字とハイフン`-`を使用して統一し、複数の単語はハイフンでつなぐ 4 | 5 | ``` 6 | views 7 | ├── home 8 | │ └── index.vue 9 | 10 | ``` 11 | 12 | - Vue コンポーネントの命名 13 | 14 | - コンポーネント名は PascalCase(単語の先頭を大文字)で統一 15 | 16 | ```vue 17 | 22 | ``` 23 | 24 | - iconify のアイコンコンポーネント名は kebab-case(小文字+ハイフン)で統一 25 | 26 | ```vue 27 | 30 | ``` 31 | 32 | > iconify プラグインが直接アイコンを表示できるようにするため 33 | 34 | - コンストラクタ、クラス、TS の型の命名:PascalCase(単語の先頭を大文字)で統一 35 | 36 | ```ts 37 | function Person() {} 38 | 39 | class Person {} 40 | 41 | type Person = { 42 | name: string; 43 | }; 44 | 45 | interface Person { 46 | name: string; 47 | } 48 | ``` 49 | 50 | - 変数・通常の関数の命名:camelCase(単語の先頭は小文字)で統一 51 | 52 | ```ts 53 | let num: number = 1; 54 | 55 | function getNum() {} 56 | ``` 57 | 58 | - 定数の命名:すべて大文字で統一し、単語はアンダースコア`_`でつなぐ 59 | 60 | ```ts 61 | const MAX_COUNT = 10; 62 | ``` 63 | 64 | - スタイルの命名:すべて小文字で統一し、単語はハイフンでつなぐ 65 | 66 | ```css 67 | .container { 68 | } 69 | 70 | .container-item { 71 | } 72 | ``` 73 | 74 | - リクエスト関数の命名:`fetch` で始め、後ろにリソース名をつける 75 | 76 | ```ts 77 | function fetchUser() {} 78 | ``` 79 | -------------------------------------------------------------------------------- /src/jp/standard/synthesis.md: -------------------------------------------------------------------------------- 1 | # 综合 2 | -------------------------------------------------------------------------------- /src/jp/standard/tools.md: -------------------------------------------------------------------------------- 1 | # 工具规范 2 | -------------------------------------------------------------------------------- /src/jp/standard/ts.md: -------------------------------------------------------------------------------- 1 | # TS 写法规范 2 | -------------------------------------------------------------------------------- /src/jp/standard/vue.md: -------------------------------------------------------------------------------- 1 | # Vue の記述規約 2 | 3 | ## SFC の順序 4 | 5 | ### script 6 | 7 | - import の記述順序 8 | 9 | - 以下の依存関係の順序に従うことを推奨: 10 | 11 | 1. vue 12 | 2. vue-router 13 | 3. pinia 14 | 4. @vueuse/core 15 | 5. UI ライブラリ 16 | 6. その他の依存関係 17 | 7. プロジェクト内部の依存関係(monorepo) 18 | 8. エイリアスのインポート 19 | 9. 相対パスのインポート 20 | 21 | - 型のインポートは `import type` を使用し、同じ依存関係のインポートの下に記述する 22 | 23 | 例: 24 | 25 | ```ts 26 | import { ref } from 'vue'; 27 | import type { Ref } from 'vue'; 28 | ``` 29 | 30 | - defineOptions 31 | 32 | - Props の型定義 33 | 34 | ```ts 35 | interface Props { 36 | prop1: string; 37 | prop2: number; 38 | } 39 | ``` 40 | 41 | - defineProps 42 | 43 | ```ts 44 | defineProps(); 45 | const props = defineProps(); // 用到props时 46 | ``` 47 | 48 | - Emits の型定義 49 | 50 | ```ts 51 | interface Emits { 52 | emit1: (arg1: string) => void; 53 | emit2: (arg1: number) => void; 54 | } 55 | 56 | // または 57 | interface Emits { 58 | emit1: [arg1: string]; 59 | emit2: [arg1: number]; 60 | } 61 | ``` 62 | 63 | - defineEmits 64 | 65 | ```ts 66 | defineEmits(); 67 | const emit = defineEmits(); // emit を使用する場合 68 | ``` 69 | 70 | - インポートした hooks 関数 71 | 72 | 例: useRouter、useRoute、および独自の hooks 73 | 74 | ```ts 75 | const router = useRouter(); 76 | const route = useRoute(); 77 | const appStore = useAppStore(); 78 | const { loading, startLoading, endLoading } = useLoading(); 79 | ``` 80 | 81 | - コンポーネントのロジック定義 82 | 83 | ```ts 84 | const count = ref(0); 85 | const increment = () => { 86 | count.value++; 87 | }; 88 | 89 | const visible = ref(false); 90 | const toggleVisible = () => { 91 | visible.value = !visible.value; 92 | }; 93 | ``` 94 | 95 | - 必要な `init` 関数(すべての初期化処理をここにまとめる) 96 | 97 | ```ts 98 | async function init() { 99 | await fetchData(); 100 | } 101 | ``` 102 | 103 | - watch と watchEffect 104 | 105 | ```ts 106 | watchEffect(() => { 107 | console.log(count.value); 108 | }); 109 | 110 | watch( 111 | () => count.value, 112 | (newValue, oldValue) => { 113 | console.log(newValue, oldValue); 114 | } 115 | ); 116 | ``` 117 | 118 | - ライフサイクルフック 119 | 120 | ```ts 121 | // 相当于在`created`钩子中执行 122 | init(); 123 | 124 | // 或者 125 | onMounted(() => { 126 | init(); 127 | }); 128 | ``` 129 | 130 | - defineExpose 131 | 132 | ```ts 133 | const exposed = { 134 | count, 135 | increment 136 | }; 137 | 138 | defineExpose(exposed); 139 | ``` 140 | -------------------------------------------------------------------------------- /src/jp/tutorial/debug.md: -------------------------------------------------------------------------------- 1 | # デバッグ 2 | 3 | ## 概要 4 | 5 | ソフトウェア開発の世界では、デバッグは開発者の拡大鏡と手術用ナイフのようなもので、以下のことを助けてくれます: 6 | 7 | - 🔍 コードのエラーを迅速に特定し修正する 8 | - 🔄 コードの実行フローを深く理解する 9 | - 📊 変数の状態をリアルタイムで監視する 10 | - 💾 メモリ使用量を分析する 11 | - ⚡ プログラムのパフォーマンスを最適化する 12 | 13 | この記事では、VSCode の強力なデバッグ機能を使い、デバッグのプロセスを効率的に行う方法を紹介します。 14 | 15 | ## JavaScript と TypeScript のデバッグ 16 | 17 | ### tsx - TypeScript 実行ツール 18 | 19 | [`tsx`](https://tsx.is/) は、Node.js で TypeScript を実行するための強化ツールです。これにより、TypeScript コードの実行がシンプルで直接的になります: 20 | 21 | - 設定なしで TypeScript ファイルを実行 22 | - ES モジュールと CommonJS の両方をサポート 23 | - ソースマップのサポート 24 | - 優れたパフォーマンス 25 | 26 | ```bash 27 | # tsx をインストール 28 | npm install -g tsx 29 | 30 | # TypeScript ファイルを実行 31 | tsx your-file.ts 32 | ``` 33 | 34 | VSCode のデバッグ設定を使うことで、ブレークポイントのデバッグや変数監視などの高度な機能を簡単に実現できます。次のセクションでは、VSCode のデバッグ環境の設定方法を詳しく説明します。 35 | 36 | > 💡 ヒント:VSCode のデバッグ機能は、Node.js のデバッガーと完璧に統合されているため、JavaScript のデバッグと同じように簡単に TypeScript のコードをデバッグできます。 37 | 38 | ### tsx のデバッグ手順 39 | 40 | 1. 最初に `tsx` をグローバルにインストールします: 41 | 42 | ```bash 43 | npm i -g tsx 44 | ``` 45 | 46 | 2. 次に、プロジェクトの `.vscode/launch.json` に以下のデバッグ設定を追加します: 47 | 48 | ```json 49 | { 50 | "version": "0.2.0", 51 | "configurations": [ 52 | { 53 | "type": "node", 54 | "request": "launch", 55 | "name": "TS Debugger", 56 | "runtimeExecutable": "tsx", 57 | "skipFiles": ["/**", "${workspaceFolder}/node_modules/**"], 58 | "program": "${file}" 59 | } 60 | ] 61 | } 62 | ``` 63 | 64 | 3. デバッグテスト 65 | 66 | - 新しく `debug.ts` ファイルを作成 67 | - 以下のコードを入力 68 | 69 | ```ts 70 | function transformToKebabCase(input: string): string { 71 | return input.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase(); 72 | } 73 | 74 | function start() { 75 | const input = 'HelloWorld'; 76 | const result = transformToKebabCase(input); 77 | return result; 78 | } 79 | 80 | start(); 81 | ``` 82 | 83 | 4. 画像の手順に従ってデバッグします 84 | 85 | ![](../../assets/VSCode调试指南01.png) 86 | ![](../../assets/VSCode调试指南02.png) 87 | 88 | ## Vue デバッグ 89 | 90 | ### デバッグ手順 91 | 92 | 1. プロジェクトの `.vscode/launch.json` に以下のデバッグ設定を追加します: 93 | 94 | ```json 95 | { 96 | "version": "0.2.0", 97 | "configurations": [ 98 | { 99 | "type": "chrome", 100 | "request": "launch", 101 | "name": "Vue Debugger", 102 | "url": "http://localhost:9527", 103 | "webRoot": "${workspaceFolder}" 104 | } 105 | ] 106 | } 107 | ``` 108 | 109 | > 設定内の URL のポート番号は、プロジェクトのローカル開発サーバーのポート番号と一致させてください。 110 | 111 | 2. プロジェクトをローカルで起動します 112 | 3. デバッグをテストします 113 | 114 | - `about/index.vue` ページを開き、`onMounted` 内にブレークポイントを追加 115 | - `Vue Debugger` を選択し、デバッグを開始 - ブラウザで about ページが開き、その後 VSCode に自動で戻ります 116 | ![](../../assets/VSCode调试指南03.png) 117 | > 同様に、例えばボタンをクリックして実行されるロジックをテストする場合、クリックイベント内にブレークポイントを追加し、ページ上でクリックすることでデバッグをトリガーできます。 118 | 119 | ### ブレークポイントの種類 120 | 121 | - コンポーネントの methods にブレークポイントを設定 122 | - ライフサイクルフック内にブレークポイントを設定 123 | - 計算プロパティ内にブレークポイントを設定 124 | - watch 内にブレークポイントを設定 125 | - ルートガード内にブレークポイントを設定 126 | 127 | > 開発環境で最良のデバッグ体験を得るために、ソースマップを有効にすることを忘れないでください: 128 | 129 | ```ts 130 | // vite.config.ts 131 | export default defineConfig({ 132 | build: { 133 | sourcemap: true 134 | } 135 | ``` 136 | -------------------------------------------------------------------------------- /src/jp/tutorial/git.md: -------------------------------------------------------------------------------- 1 | # Git 2 | 3 | [Git](https://git-scm.com/) の公式サイトから Git ツールをダウンロードします。 4 | 5 | ## Git の初期設定 6 | 7 | - ユーザー情報の設定 8 | 9 | ```bash 10 | git config --global user.name "Soybean" 11 | git config --global user.email "soybeanjs@outlook.com" 12 | ``` 13 | 14 | - SSH キーの生成 15 | 16 | ```bash 17 | ssh-keygen 18 | ``` 19 | 20 | > 途中の選択肢では、そのまま Enter を押してください。 21 | 22 | ::: tip ヒント 23 | 完全なコマンド: 24 | 25 | ```bash 26 | ssh-keygen -t rsa -C "soybeanjs@outlook.com" 27 | ``` 28 | 29 | > `-t` rsa は RSA 鍵を生成するオプション、`-C` はコメントを設定するオプションで、後にコメント内容を指定します。 30 | 31 | ::: 32 | 33 | - Git の SSH キーをアップロード 34 | 35 | ユーザーディレクトリ内の .ssh/id_rsa.pub を探し、ファイルを開いて内容をコピーし、Git コード管理プラットフォームの SSH キー設定に追加します。 36 | 37 | ## Git の基本コマンド 38 | 39 | - main ブランチの最新コードを現在のブランチに同期 40 | 41 | ```bash 42 | git pull origin main 43 | git rebase origin/main 44 | ``` 45 | 46 | > 現在のブランチが main の場合、` ` を直接使用できます。 47 | 48 | 競合が発生した場合は、競合を解決した後、以下のコマンドで rebase を続行します。 49 | 50 | ```bash 51 | git add . 52 | git rebase --continue 53 | ``` 54 | 55 | - 直前のコミットの日時を変更 56 | 57 | ```bash 58 | git commit --amend --date="2022-07-29T23:45" 59 | ``` 60 | 61 | - 複数のコミットを統合 62 | 63 | ```bash 64 | git rebase -i HEAD~n # n为要合并commit的个数 65 | ``` 66 | 67 | -- 指定したコミットを現在のブランチにコピー 68 | 69 | ```bash 70 | git cherry-pick 71 | ``` 72 | 73 | > デフォルトでは元のコミット情報を保持します。コミット履歴を残さず適用したい場合は、`git cherry-pick -n ` を使用します。 74 | -------------------------------------------------------------------------------- /src/jp/tutorial/index.md: -------------------------------------------------------------------------------- 1 | # チュートリアル 2 | 3 | 現代のフロントエンド開発において、さまざまな開発ツールや環境のインストールと設定を習得することは非常に重要です。バージョン管理ツールの Git、JavaScript の実行環境である Node.js、さらにはデバッグツールなど、これらはフロントエンド開発者の日常業務に欠かせないものです。本チュートリアルでは、Mac システム上でこれらのツールをインストールし、設定する方法を詳しく解説し、効率的なフロントエンド開発環境を迅速に構築する手助けをします。 4 | 5 | 本チュートリアルを通じて、次のことを学ぶことができます: 6 | 7 | - Git のインストールと基本操作:Git のインストール方法、設定、および基本的な Git コマンドの使い方。 8 | - Node.js のインストールと設定:Node.js のインストール方法、npm の設定、および fnm を使用した Node.js バージョン管理。 9 | - デバッグツールの使用:VS Code を用いたフロントエンドコードのデバッグ、ブレークポイントの設定、変数の確認方法など。 10 | 11 | 本チュートリアルを通じて、フロントエンド開発環境をスムーズに構築し、開発効率を向上させ、フロントエンド開発を楽しんでいただければ幸いです。 12 | -------------------------------------------------------------------------------- /src/jp/tutorial/nodejs.md: -------------------------------------------------------------------------------- 1 | # NodeJS インストールチュートリアル 2 | 3 | 日常的な開発では、さまざまな NodeJS バージョンで開発されたプロジェクトに出会うことがよくあります。あるプロジェクトでは古いバージョンの NodeJS が必要で、別のプロジェクトでは新しいバージョンが必要です。そのため、NodeJS のバージョン管理ツールをインストールする必要があります。 4 | 5 | 以下に、いくつかのツールをおすすめします。 6 | 7 | - ## nvm 8 | 9 | ### インストール 10 | 11 | 1.ターミナルを開き、以下のコマンドを入力します: 12 | 13 | #### macos 14 | 15 | ```bash 16 | curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash 17 | ``` 18 | 19 | #### windows 20 | 21 | ```bash 22 | https://github.com/coreybutler/nvm-windows/releases/download/1.2.2/nvm-setup.exe 23 | ``` 24 | 25 | 2.インストールが完了したら、ターミナルを閉じて再度開き、以下のコマンドを入力します: 26 | 27 | ```bash 28 | nvm --version 29 | ``` 30 | 31 | 3.バージョン番号が表示されれば、インストール成功です。 32 | 33 | ### 安装 NodeJS 34 | 35 | 1. 以下のコマンドを入力して、利用可能な NodeJS のバージョンを一覧表示します: 36 | 37 | ```bash 38 | nvm ls-remote 39 | ``` 40 | 41 | 2. 任意のバージョンを選んでインストールします(例:NodeJS 18.20.5 をインストール): 42 | 43 | ```bash 44 | nvm install 18.20.5 45 | ``` 46 | 47 | 3. インストールが完了したら、以下のコマンドでそのバージョンを切り替えます: 48 | 49 | ```bash 50 | nvm use 18.20.5 51 | ``` 52 | 53 | 4. 以下のコマンドで、現在使用している NodeJS のバージョンを確認します: 54 | 55 | ```bash 56 | node -v 57 | ``` 58 | 59 | 5. 以下のコマンドで、インストールされているすべての NodeJS バージョンを確認します: 60 | 61 | ```bash 62 | nvm ls 63 | ``` 64 | 65 | - ## fnm 66 | 67 | ### windows 68 | 69 | #### 安装chocolatey 70 | 71 | 1. 管理者モードで Windows Terminal を開きます。 72 | 73 | 2. 以下のコマンドを実行します: 74 | 75 | ```bash 76 | Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1')) 77 | ``` 78 | 79 | 3. choco -v と入力して、インストールが成功したか確認します。 80 | 81 | > Chocolatey を使用してソフトウェアをインストールする際は、管理者モードで Windows Terminal を開く必要があります。 82 | 83 | ### fnm のインストール 84 | 85 | 1. 管理者モードで Terminal を開きます。 86 | 87 | 2. 以下のコマンドを実行します: 88 | 89 | ```bash 90 | choco install fnm 91 | ``` 92 | 93 | ### fnm コマンドのテスト 94 | 95 | 1. PowerShell を開きます。 96 | 97 | 2. `fnm -h` と入力して、コマンドが正常に動作するかテストします: 98 | 99 | ```bash 100 | fnm -h 101 | ``` 102 | 103 | ### 環境変数の設定 104 | 105 | #### Powershell 106 | 107 | 1. 以下のディレクトリに `profile.ps1` ファイルを新規作成します: 108 | 109 | ```other 110 | %USERPROFILE%\Documents\WindowsPowerShell\profile.ps1 111 | ``` 112 | 113 | > %USERPROFILE% はユーザーディレクトリを指します。ファイルエクスプローラーのアドレスバーに %USERPROFILE% を入力し、Enter を押してください。 114 | 115 | > WindowsPowerShell は新規作成したディレクトリ名です。Node をインストールした後もコマンドが認識されない場合は、フォルダ名を PowerShell に変更してください。 116 | 117 | 2. 上記の設定ファイルに以下のコードを追加します: 118 | 119 | ```bash 120 | fnm env --use-on-cd | Out-String | Invoke-Expression 121 | ``` 122 | 123 | #### cmd 124 | 125 | 1. cmd を検索します。 126 | 2. ファイルの場所を開きます。 127 | 3. 「コマンドプロンプト」を右クリックし、プロパティを選択します。 128 | 4. 目標を以下のように変更します: 129 | 130 | ```other 131 | %windir%\system32\cmd.exe /k %USERPROFILE%\bashrc.cmd 132 | ``` 133 | 134 | 5. ユーザーディレクトリに bashrc.cmd ファイルを作成します。 135 | 6. 上記の設定ファイルに以下のコードを追加します: 136 | 137 | ```bash 138 | @echo off 139 | FOR /f "tokens=*" %%z IN ('fnm env --use-on-cd') DO CALL %%z 140 | ``` 141 | 142 | #### git bash 143 | 144 | ユーザーディレクトリにある git bash の設定ファイル .bash_profile に以下のコードを追加します: 145 | 146 | ```bash 147 | eval $(fnm env | sed 1d) 148 | export PATH=$(cygpath $FNM_MULTISHELL_PATH):$PATH 149 | 150 | if [[ -f .node-version || -f .nvmrc ]]; then 151 | fnm use 152 | fi 153 | ``` 154 | 155 | #### VSCode 内蔵のcmd 156 | 157 | 設定ファイル settings.json に以下のコードを追加します: 158 | 159 | ```json 160 | "terminal.integrated.defaultProfile.windows": "Default Cmd", 161 | "terminal.integrated.profiles.windows": { 162 | "Default Cmd":{ 163 | "path": "C:\\Windows\\System32\\cmd.exe", 164 | "args": ["/k", "%USERPROFILE%\\bashrc.cmd"] 165 | } 166 | } 167 | ``` 168 | 169 | ### macOS 170 | 171 | #### fnm のインストール 172 | 173 | ```bash 174 | curl -fsSL https://fnm.vercel.app/install | bash 175 | ``` 176 | 177 | #### fnm 環境の設定 178 | 179 | 1. .zshrc をリフレッシュします: 180 | 181 | ```bash 182 | eval "$(fnm env --use-on-cd)" 183 | ``` 184 | 185 | 2. source ~/.zshrc 186 | 187 | ```bash 188 | source ~/.zshrc 189 | ``` 190 | 191 | #### fnm の使用 192 | 193 | #### NodeJS のインストール 194 | 195 | ```other 196 | fnm install 16 197 | fnm install 14 198 | fnm install 12 199 | ``` 200 | 201 | #### NodeJS の使用 202 | 203 | ```other 204 | fnm use 16 205 | fnm use 14 206 | fnm use 12 207 | ``` 208 | 209 | #### Node コマンドのテスト 210 | 211 | ```other 212 | node -v 213 | ``` 214 | 215 | #### fnm のデフォルト Node バージョンを切り替える 216 | 217 | ```other 218 | fnm default 14 # デフォルトで Node バージョン 14 を使用、ターミナルを開くたびにバージョン 14 が使用される 219 | ``` 220 | 221 | #### fnm のその他の使い方 222 | 223 | ```other 224 | fnm -h 225 | ``` 226 | 227 | > または [fnm](https://github.com/Schniz/fnm) を参照してください。 228 | -------------------------------------------------------------------------------- /src/jp/tutorial/other.md: -------------------------------------------------------------------------------- 1 | # 其他教程 2 | -------------------------------------------------------------------------------- /src/jp/tutorial/software.md: -------------------------------------------------------------------------------- 1 | # ソフトウェアインストールガイド 2 | 3 | - ## ApiPost 4 | 5 | 概要:API テストおよびモックツール 6 | 7 | [官方网址](https://www.apipost.cn/download.html) 8 | 9 | - ## Postman 10 | 11 | 概要:API テストツール 12 | 13 | [官方网址](https://www.postman.com/downloads/) 14 | 15 | - ## Charles 16 | 17 | 概要:パケットキャプチャツール 18 | 19 | [官方网址](https://www.charlesproxy.com/) 20 | [下载地址](https://www.charlesproxy.com/download/) 21 | 22 | - ## Fiddler 23 | 24 | 概要:パケットキャプチャツール 25 | 26 | [官方网址](https://www.telerik.com/fiddler) 27 | 28 | - ## Typora 29 | 30 | 概要:Markdown エディター 31 | 32 | [官方网址](https://typora.io/) 33 | 34 | - ## Xshell 35 | 36 | 概要:リモート接続ツール 37 | 38 | [官方网址](https://www.netsarang.com/zh/xshell-download/) 39 | 40 | - ## Xftp 41 | 42 | 概要:リモートファイル転送ツール 43 | 44 | [官方网址](https://www.netsarang.com/zh/xftp-download/) 45 | -------------------------------------------------------------------------------- /src/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soybeanjs/soybean-admin-docs/de47ce6a2600a0422e0992fc27188b5c36d0dade/src/public/favicon.ico -------------------------------------------------------------------------------- /src/public/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | -------------------------------------------------------------------------------- /src/public/router-guard-flow.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soybeanjs/soybean-admin-docs/de47ce6a2600a0422e0992fc27188b5c36d0dade/src/public/router-guard-flow.pdf -------------------------------------------------------------------------------- /src/public/tencent-qq.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/recommend/alova.md: -------------------------------------------------------------------------------- 1 | # Alova 2 | 3 | ## Related links 4 | 5 | - [Docs](https://alova.js.org) 6 | - [GitHub](https://github.com/alovajs/alova) 7 | 8 | 9 | ## Introduce 10 | 11 | Alova is a workflow-streamlined next-generation request tool. It can extremely streamline your API integration workflow from 7 steps to 1 step, and you just select the API what you need. 12 | 13 | Different from @tanstack/react-request, swrjs, ahooks's useRequest, etc. library, alova is a comprehensive request tool, alova makes your request integration very simple and maintains more efficient Client-Server data interaction. In addition, you can use it in client and server environments (including SSR). 14 | 15 | In addition, alova also has the following features: 16 | - API design similar to axios, with lower learning cost; 17 | - High-performance client and server request strategies, making the application smoother; 18 | - High flexibility, alova can be used in any js environment with any UI framework, and provides a unified user experience and perfect code migration; 19 | - Multi-level cache mode and request sharing mechanism to improve request performance and reduce server-side pressure; 20 | - High aggregation of api code organization, the request parameters, cache behavior, response data conversion, etc. of each API will be gathered in the same code block, which is a great advantage for managing a large number of APIs; 21 | -------------------------------------------------------------------------------- /src/recommend/index.md: -------------------------------------------------------------------------------- 1 | # Preface 2 | 3 | In this section of the document, we will introduce various technologies that we find interesting. Although these technologies may not have been used in our project yet, we believe they are very valuable content. We hope that through these introductions, we can help you. 4 | 5 | We are well aware of the rapid development of technology and the constant emergence of new technologies. Although we cannot guarantee that the techniques presented in these introductions will be applicable to every project, we believe they have some reference value. Whether you are interested in these technologies or looking to try new solutions in a project, we hope to provide you with some useful information. 6 | 7 | Please continue reading the following content to learn more about these technologies. If there are any errors in the introduction or other information, please feel free to contact us and we will be happy to provide assistance and correction for you. thank you! 8 | 9 | Wishing you a pleasant reading! 10 | -------------------------------------------------------------------------------- /src/recommend/klona.md: -------------------------------------------------------------------------------- 1 | # klona 2 | 3 | ## Related Links 4 | 5 | - [GitHub](https://github.com/lukeed/klona) 6 | 7 | ## Introduction 8 | 9 | `klona` is a tiny (240B to 501B) and fast utility to "deep clone" Objects, Arrays, Dates, RegExps, and more! 10 | 11 | ### Features 12 | 13 | - Super tiny and performant 14 | - Deep clone / recursive copies 15 | - Safely handles complex data types: `Array`, `Date`, `Map`, `Object`, `RegExp`, `Set`, `TypedArray`, and more. 16 | 17 | Unlike a "shallow copy" (eg, `Object.assign`), a "deep clone" recursively traverses a source input and copies its _values_ — instead of _references_ to its values — into a new instance of that input. The result is a structurally equivalent clone that operates independently of the original source and controls its own values. 18 | 19 | > **Why "klona"?** It's "clone" in Swedish. 20 | 21 | ## Install 22 | 23 | ```bash 24 | npm install --save klona 25 | ``` 26 | 27 | ## Modes 28 | 29 | There are multiple "versions" of `klona` available, which allows you to bring only the functionality you need! 30 | 31 | #### `klona/json` 32 | 33 | > **Size (gzip):** 240 bytes 34 | > **Availability:** CommonJS, ES Module, UMD 35 | > **Ability:** JSON data types 36 | 37 | ```javascript 38 | import { klona } from 'klona/json'; 39 | ``` 40 | 41 | #### `klona/lite` 42 | 43 | > **Size (gzip):** 354 bytes 44 | > **Availability:** CommonJS, ES Module, UMD 45 | > **Ability:** extends `klona/json` with support for custom class, Date, and RegExp 46 | 47 | ```javascript 48 | import { klona } from 'klona/lite'; 49 | ``` 50 | 51 | #### `klona` (default) 52 | 53 | > **Size (gzip):** 451 bytes 54 | > **Availability:** CommonJS, ES Module, UMD 55 | > **Ability:** extends `klona/lite` with support for Map, Set, DataView, ArrayBuffer, TypedArray 56 | 57 | ```javascript 58 | import { klona } from 'klona'; 59 | ``` 60 | 61 | #### `klona/full` 62 | 63 | > **Size (gzip):** 501 bytes 64 | > **Availability:** CommonJS, ES Module, UMD 65 | > **Ability:** extends `klona` with support for Symbol properties and non-enumerable properties 66 | 67 | ```javascript 68 | import { klona } from 'klona/full'; 69 | ``` 70 | 71 | ## Usage 72 | 73 | ```javascript 74 | import { klona } from 'klona'; 75 | 76 | const input = { 77 | foo: 1, 78 | bar: { 79 | baz: 2, 80 | bat: { 81 | hello: 'world' 82 | } 83 | } 84 | }; 85 | 86 | const output = klona(input); 87 | 88 | // exact copy of original 89 | // assert.deepStrictEqual(input, output); // For assertion in Node.js environment 90 | 91 | // applying deep updates... 92 | output.bar.bat.hola = 'mundo'; 93 | output.bar.baz = 99; 94 | 95 | // ...doesn't affect source! 96 | console.log(JSON.stringify(input, null, 2)); 97 | // { 98 | // "foo": 1, 99 | // "bar": { 100 | // "baz": 2, 101 | // "bat": { 102 | // "hello": "world" 103 | // } 104 | // } 105 | // } 106 | ``` 107 | 108 | ## API 109 | 110 | ### `klona(input)` 111 | 112 | Returns: `typeof input` 113 | 114 | Returns a deep copy/clone of the input. 115 | -------------------------------------------------------------------------------- /src/recommend/page-spy.md: -------------------------------------------------------------------------------- 1 | # PageSpy 2 | 3 | ## Related Links 4 | 5 | - [GitHub](https://github.com/HuolalaTech/page-spy-web) 6 | - [Docs](https://pagespy.org) 7 | - [Bilibili](https://space.bilibili.com/3493272492181886/) 8 | 9 | ## Introduction 10 | 11 | ### Background 12 | 13 | The Devtools is an essential efficiency tool in daily development, and project issues are usually first identified through it. However, sometimes it’s impossible to use the Devtools, which can lead to time-consuming and labor-intensive troubleshooting. This is the problem that PageSpy aims to solve. 14 | 15 | Have you ever encountered the following situations? 16 | 17 | - **Mobile device debugging**: In the past, some products provided a panel to view information on mobile device, but the small screen size of real devices made it inconvenient to operate and display, and the data was often truncated. 18 | 19 | - **Remote work, cross-location collaboration**: Traditional communication methods such as email, phone calls, or video conferences are lengthy, inefficient, and the fault information is often incomplete, leading to misunderstandings or misjudgments. 20 | 21 | - **User device white screen**: Besides needing to pre-obtain user information when issues arise, methods to pinpoint problems include reviewing data monitoring, log analysis, and even visiting the client on-site. These approaches rely on the troubleshooting staff understanding both the business scenario and the technical implementation. 22 | 23 | - **Global "Feedback" Component**: Many user-centric websites provide a feedback form component to gather user reports after a product issue occurs, allowing for timely resolution. From the user's perspective, this improves user satisfaction, but the content submitted by users might not be very helpful for troubleshooting. The main reason is: users mostly submit a textual summary and screenshots, which may include user information, but what developers really want to see are: 24 | 25 | - The user’s action trail. 26 | - Runtime data generated during the operations, such as printed logs, network requests, and response data. 27 | 28 | Just like how we use the console during local development, right? 29 | 30 | ### Capabilities 31 | 32 | PageSpy provides two modes based on usage scenarios: **Online Real-time Debugging** and **Offline Log Replay**. It offers panels for Console, Network, Page, Storage, and System information, and also allows you to send code to the project for execution. This helps developers improve troubleshooting efficiency and reduce communication time. 33 | 34 | Currently, PageSpy has stable SDKs available for Web, Mini Programs, ReactNative, and OpenHarmony platforms. 35 | -------------------------------------------------------------------------------- /src/recommend/soybean-cli.md: -------------------------------------------------------------------------------- 1 | # @soybeanjs/cli 2 | 3 | ## Related links 4 | 5 | - [Docs](https://github.com/soybeanjs/cli/blob/main/README.md) 6 | - [GitHub](https://github.com/soybeanjs/cli) 7 | 8 | ## Introduce 9 | 10 | SoybeanJS's command-line tool includes six convenient commands: 11 | 12 | | command | effect | 13 | |-------------------|--------------------------------------------------------| 14 | | git-commit | Generate Git commit information that complies with Angular specifications (adding the prefix '!' to the commit information can indicate a destructive update commit) | 15 | | git-commit-verify | Verify whether the commit information of Git complies with Angular specifications | 16 | | cleanup | Quickly and completely clear dependencies and build products | 17 | | ncu | Command npm check updates to upgrade dependencies | 18 | | changelog | Generate changelog based on two tags (-- total: Generate changelog based on all tags) | 19 | | release | Release: Update version number, generate changelog, submit code | 20 | -------------------------------------------------------------------------------- /src/standard/index.md: -------------------------------------------------------------------------------- 1 | # Code Standards 2 | 3 | In the process of front-end development, code standardization not only helps improve code readability and maintainability but also reduces friction in team collaboration and enhances development efficiency. This standard aims to provide a unified set of guidelines for front-end development, covering aspects such as code formatting checks, naming conventions, Vue writing standards, and TypeScript writing standards. 4 | 5 | By adhering to this standard, developers can ensure code consistency, reduce code review issues caused by style differences, and benefit greatly in the long-term maintenance of the project. We hope this standard can provide strong support and guidance for your development work. 6 | -------------------------------------------------------------------------------- /src/standard/lint.md: -------------------------------------------------------------------------------- 1 | # Formatting Check 2 | 3 | ## Code Formatting with ESLint and Prettier 4 | 5 | The SoybeanJS team uses [`@soybeanjs/eslint-config`](https://github.com/soybeanjs/eslint-config) for code formatting. This configuration includes ESLint and Prettier settings, as well as some custom rules. 6 | 7 | ## Code Check 8 | 9 | ### lint-staged 10 | 11 | Install `lint-staged`: 12 | 13 | ```bash 14 | pnpm i lint-staged -D 15 | ``` 16 | 17 | Add to `package.json`: 18 | 19 | ```json 20 | { 21 | "lint-staged": { 22 | "*": "eslint --fix" 23 | } 24 | } 25 | ``` 26 | 27 | ### simple-git-hooks 28 | 29 | Install `simple-git-hooks`: 30 | 31 | ```bash 32 | pnpm i simple-git-hooks -D 33 | ``` 34 | 35 | Add git hooks to `package.json`: 36 | 37 | ```json 38 | { 39 | "simple-git-hooks": { 40 | "commit-msg": "pnpm sa git-commit-verify", 41 | "pre-commit": "pnpm typecheck && pnpm lint-staged" 42 | } 43 | } 44 | ``` 45 | 46 | Add scripts to `package.json`: 47 | 48 | ```json 49 | { 50 | "scripts": { 51 | "prepare": "simple-git-hooks" 52 | } 53 | } 54 | ``` 55 | 56 | ::: tip 57 | When changing the `simple-git-hooks` configuration or removing `simple-git-hooks`, first update the corresponding configuration in `package.json`, then run `pnpm run prepare` to apply the changes. 58 | ::: 59 | -------------------------------------------------------------------------------- /src/standard/naming.md: -------------------------------------------------------------------------------- 1 | # Naming Conventions 2 | 3 | - File and folder naming: Use lowercase with hyphen `-` for naming, connect multiple words with hyphens 4 | 5 | ``` 6 | views 7 | ├── home 8 | │ └── index.vue 9 | 10 | ``` 11 | 12 | - Vue component names 13 | 14 | - Component names are uniformly named in PascalCase, with the first letter of multiple words capitalized 15 | 16 | ```vue 17 | 22 | ``` 23 | 24 | - Iconify icon component names are uniformly named in kebab-case, with multiple words connected by hyphens 25 | 26 | ```vue 27 | 30 | ``` 31 | 32 | > To facilitate the direct display of icons by the Iconify plugin 33 | 34 | - Constructor, class, TS type naming: Uniformly named in PascalCase, with the first letter of multiple words capitalized 35 | 36 | ```ts 37 | function Person() {} 38 | 39 | class Person {} 40 | 41 | type Person = { 42 | name: string; 43 | }; 44 | 45 | interface Person { 46 | name: string; 47 | } 48 | ``` 49 | 50 | - Variable, ordinary function naming: Uniformly named in camelCase, with the first letter of multiple words lowercase 51 | 52 | ```ts 53 | let num: number = 1; 54 | 55 | function getNum() {} 56 | ``` 57 | 58 | - Constant naming: Uniformly named in uppercase, with multiple words connected by underscores 59 | 60 | ```ts 61 | const MAX_COUNT = 10; 62 | ``` 63 | 64 | - Style naming: Uniformly named in lowercase, with multiple words connected by hyphens 65 | 66 | ```css 67 | .container { 68 | } 69 | 70 | .container-item { 71 | } 72 | ``` 73 | 74 | - Request function naming: uniformly start with `fetch`, followed by the name of the requested resource 75 | 76 | ```ts 77 | function fetchUser() {} 78 | ``` 79 | -------------------------------------------------------------------------------- /src/standard/synthesis.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soybeanjs/soybean-admin-docs/de47ce6a2600a0422e0992fc27188b5c36d0dade/src/standard/synthesis.md -------------------------------------------------------------------------------- /src/standard/tools.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soybeanjs/soybean-admin-docs/de47ce6a2600a0422e0992fc27188b5c36d0dade/src/standard/tools.md -------------------------------------------------------------------------------- /src/standard/ts.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soybeanjs/soybean-admin-docs/de47ce6a2600a0422e0992fc27188b5c36d0dade/src/standard/ts.md -------------------------------------------------------------------------------- /src/standard/vue.md: -------------------------------------------------------------------------------- 1 | # Vue Writing Standards 2 | 3 | ## SFC Order 4 | 5 | ### script 6 | 7 | - import statements 8 | 9 | - Recommended dependency order: 10 | 11 | 1. vue 12 | 2. vue-router 13 | 3. pinia 14 | 4. @vueuse/core 15 | 5. UI libraries 16 | 6. Other dependencies 17 | 7. Internal project dependencies (monorepo) 18 | 8. Alias imports 19 | 9. Relative path imports 20 | 21 | - Types should be imported separately using `import type` and placed below the same dependency 22 | 23 | Example: 24 | 25 | ```ts 26 | import { ref } from 'vue'; 27 | import type { Ref } from 'vue'; 28 | ``` 29 | 30 | - defineOptions 31 | 32 | - Props type definition 33 | 34 | ```ts 35 | interface Props { 36 | prop1: string; 37 | prop2: number; 38 | } 39 | ``` 40 | 41 | - defineProps 42 | 43 | ```ts 44 | defineProps(); 45 | const props = defineProps(); // When using props 46 | ``` 47 | 48 | - Emits type definition 49 | 50 | ```ts 51 | interface Emits { 52 | emit1: (arg1: string) => void; 53 | emit2: (arg1: number) => void; 54 | } 55 | 56 | // Or 57 | interface Emits { 58 | emit1: [arg1: string]; 59 | emit2: [arg1: number]; 60 | } 61 | ``` 62 | 63 | - defineEmits 64 | 65 | ```ts 66 | defineEmits(); 67 | const emit = defineEmits(); // When using emit 68 | ``` 69 | 70 | - Imported hooks functions 71 | 72 | Example: useRouter, useRoute, and custom hooks 73 | 74 | ```ts 75 | const router = useRouter(); 76 | const route = useRoute(); 77 | const appStore = useAppStore(); 78 | const { loading, startLoading, endLoading } = useLoading(); 79 | ``` 80 | 81 | - Component logic definition 82 | 83 | ```ts 84 | const count = ref(0); 85 | const increment = () => { 86 | count.value++; 87 | }; 88 | 89 | const visible = ref(false); 90 | const toggleVisible = () => { 91 | visible.value = !visible.value; 92 | }; 93 | ``` 94 | 95 | - Necessary `init` function, all initialization logic is placed here 96 | 97 | ```ts 98 | async function init() { 99 | await fetchData(); 100 | } 101 | ``` 102 | 103 | - watch and watchEffect 104 | 105 | ```ts 106 | watchEffect(() => { 107 | console.log(count.value); 108 | }); 109 | 110 | watch( 111 | () => count.value, 112 | (newValue, oldValue) => { 113 | console.log(newValue, oldValue); 114 | } 115 | ); 116 | ``` 117 | 118 | - Lifecycle hooks 119 | 120 | ```ts 121 | // Equivalent to executing in the `created` hook 122 | init(); 123 | 124 | onMounted(() => { 125 | console.log('mounted'); 126 | }); 127 | ``` 128 | 129 | - defineExpose 130 | 131 | ```ts 132 | const exposed = { 133 | count, 134 | increment 135 | }; 136 | 137 | defineExpose(exposed); 138 | ``` 139 | -------------------------------------------------------------------------------- /src/tutorial/debug.md: -------------------------------------------------------------------------------- 1 | # Debugging 2 | 3 | ## Overview 4 | 5 | In the world of software development, debugging is like a developer's magnifying glass and scalpel. It not only helps us: 6 | 7 | - 🔍 Quickly locate and fix code errors 8 | - 🔄 Deeply understand the code execution process 9 | - 📊 Monitor variable states in real-time 10 | - 💾 Analyze memory usage 11 | - ⚡ Optimize program performance 12 | 13 | This article will explore how to use VSCode's powerful debugging features to make the debugging process easy and efficient. 14 | 15 | ## JavaScript and TypeScript Debugging 16 | 17 | ### tsx - The TypeScript Execution Tool 18 | 19 | [`tsx`](https://tsx.is/) is an enhancement for running TypeScript in Node.js, making the execution of TypeScript code simple and straightforward: 20 | 21 | - Zero-configuration execution of TypeScript files 22 | - Supports ES modules and CommonJS 23 | - Built-in source map support 24 | - Excellent performance 25 | 26 | ```bash 27 | 28 | Install tsx 29 | npm install -g tsx 30 | 31 | Execute TypeScript file 32 | tsx your-file.ts 33 | ``` 34 | 35 | With VSCode's debugging configuration, we can easily achieve advanced features such as breakpoint debugging and variable monitoring. In the next section, we will detail how to configure the debugging environment in VSCode. 36 | 37 | > 💡 Tip: VSCode's debugging feature is perfectly integrated with Node.js's debugger, allowing you to easily debug TypeScript code just like debugging JavaScript. 38 | 39 | ### tsx Debugging Steps 40 | 41 | 1. First, install the global dependency `tsx` 42 | 43 | ```bash 44 | npm i -g tsx 45 | ``` 46 | 47 | 2. Add the following debugging configuration to the project's `.vscode/launch.json` 48 | 49 | ```json 50 | { 51 | "version": "0.2.0", 52 | "configurations": [ 53 | { 54 | "type": "node", 55 | "request": "launch", 56 | "name": "TS Debugger", 57 | "runtimeExecutable": "tsx", 58 | "skipFiles": ["/**", "${workspaceFolder}/node_modules/**"], 59 | "program": "${file}" 60 | } 61 | ] 62 | } 63 | ``` 64 | 65 | 3. Debug test 66 | 67 | - Add a new file `debug.ts` 68 | - Add the following code to `debug.ts` 69 | 70 | ```ts 71 | function transformToKebabCase(input: string): string { 72 | return input.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase(); 73 | } 74 | 75 | function start() { 76 | const input = 'HelloWorld'; 77 | const result = transformToKebabCase(input); 78 | return result; 79 | } 80 | 81 | start(); 82 | ``` 83 | 84 | 4. Follow the steps in the image to debug 85 | 86 | ![](../assets/VSCode调试指南01.png) 87 | ![](../assets/VSCode调试指南02.png) 88 | 89 | ## Vue Debugging 90 | 91 | ### Debugging Steps 92 | 93 | 1. Add the following debugging configuration to the project's `.vscode/launch.json` 94 | 95 | ```json 96 | { 97 | "version": "0.2.0", 98 | "configurations": [ 99 | { 100 | "type": "chrome", 101 | "request": "launch", 102 | "name": "Vue Debugger", 103 | "url": "http://localhost:9527", 104 | "webRoot": "${workspaceFolder}" 105 | } 106 | ] 107 | } 108 | ``` 109 | 110 | > Keep the port number in the url consistent with the port number of the local development environment 111 | 112 | 2. Start the project locally 113 | 3. Test debugging 114 | 115 | - Open the page file `about/index.vue`, add a breakpoint in `onMounted` 116 | - Select `Vue Debugger`, click to start debugging - The browser enters the about page, and then automatically jumps back to VSCode 117 | ![](../assets/VSCode调试指南03.png) 118 | > Similarly, for example, when testing the logic executed after clicking a button, add the corresponding breakpoint in the click event, and then click on the page to trigger the debugging 119 | 120 | ### Breakpoint Types 121 | 122 | - Set breakpoints in component methods 123 | - Set breakpoints in lifecycle hooks 124 | - Set breakpoints in computed properties 125 | - Set breakpoints in watchers 126 | - Set breakpoints in route guards 127 | 128 | > Remember to enable source maps in the development environment for the best debugging experience: 129 | 130 | ```ts 131 | // vite.config.ts 132 | export default defineConfig({ 133 | build: { 134 | sourcemap: true 135 | } 136 | ``` 137 | -------------------------------------------------------------------------------- /src/tutorial/git.md: -------------------------------------------------------------------------------- 1 | # Git 2 | 3 | Download the Git tool from the [git](https://git-scm.com/) website. 4 | 5 | ## Initialize git 6 | 7 | - Set user information 8 | 9 | ```bash 10 | git config --global user.name "Soybean" 11 | git config --global user.email "soybeanjs@outlook.com" 12 | ``` 13 | 14 | - Generate SSH key 15 | 16 | ```bash 17 | ssh-keygen 18 | ``` 19 | 20 | > Press Enter during the process 21 | 22 | ::: tip 23 | Complete command: 24 | 25 | ```bash 26 | ssh-keygen -t rsa -C "soybeanjs@outlook.com" 27 | ``` 28 | 29 | > -t rsa indicates generating an RSA key, -C indicates a comment, followed by the comment content 30 | 31 | ::: 32 | 33 | - Upload git SSH key 34 | 35 | Find .ssh/id_rsa.pub in the user directory, open it, and copy the content to the SSH keys section of your git code platform. 36 | 37 | ## Common git commands 38 | 39 | - Sync the latest code from the main branch to the current branch 40 | 41 | ```bash 42 | git pull origin main 43 | git rebase origin/main 44 | ``` 45 | 46 | > If the current branch is the main branch, you can directly use `git pull --rebase` 47 | 48 | When encountering conflicts, resolve the conflicts and use the following command to continue the rebase 49 | 50 | ```bash 51 | git add . 52 | git rebase --continue 53 | ``` 54 | 55 | - Modify the date of the most recent commit 56 | 57 | ```bash 58 | git commit --amend --date="2022-07-29T23:45" 59 | ``` 60 | 61 | - Merge multiple commits 62 | 63 | ```bash 64 | git rebase -i HEAD~n # n is the number of commits to merge 65 | ``` 66 | 67 | - Cherry-pick a commit to the current branch 68 | 69 | ```bash 70 | git cherry-pick 71 | ``` 72 | 73 | > By default, it will keep the commit information. If you need to avoid creating a commit record, you can use `git cherry-pick -n ` 74 | -------------------------------------------------------------------------------- /src/tutorial/index.md: -------------------------------------------------------------------------------- 1 | # Tutorial 2 | 3 | In modern front-end development, mastering the installation and configuration of various development tools and environments is crucial. Whether it's the version control tool Git, the JavaScript runtime environment Node.js, or debugging tools, they are all indispensable parts of a front-end developer's daily work. This tutorial will detail how to install and configure these tools on a Mac system, helping you quickly set up an efficient front-end development environment. 4 | 5 | Through this tutorial, you will learn: 6 | 7 | - Installation and basic use of Git: including how to install Git, configure Git, and use basic Git commands. 8 | - Installation and configuration of Node.js: including how to install Node.js, configure npm, and use fnm to manage Node.js versions. 9 | - Use of debugging tools: including how to debug front-end code in VS Code, set breakpoints, view variables, etc. 10 | 11 | I hope that through this tutorial, you can smoothly set up a front-end development environment, improve development efficiency, and enjoy the fun of front-end development. 12 | -------------------------------------------------------------------------------- /src/tutorial/other.md: -------------------------------------------------------------------------------- 1 | # Other 2 | -------------------------------------------------------------------------------- /src/tutorial/software.md: -------------------------------------------------------------------------------- 1 | # Software installation tutorial 2 | 3 | - ## ApiPost 4 | 5 | Introduction: API debugging and mock tools. 6 | 7 | [Official Website](https://www.apipost.cn/download.html) 8 | [Download](https://www.apipost.cn/download.html) 9 | 10 | - ## Postman 11 | 12 | Introduction: API debugging and mock tools. 13 | 14 | [Official Website](https://www.postman.com/downloads/) 15 | [Download](https://www.postman.com/downloads/) 16 | 17 | - ## Charles 18 | 19 | Introduction: Packet Capture Tool 20 | 21 | [Official Website](https://www.charlesproxy.com/) 22 | [Download](https://www.charlesproxy.com/download/) 23 | 24 | - ## Fiddler 25 | 26 | Introduction: Packet Capture Tool 27 | 28 | [Official Website](https://www.telerik.com/fiddler) 29 | -------------------------------------------------------------------------------- /src/zh/cooperate/index.md: -------------------------------------------------------------------------------- 1 | # 合作事项 2 | 3 | 我们非常感谢大家对 [`SoybeanAdmin`](https://github.com/soybeanjs/soybean-admin) 的支持!为了进一步回馈社区,并助力企业和开发者实现个性化需求,我们现提供多种合作服务,期待与您携手共赢。 4 | 5 | ## 1、定制化管理后台开发 6 | 7 | 针对企业和开发者的特定业务需求,我们提供基于 [`SoybeanAdmin`](https://github.com/soybeanjs/soybean-admin) 的定制化管理后台开发服务。我们的团队具备丰富的行业经验,能够迅速理解并实现您的需求,打造高效、灵活且安全的定制化解决方案。 8 | 9 | - **定制开发**:我们将根据您的具体需求,提供从需求分析、UI设计到功能实现的全方位服务,确保项目高效交付。 10 | - **功能扩展**:在 [`SoybeanAdmin`](https://github.com/soybeanjs/soybean-admin) 基础上,扩展您所需的特定功能模块,提升管理后台的功能和用户体验。 11 | 12 | ## 2、企业外包服务 13 | 14 | 我们承接各类企业级外包项目,特别是在管理后台系统的开发、集成与运维方面。我们以精益求精的态度,确保项目的质量和进度,为您的业务提供强有力的技术支持。 15 | 16 | - **项目开发**:无论是全新的项目,还是现有系统的优化与集成,我们都将为您量身打造高效可靠的解决方案。 17 | - **系统集成与维护**:我们也提供基于 [`SoybeanAdmin`](https://github.com/soybeanjs/soybean-admin) 的系统集成与长期维护服务,确保您的系统稳定、安全地运行。 18 | 19 | ## 3、联系方式 20 | 21 | 如有合作意向或项目咨询,请通过以下方式与我们联系: 22 | 23 | - **Email**: [soybeanjs@outlook.com](mailto:soybeanjs@outlook.com) 24 | - **GitHub Issues**: 欢迎通过 [GitHub Issues](https://github.com/soybeanjs/soybean-admin/issues/new) 联系我们,进行初步的合作洽谈。 25 | - **商务合作微信**: honghuangdc 26 | 27 | 期待与您开展深入合作,共同推动 SoybeanAdmin 项目及其在更多领域的成功应用! 28 | -------------------------------------------------------------------------------- /src/zh/guide/cli/command.md: -------------------------------------------------------------------------------- 1 | # 命令 2 | 3 | ## cleanup 4 | 5 | 删除目录: node_modules, dist, 等 6 | 7 | ```bash 8 | sa cleanup 9 | ``` 10 | 11 | ## update-pkg 12 | 13 | 更新 package.json 依赖版本 14 | 15 | ```bash 16 | sa update-pkg 17 | ``` 18 | 19 | ## git-commit 20 | 21 | 生成符合 Conventional Commits 标准的提交信息 22 | 23 | ```bash 24 | sa git-commit 25 | ``` 26 | 27 | ## git-commit-verify 28 | 29 | 验证 git 提交信息,确保符合 Conventional Commits 标准 30 | 31 | ```bash 32 | sa git-commit-verify 33 | ``` 34 | 35 | ## changelog 36 | 37 | 生成 changelog 38 | 39 | ```bash 40 | sa changelog 41 | ``` 42 | 43 | ## release 44 | 45 | 发布,更新版本,生成 changelog,提交代码 46 | 47 | ```bash 48 | sa release 49 | ``` 50 | 51 | ## gen-route 52 | 53 | 生成路由 54 | 55 | ```bash 56 | sa gen-route 57 | ``` 58 | -------------------------------------------------------------------------------- /src/zh/guide/cli/git-hooks.md: -------------------------------------------------------------------------------- 1 | # Git Hooks 2 | 3 | ## 写在前面 4 | 5 | > 大部份用JS写的代码,都是习惯于用运行时去判断代码有没有问题 6 | > 7 | > 比如用JS开发对接后端是这么一个流程,等接口好了后,调接口,拿到数据,再想办法把数据塞到页面里面 8 | > 9 | > 如果说是非常简单的页面,这个流程看上去是没啥毛病,如果是稍微复杂点的,这种流程写出来的代码就成了💩山的地基了,后期各种问题的排查就很头痛了 10 | 11 | TypeScript是能写出高质量代码的一大利器,定义数据类型的过程就是在定义前端数据模型的过程,一旦数据模型确定了,关于数据模型的各种操作都可以用纯函数来实现, 然后,将数据结合响应式时,只需要把对应的纯函数引进来做个简单的二次封装即可,大部份人不适应TS的类型,主要是开发模式没有切换,可以尝试使用这个模式进行几段开发体验TypeScript的魅力,然后再决定是否移除 `git-hooks`。 12 | 13 | 使用 `git-hooks` 作提交前校验,不但有助于提升自己的代码水平、降低项目的维护成本,更有助于自己去接手他人的代码,在诸多好处下为数不多的坏处仅在于一小段时间的学习(SoybeanAdmin项目内的类型覆盖率100%,皆为最佳实践,也是您上手TypeScript的最佳时机)与适应,您可以尝试一小段时间(欢迎随时在交流群中与我们讨论)后再决定是否移除 `git-hooks`。 14 | 15 | ## 移除git-hooks 16 | 17 | ::: details 方式一:临时关闭校验 18 | 建议初期尽可能完全遵循完善的类型校验,仅在有需要时通过临时取消提交校验的方式略微跳过几次。 19 | 20 | ```shell 21 | git add . 22 | 23 | git commit -m "commit message" # [!code --] 24 | git commit -m "commit message" --no-verify # [!code ++] 25 | 26 | git push 27 | ``` 28 | 29 | ::: 30 | 31 | ::: details 方式二:永久关闭校验 32 | 33 | > [!CAUTION] 不推荐 34 | > 1、把 `package.json` 的 `simple-git-hooks` 里面的命令删掉 35 | > 36 | > 2、执行 `simple-git-hooks` 命令 37 | > 38 | > ::: 39 | -------------------------------------------------------------------------------- /src/zh/guide/cli/intro.md: -------------------------------------------------------------------------------- 1 | # 命令行 2 | 3 | ## 概述 4 | 5 | 项目中的 `sa` 命令行工具提供了一些常用的功能 6 | 7 | - `cleanup`: 删除目录: node_modules, dist, 等 8 | - `update-pkg`: 更新 package.json 依赖版本 9 | - `git-commit`: 生成符合 Conventional Commits 标准的提交信息 10 | - `git-commit-verify`: 验证 git 提交信息,确保符合 Conventional Commits 标准 11 | - `changelog`: 生成 changelog 12 | - `release`: 发布,更新版本,生成 changelog,提交代码 13 | - `gen-route`: 生成路由 14 | 15 | > `sa` 命令是由 `packages/scripts` 提供 16 | -------------------------------------------------------------------------------- /src/zh/guide/icon/intro.md: -------------------------------------------------------------------------------- 1 | # 系统图标 2 | 3 | ## iconify 图标渲染原理 4 | 5 | 基于 iconify 的 svg 的 json 数据,通过 unplugin-icons 插件,将 svg 数据转换成 vue 组件 6 | 7 | - [unplugin-icons](https://github.com/antfu/unplugin-icons) 8 | - [iconify](https://github.com/iconify/iconify) 9 | - [Journey with Icons Continues](https://antfu.me/posts/journey-with-icons-continues) 10 | 11 | ## 本地 svg 图标渲染原理 12 | 13 | 通过 `unplugin-icons` 插件 与 `vite-plugin-svg-icons` 插件,将本地 svg 文件转换成 vue 组件 14 | 15 | > 本地 svg 图标需要放在 src/assets/svg-icon 目录下 16 | 17 | ## 相关配置 18 | 19 | **.env 配置文件** 20 | 21 | - VITE_ICON_PREFIX: iconify 图标前缀 22 | - VITE_ICON_LOCAL_PREFIX: 本地 svg 图标前缀,格式遵循 {VITE_ICON_PREFIX}-{local icon name} 23 | 24 | ## 请注意 25 | 26 | > 根据 svg 图标渲染原理,已被转换为静态资源,这意味着一旦 svg 文件被加载并转换为组件,它们将成为您项目的一部分,不会自动检测和更新源文件的更改。因此,如果您修改了 svg 文件并希望在项目中看到更改的效果,您需要重新启动项目。 27 | -------------------------------------------------------------------------------- /src/zh/guide/icon/usage.md: -------------------------------------------------------------------------------- 1 | # 图标教程 2 | 3 | ## 一、静态用法:直接写在 template 中 4 | 5 | - **iconify** 6 | 7 | - 安装 vscode 智能提示的插件: [Iconify IntelliSense](https://marketplace.visualstudio.com/items?itemName=antfu.iconify) 8 | 9 | - 找图标:网址 [https://icones.js.org/](https://icones.js.org/) 或者 vscode 安装 - [Icônes](https://marketplace.visualstudio.com/items?itemName=afzalsayed96.icones) 10 | 11 | - 确定图标名字:找到图标后复制名字 如:'mdi:emoticon' 或者 'mdi-emoticon',则对应的 vue 的 template 为 12 | 13 | ```html 14 |
15 | 16 | 17 |
18 | ``` 19 | 20 | ::: tip 提示 21 | 'icon-' 为预设的前缀, 在.env 里面设置变量 VITE_ICON_PREFIX 22 | ::: 23 | 24 | - 设置样式:同 html 标签一样直接应用 style 属性或者 class 属性; 通过设置 color 和 font-size 属性设置对应的颜色和大小 25 | 26 | - **本地 svg 图标** 27 | 28 | - 在 src/assets/svg-icon 目录下选择一个 svg,取它的文件名,例如: 'custom-icon.svg' 29 | 30 | - 则对应的 vue 的 template 为 31 | 32 | ```html 33 | 34 | ``` 35 | 36 | ::: tip 提示 37 | 'icon-local' 为预设的前缀, 在.env 里面设置变量 VITE_ICON_LOCAL_PREFIX 38 | ::: 39 | 40 | ## 二、动态渲染: 根据图标名称渲染对应图标 41 | 42 | - **iconify** 43 | 44 | - 确定图标名字,如:'mdi-emoticon' 45 | 46 | - 动态渲染 47 | 48 | ```html 49 | 50 | ``` 51 | 52 | - 多个图标动态渲染 53 | 54 | ```html 55 | 56 | ``` 57 | 58 | - **本地 svg 图标** 59 | 60 | - 确定 svg 文件名,例如: 'custom-icon.svg' 61 | 62 | - 动态渲染 63 | 64 | ```html 65 | 66 | ``` 67 | 68 | ::: tip 提示 69 | svg-icon 为全局组件,已经注册过了,直接在 template 中应用,icon 属性为 iconify 图标名称, local-icon 为本地 svg 图标的文件名 70 | ::: 71 | 72 | ## 三、通过 render 函数渲染: 适用于 NaiveUI 的图标渲染 73 | 74 | - 确定图标名字,如:iconify: **'mdi-emoticon'**, 或者本地 svg 图标 'custom-icon.svg' 75 | 76 | - 使用 `useSvgIcon` 77 | 78 | ```typescript 79 | import { useSvgIcon } from '@/hooks/common/icon'; 80 | 81 | const { SvgIconVNode } = useSvgIcon(); 82 | 83 | SvgIconVNode({ icon: 'ant-design:close-outlined', fontSize: 18 }); // iconify 84 | 85 | SvgIconVNode({ localIcon: 'custom-icon' }); // 本地svg图标 86 | ``` 87 | 88 | ## 四、离线加载:添加指定的离线 iconify 图标集合 89 | 90 | - **使用步骤** 91 | 92 | - 安装依赖 93 | 94 | ```bash 95 | ## 包含图标组件数据 96 | pnpm add @iconify/vue 97 | 98 | ## 包含离线图标数据 99 | pnpm add @iconify/json 100 | ``` 101 | 102 | ::: tip 提示 103 | 项目中已经引入相关依赖,直接在组件内引用即可 104 | ::: 105 | 106 | - 准备离线图标集合数据 107 | 108 | 如:我们需要在项目中使用 `Ant Design` 图标库,则可以按照以下方式引入离线图标 109 | 110 | ```typescript 111 | import AntDesign from '@iconify/json/json/ant-design.json'; 112 | ``` 113 | 114 | - 在页面中使用 `addCollection` 方法添加离线图标 115 | 116 | ```typescript 117 | import { addCollection } from '@iconify/vue'; 118 | ``` 119 | 120 | - **代码示例** 121 | 122 | ```vue 123 | 129 | 130 | 133 | ``` 134 | -------------------------------------------------------------------------------- /src/zh/guide/request/backend.md: -------------------------------------------------------------------------------- 1 | # 对接后端 2 | 3 | ## 确认后端的返回结果的数据结构类型 4 | 5 | 默认如下: 6 | 7 | `App.Service.Response`: 8 | 9 | ```ts 10 | type Response = { 11 | /** 业务状态码 */ 12 | code: string; 13 | /** 响应信息 */ 14 | msg: string; 15 | /** 响应数据 */ 16 | data: T; 17 | }; 18 | ``` 19 | 20 | > 请根据自己的后端返回数据类型进行修改 21 | 22 | ## 配置后端请求成功的 code 23 | 24 | 更改 `.env` 的配置 `VITE_SERVICE_SUCCESS_CODE` 25 | 26 | > 环境文件加载的配置为字符串类型,如果后端返回的 code 为数字类型,对比时需要转换同一类型再比较。 27 | 28 | ## 配置其他后端请求相关的 code 29 | 30 | 参考请求介绍中的[配置项](./intro.md#请求相关配置介绍) 31 | -------------------------------------------------------------------------------- /src/zh/guide/request/intro.md: -------------------------------------------------------------------------------- 1 | # 请求 2 | 3 | ## 多个请求环境 4 | 5 | 开发项目经常会用到多个请求环境地址:如用户开发环境的后台地址、用于测试环境的后台地址、用于预生产环境的后台地址和用于生产环境的地址等 6 | 7 | 在环境文件中配置多个请求地址,然后在请求函数中根据环境变量来判断使用哪个请求地址 8 | 9 | 目前项目的环境文件有 10 | 11 | `.env.prod`, `.env.test` 12 | 13 | ## 请求相关配置介绍 14 | 15 | `.env` 文件中的配置项 16 | 17 | - `VITE_SERVICE_SUCCESS_CODE`: 后端请求成功的 code 18 | - `VITE_SERVICE_LOGOUT_CODES`: 后端请求失败并需要用户退出登录的 code,多个 code 用 `,` 分隔 19 | - `VITE_SERVICE_MODAL_LOGOUT_CODES`: 后端请求失败并需要用户退出登录的 code(通过弹窗形式提醒),多个 code 用 `,` 分隔 20 | - `VITE_SERVICE_EXPIRED_TOKEN_CODES`: 后端请求失败并刷新 token 的 code,多个 code 用 `,` 分隔 21 | 22 | `.env.test` 或 `.env.prod` 文件中的配置项 23 | 24 | - `VITE_SERVICE_BASE_URL`: 请求的基础地址 25 | - `VITE_OTHER_SERVICE_BASE_URL`: 其他请求的基础地址 26 | 27 | ### 请求函数介绍 28 | 29 | 1. **请求函数:createRequest 和 createFlatRequest** 30 | 31 | `createRequest`: 返回的请求实例直接返回 Axios 响应数据(可转换) 32 | 33 | `createFlatRequest`: 返回的请求实例会将响应数据和错误信息包装在一个扁平的对象中,以统一的格式返回结果。 34 | 35 | 2. **createRequest/createFlatRequest 参数** 36 | 37 | `axiosConfig`: axios 配置,传入 baseUrl,定义一些其他配置:如:请求的超时时间、请求头等 38 | 39 | `options`: 配置入参校验等逻辑(见下方的`RequestOption`) 40 | 41 | ```ts 42 | interface RequestOption { 43 | /** 44 | * 请求发送之前执行,用来修改请求配置,例如:添加请求头 token 45 | */ 46 | onRequest: (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig | Promise; 47 | /** 48 | * 判断后端响应是否成功,通过对比后端返回的 code 来判断 49 | */ 50 | isBackendSuccess: (response: AxiosResponse) => boolean; 51 | /** 52 | * 后端请求在业务上表示失败时调用的异步函数,例如:处理 token 过期 53 | */ 54 | onBackendFail: ( 55 | response: AxiosResponse, 56 | instance: AxiosInstance 57 | ) => Promise | Promise; 58 | /** 59 | * 当 responseType 为 json 时,转换后端响应的数据 60 | */ 61 | transformBackendResponse(response: AxiosResponse): any | Promise; 62 | /** 63 | * 当请求失败时调用的函数(包括请求失败和后端业务上的失败请求),例如:处理错误信息 64 | */ 65 | onError: (error: AxiosError) => void | Promise; 66 | } 67 | ``` 68 | -------------------------------------------------------------------------------- /src/zh/guide/request/proxy.md: -------------------------------------------------------------------------------- 1 | # 代理 2 | 3 | ## 概述 4 | 5 | 项目中通过函数 `createServiceConfig` 创建服务的基础路径和匹配代理的字符串 6 | 7 | ::: tip 代码位置 8 | @/utils/service.ts 9 | ::: 10 | 11 | 然后在函数 `createViteProxy` 中根据上述获取的配置创建代理 12 | 13 | ## 开启/关闭 14 | 15 | 通过 `env` 文件的 `VITE_HTTP_PROXY` 开启或关闭代理 16 | 17 | ::: tip 代码位置 18 | ~.env 19 | ::: 20 | 21 | 在 `@/service/request/index.ts` 里,通过给 `getServiceBaseURL` 的第二个参数传入根据代码运行环境与 `VITE_HTTP_PROXY` 共同判断出的 `isHttpProxy` 来决定该URL是否需要处理代理,您可以在这里通过传入不同的参数解构获取所需的请求URL 22 | 23 | ``` 24 | const isHttpProxy = import.meta.env.DEV && import.meta.env.VITE_HTTP_PROXY === 'Y'; 25 | const { baseURL } = getServiceBaseURL(import.meta.env, isHttpProxy); 26 | const { otherBaseURL } = getServiceBaseURL(import.meta.env, false); 27 | ``` 28 | 29 | ## 原理 30 | 31 | SoybeanAdmin 为了简化配置代理的过程,特意将匹配字符串设定为 `/proxy-default/` (其他请求 `proxy-{key}`),这样在配置代理时,只需要将请求的地址中的 `/proxy-default/` 替换为实际的请求地址即可,这样就可以实现代理的配置。 32 | 33 | ```ts 34 | { 35 | '/proxy-default': { 36 | target: 'https://default.com', 37 | changeOrigin: true, 38 | rewrite: (path) => path.replace(/^\/proxy-default/, ''), 39 | }, 40 | '/proxy-demo': { 41 | target: 'https://demo.com', 42 | changeOrigin: true, 43 | rewrite: (path) => path.replace(/^\/proxy-demo/, ''), 44 | } 45 | } 46 | ``` 47 | 48 | ### 注意 49 | 50 | 这里介绍2种容易混淆的配置: 51 | 52 | 1. 假设一个请求的路径为 `https://example.com/api/user`, 大多数会这样配置代理 53 | 54 | ```ts 55 | 56 | { 57 | '/api': { 58 | target: 'https://example.com', 59 | changeOrigin: true, 60 | } 61 | } 62 | 63 | ``` 64 | 65 | > 这时候 `/api` 既是作为匹配字符串,也是作为请求的路径。所以这里没有 `rewrite` 的配置,因为请求的路径和匹配字符串是一样的。 66 | 67 | 2. 假设一个请求的路径为 `https://example.com/user`, 但是配置代理时,匹配字符串为 `/api` 68 | 69 | ```ts 70 | 71 | { 72 | '/api': { 73 | target: 'https://example.com', 74 | changeOrigin: true, 75 | rewrite: (path) => path.replace(/^\/api/, ''), 76 | } 77 | } 78 | 79 | ``` 80 | 81 | > 这时候 `/api` 是作为匹配字符串,`user` 是作为请求的路径。所以这里需要配置 `rewrite`,将匹配字符串去掉。 82 | 83 | 在 SoybeanAdmin 中,使用的是第二种包含`rewrite`配置,因为为了支持多个服务的代理,同时避免多个服务包含相同的`/api`路径,所以SoybeanAdmin 选择创建了类似 `/proxy-*` 作为匹配字符串和请求的路径分开。避免冲突。 84 | -------------------------------------------------------------------------------- /src/zh/guide/router/cache.md: -------------------------------------------------------------------------------- 1 | # 路由缓存 2 | 3 | ## 原理 4 | 5 | 路由缓存是通过 `vue-router` 的 `keep-alive` 组件实现的。`keep-alive` 组件会缓存组件的状态,当组件再次被访问时,会直接从缓存中取出组件,而不是重新创建一个新的组件。 6 | 由于 `keep-alive` 组件使用的是组件的 `name` 属性来作为缓存的 key,项目中的页面组件都已经通过 `@elegant-router/vue` 插件自动注入了 `name` 属性,所以只需要在路由数据中设置 `meta` 属性的 `keepAlive` 字段即可。 7 | `vue-router` 的多级路由缓存是有问题的,因次项目中的路由数据都被转换成了二级路由,保证每个路由都能正常缓存。 8 | 9 | ## 用法 10 | 11 | 通过设置路由数据的 `meta` 属性中的 `keepAlive` 字段,可以控制路由是否缓存。 12 | 13 | ```ts 14 | { 15 | name: 'about', 16 | path: '/about', 17 | component: 'layout.base$view.about', 18 | meta: { 19 | title: 'about', 20 | keepAlive: true 21 | } 22 | } 23 | ``` 24 | -------------------------------------------------------------------------------- /src/zh/guide/router/component.md: -------------------------------------------------------------------------------- 1 | # 路由组件 2 | 3 | ## 布局组件 4 | 5 | - **layout.base**: 具有公共部分的布局,如全局头部、侧边栏、底部等 6 | 7 | - **layout.blank**: 空白布局 8 | 9 | ## 页面组件 10 | 11 | - **view.[RouteKey]**: 页面组件 12 | > 例如:`view.home`, `view.multi-menu_first_child` 13 | 14 | ## 布局和页面的混合组件 15 | 16 | - **layout.base$view.[RouteKey]**: 布局和页面的混合组件 17 | > 例如:`layout.base$view.home`, `layout.base$view.multi-menu_first_child` 18 | 19 | ::: tip 提示 20 | 该类型组件表示单级路由 21 | ::: 22 | -------------------------------------------------------------------------------- /src/zh/guide/router/create.md: -------------------------------------------------------------------------------- 1 | # 路由创建 2 | 3 | ## 命令创建 4 | 5 | 通过执行 `pnpm gen-route` 命令,可以快速创建路由文件 6 | 7 | **路由名称的命名规则** 8 | 9 | - 一级路由: `demo`, `demo-page`, `route1` 10 | > 名称为小写加连字符`-`的形式 11 | - 二级路由: `demo2_child`, `demo2-page_child`, `route2_child` 12 | > 路由的层级用下划线`_`分隔,两边仍然遵守一级路由的命名规则 13 | - 三级及三级以上路由: `demo3_child_child`, `demo3-page_child_child_child` 14 | 15 | ## 手动创建 16 | 17 | **手动创建路由文件,需要遵循以下规则:** 18 | 每层路由的文件夹名称为路由名称,文件夹下的 `index.vue` 或者 `[id].vue` 为路由组件 19 | -------------------------------------------------------------------------------- /src/zh/guide/router/dynamic.md: -------------------------------------------------------------------------------- 1 | # 路由权限 2 | 3 | ## 指引 4 | 5 | ### 固定路由(无需权限即可进入的路由) 6 | 7 | 在静态路由模式下,路由权限是通过 `meta.constant` 来控制的, `constant` 为 `true` 的路由无需登录即可访问; 8 |
9 | 而在动态路由模式下,无需登录即可访问的路由需要在 `fetchGetConstantRoutes` 接口中返回,也就是说,在 `fetchGetUserRoutes` 中返回`constant` 为 `true` 的路由是不会生效的,仍需登录才能访问; 10 | 11 | ### 权限路由 12 | 13 | 在静态路由模式下默认的路由都需要登录才能访问,需要配置权限可以添加 `meta.roles` 字段,该字段类型为 `string[]` ,在 `UserInfo` 中配置,若能匹配到该角色则允许进入,否则不允许进入,匹配发生在前置路由守卫阶段; 14 |
15 | 在动态路由模式下仍可沿用 `meta.roles` ,但是一般可直接让后端根据角色权限控制路由表的返回,不返回无权的路由即可; 16 | 17 | ## 动态路由 18 | 19 | 修改路由的来源,静态路由的路由表来源于 `./src/router/elegant/routes.ts` ,动态路由的路由表来源于 `fetchGetConstantRoutes` 与 `fetchGetUserRoutes` 接口。 20 | 21 | > [!WARNING] 注意 22 | > 接口返回的路由表的类型必须与前端静态的路由表类型一致,在尝试修改前建议先熟悉本项目的特色路由插件与路由表结构 23 | 24 | ### 开启/关闭 25 | 26 | 通过在 `env` 文件中配置 `VITE_AUTH_ROUTE_MODE` 变量来开启/关闭动态路由模式。 27 | 28 | ::: tip 代码位置 29 | .env 30 | ::: 31 | 32 | ```dotenv:line-numbers=14 33 | # auth route mode: static | dynamic 34 | VITE_AUTH_ROUTE_MODE=dynamic 35 | ``` 36 | -------------------------------------------------------------------------------- /src/zh/guide/router/guard.md: -------------------------------------------------------------------------------- 1 | # 路由守卫 2 | 3 | ## 路由守卫流程图 4 | 5 | ![](../../../assets/router-guard-flow.png) 6 | 7 | [高清PDF](/router-guard-flow.pdf) 8 | -------------------------------------------------------------------------------- /src/zh/guide/router/intro.md: -------------------------------------------------------------------------------- 1 | # 系统路由 2 | 3 | 本系统的路由基于插件 [Elegant Router](https://github.com/soybeanjs/elegant-router),详细用法请查看插件文档。 4 | 5 | ::: danger 警告 6 | 由于使用了 `` 标签支持页面过渡动画,所以在页面的 `.vue` 文件的 `template` 中只能有一个根元素,注释和纯文本都不行,必须只有一个根标签元素。 7 | 相关文档: [Transition | Vue.js (vuejs.org)](https://cn.vuejs.org/guide/built-ins/transition.html#the-transition-component) 8 | ::: 9 | 10 | ## 自动生成 11 | 12 | 启动项目后,插件会自动生成 src/router/elegant 目录,该目录下的文件为自动生成的路由导入、路由定义和路由转换的文件 13 | 14 | > [!IMPORTANT] 15 | > 路由是文件的副产物,所以删除路由的操作是删除文件,路由会跟随文件一起消失。
路由支持修改的内容只有 `component` 和 `meta` 信息,自动生成的操作不会影响到这两个属性。 16 | 17 | ## 配置属性 18 | 19 | ### 1. type RouteKey 20 | 21 | **解释:** 22 | 23 | 联合类型 RouteKey 声明所有的路由 key,方便统一管理路由, 该类型由插件 [Elegant Router](https://github.com/soybeanjs/elegant-router) 根据 views 下面的页面文件自动生成 24 | 25 | ::: tip 代码位置 26 | src/typings/elegant-router.d.ts 27 | ::: 28 | 29 | ### 2. type RoutePath 30 | 31 | **解释:** 32 | 33 | 路由的路径 path,该类型与 RouteKey 一一对应 34 | 35 | ### 3. type RouteMeta 36 | 37 | ```typescript 38 | // 路由元信息接口 39 | interface RouteMeta { 40 | /** 41 | * 路由标题 42 | * 43 | * 可用于文档标题中 44 | */ 45 | title: string; 46 | /** 47 | * 路由的国际化键值 48 | * 49 | * 如果设置,将用于i18n,此时title将被忽略 50 | */ 51 | i18nKey?: App.I18n.I18nKey; 52 | /** 53 | * 路由的角色列表 54 | * 55 | * 当前用户拥有至少一个角色时,允许访问该路由,角色列表为空时,表示无需权限 56 | */ 57 | roles?: string[]; 58 | /** 是否缓存该路由 */ 59 | keepAlive?: boolean; 60 | /** 61 | * 是否为常量路由 62 | * 63 | * 无需登录,并且该路由在前端定义 64 | */ 65 | constant?: boolean; 66 | /** 67 | * Iconify 图标 68 | * 69 | * 可用于菜单或面包屑中 70 | */ 71 | icon?: string; 72 | /** 73 | * 本地图标 74 | * 75 | * 存在于 "src/assets/svg-icon" 目录下,如果设置,将忽略icon属性 76 | */ 77 | localIcon?: string; 78 | /** 路由排序顺序 */ 79 | order?: number; 80 | /** 路由的外部链接 */ 81 | href?: string; 82 | /** 是否在菜单中隐藏该路由 */ 83 | hideInMenu?: boolean; 84 | /** 85 | * 进入该路由时激活的菜单键 86 | * 87 | * 该路由不在菜单中 88 | * 89 | * @example 90 | * 假设路由是"user_detail",如果设置为"user_list",则会激活"用户列表"菜单项 91 | */ 92 | activeMenu?: import('@elegant-router/types').RouteKey; 93 | /** 默认情况下,相同路径的路由会共享一个标签页,若设置为true,则使用多个标签页 */ 94 | multiTab?: boolean; 95 | /** 若设置,路由将在标签页中固定显示,其值表示固定标签页的顺序(首页是特殊的,它将自动保持fixed) */ 96 | fixedIndexInTab?: number; 97 | /** 路由查询参数,如果设置的话,点击菜单进入该路由时会自动携带的query参数 */ 98 | query?: { key: string; value: string }[] | null; 99 | } 100 | ``` 101 | 102 | ::: tip 提示 103 | icon 图标值从这里获取:[https://icones.js.org/](https://icones.js.org/) 104 | ::: 105 | 106 | ## 注意 107 | 108 | 如果在 views 中创建了一个路由页面,在别的地方调用但不在菜单那边显示,那么需要设置 meta 中的 `hideInMenu: true` 109 | 110 | ```typescript 111 | { 112 | name: '403', 113 | path: '/403', 114 | component: 'layout.blank$view.403', 115 | meta: { 116 | title: '403', 117 | i18nKey: 'route.403', 118 | hideInMenu: true 119 | } 120 | } 121 | ``` 122 | -------------------------------------------------------------------------------- /src/zh/guide/router/push.md: -------------------------------------------------------------------------------- 1 | # 路由跳转 2 | 3 | 项目内可使用普通的 `router.push` 等常规方式进行路由跳转,亦可使用项目内提供的 `useRouterPush` 进行跳转(推荐),本篇主要介绍 `useRouterPush` 。 4 | 5 | ## 介绍 6 | 7 | 该hook对 `router.push` 进行二次封装,主要目的是代替 `router.push` 使用,通过该hook可更便捷得进行跳转, `useRouterPush` 返回一个对象,包含以下属性和方法: 8 | 9 | - routerPush: Vue Router 的 push 方法。 10 | - routerBack: Vue Router 的 back 方法。 11 | - routerPushByKey: 根据路由key跳转的方法。 12 | - toLogin: 跳转到登录页的方法。 13 | - toggleLoginModule: 切换登录模块的方法。 14 | - redirectFromLogin: 从登录页重定向的方法。 15 | 16 | ::: warning 注意 17 | 在 `setup` 外使用时需要给 `useRouterPush` 传入 `false`。 18 | ::: 19 | 20 | ## 详细说明 21 | 22 | `routerPush` 和 `routerBack` 都是原有属性,就不再赘述了,这里主要介绍一下后面几个。 23 | 24 | ### routerPushByKey 25 | 26 | 这里的 `key` 指的是路由的 `name` 属性,例如某个路由的配置为: 27 | 28 | ```json 29 | { 30 | "name": "soybean", 31 | "path": "/soybean-page", 32 | "component": "layout.base$view.soybean-page" 33 | } 34 | ``` 35 | 36 | 则跳转到该路由的代码为: 37 | 38 | ```ts 39 | import { useRouterPush } from '@/hooks/common/router'; 40 | 41 | const { routerPushByKey } = useRouterPush(); 42 | 43 | routerPushByKey('soybean'); 44 | ``` 45 | 46 | 它支持传入可选参数 `query` 或是 `params`。 47 | 48 | ### toLogin 49 | 50 | 字面意思,快速跳转到登录页,注意跳转前要清除登录信息,否则在路由守卫一样会被拦截回首页的。 51 | 52 | ### toggleLoginModule 53 | 54 | 该方法传入参数类型为 55 | 56 | ```ts 57 | /** 58 | * The login module 59 | * 60 | * - pwd-login: password login 61 | * - code-login: phone code login 62 | * - register: register 63 | * - reset-pwd: reset password 64 | * - bind-wechat: bind wechat 65 | */ 66 | type LoginModule = 'pwd-login' | 'code-login' | 'register' | 'reset-pwd' | 'bind-wechat'; 67 | ``` 68 | 69 | 作用是根据传入的 `LoginModule` 改变登录页挂载的登录功能模块,您可以自行删除或是扩展更多的模块,只需要确保类型是正确的就可以了。 70 | 71 | ### redirectFromLogin 72 | 73 | 在登录成功选用,相比手动push到首页,它更见名知意。 74 | 它会根据登录页的 `redirect` 查询参数来决定重定向到哪个路由,如果没有 `redirect` 参数,则默认跳转到首页。 75 | 76 | ## 使用 77 | 78 | ```vue 79 | 80 | 85 | 86 | 91 | ``` 92 | 93 | ```ts 94 | 95 | import { useRouterPush } from '@/hooks/common/router'; 96 | 97 | // 注意传入false 98 | const { routerPushByKey } = useRouterPush(false); 99 | 100 | function backToRoot() { 101 | routerPushByKey('root') 102 | } 103 | ``` 104 | -------------------------------------------------------------------------------- /src/zh/guide/sync.md: -------------------------------------------------------------------------------- 1 | # 同步代码 2 | 3 | 1. 在自己的仓库里面新增`soybean-admin`的git地址 4 | 5 | ```bash 6 | git remote add otherOrigin https://github.com/soybeanjs/soybean-admin.git 7 | ``` 8 | 9 | 2. 拉取代码 10 | 11 | ```bash 12 | git fetch otherOrigin 13 | ``` 14 | 15 | 3. 通过`cherry-pick`挑选需要更新的git提交 16 | 17 | ```bash 18 | git cherry-pick [commit id] 19 | ``` 20 | 21 | 4. 代码有冲突时, 先解决冲突,然后执行下面命令,再执行`vim`保存 22 | 23 | ```bash 24 | git cherry-pick --continue 25 | ``` 26 | 27 | > `vim`保存操作: `esc`,`:`, `wq`, `enter`回车 28 | -------------------------------------------------------------------------------- /src/zh/guide/theme/config.md: -------------------------------------------------------------------------------- 1 | # 主题配置 2 | 3 | ## 类型定义 4 | 5 | 见 App.Theme.ThemeSetting 6 | 7 | ::: tip 代码位置 8 | src/typings/app.d.ts 9 | ::: 10 | 11 | ## 初始化配置 12 | 13 | ```ts 14 | export const themeSettings: App.Theme.ThemeSetting = { 15 | //默认配置 16 | }; 17 | ``` 18 | 19 | ::: tip 代码位置 20 | src/theme/settings.ts 21 | ::: 22 | 23 | ## 配置覆盖更新 24 | 25 | 当发布新的版本时,可以通过配置覆盖更新的方式,来更新主题配置 26 | 27 | ```ts 28 | export const overrideThemeSettings: Partial = { 29 | //覆盖配置 30 | }; 31 | ``` 32 | 33 | ::: tip 代码位置 34 | src/theme/settings.ts 35 | ::: 36 | 37 | ## 环境说明 38 | 39 | - 当项目处于`开发模式`时,主题配置不会被缓存,可以通过更新 `src/theme/settings.ts` 中的 `themeSettings` 来更新主题配置 40 | 41 | > 开发阶段为了能够实时看到主题配置的变化,所以不会缓存主题配置 42 | 43 | - 当项目处于`生产模式`时,主题配置会被缓存到 localStorage 中 44 | > 每次发布新版本,可以通过更新 `src/theme/settings.ts` 中的 `overrideThemeSettings` 来覆盖更新主题配置 45 | -------------------------------------------------------------------------------- /src/zh/guide/theme/intro.md: -------------------------------------------------------------------------------- 1 | # 系统主题 2 | 3 | 系统主题的实现分为两个部分,一部分是组件库的主题配置,另一部分是 UnoCSS 的主题配置。为了统一两个部分的主题配置,在这之上维护了一些主题配置,通过这些主题配置分别控制组件库和 UnoCSS 的主题配置。 4 | 5 | ## 原理 6 | 7 | - 定义一些主题配置的变量,包括各种主题颜色,布局的参数配置等 8 | - 通过这些配置产出符合组件库的主题变量 9 | - 通过这些配置产出一些主题 tokens 并衍生出对应的 css 变量,再将这些 css 变量传递给 UnoCSS 10 | -------------------------------------------------------------------------------- /src/zh/guide/theme/loading.md: -------------------------------------------------------------------------------- 1 | # 系统加载 2 | 3 | ![](../../../assets/loading01.png) 4 | 5 | ## 样式 6 | 7 | - 系统初始化时的加载样式通过html代码方式实现 8 | 9 | ::: tip 组件位置 10 | src/plugins/loading.ts 11 | ::: 12 | 13 | - 系统的 Logo 使用 SystemLogo 组件实现 14 | 15 | [系统Logo](./logo.md) 16 | 17 | ## 渲染原理 18 | 19 | 创建 setupLoading 函数, 它的主要功能是设置页面加载时的动画效果。 20 | 这个加载动画包括一个系统Logo、旋转的点阵动画和标题文字,并且所有元素的颜色均基于从本地存储获取的主题色 themeColor 动态生成。 21 | 并且在DOM中查找ID为app的元素作为加载动画的挂载点, 如果找到了这个元素,则将其内部HTML替换为刚刚构建的加载动画HTML结构 22 | 23 | ```ts 24 | export function setupLoading() { 25 | const themeColor = localStg.get('themeColor') || '#DB5A6B'; 26 | 27 | const { r, g, b } = getRgbOfColor(themeColor); 28 | 29 | const primaryColor = `--primary-color: ${r} ${g} ${b}`; 30 | 31 | const loadingClasses = [ 32 | 'left-0 top-0', 33 | 'left-0 bottom-0 animate-delay-500', 34 | 'right-0 top-0 animate-delay-1000', 35 | 'right-0 bottom-0 animate-delay-1500' 36 | ]; 37 | 38 | const logoWithClass = systemLogo.replace(' { 42 | return `
`; 43 | }) 44 | .join('\n'); 45 | 46 | const loading = ` 47 |
48 | ${logoWithClass} 49 |
50 |
51 | ${dot} 52 |
53 |
54 |

${$t('system.title')}

55 |
`; 56 | 57 | const app = document.getElementById('app'); 58 | 59 | if (app) { 60 | app.innerHTML = loading; 61 | } 62 | } 63 | ``` 64 | 65 | ::: tip 代码位置 66 | src/plugins/loading.ts 67 | ::: 68 | 69 | 最后要将 setupLoading 函数注册到 main.ts 中 70 | 71 | ```typescript 72 | async function setupApp() { 73 | setupLoading(); 74 | app.mount('#app'); 75 | } 76 | ``` 77 | -------------------------------------------------------------------------------- /src/zh/guide/theme/logo.md: -------------------------------------------------------------------------------- 1 | # 概述 2 | 3 | 系统Logo 由组件 `SystemLogo` 来实现,它是一个 `SFC` 组件,可以通过 `props` 来设置它的样式。 4 | 5 | ```vue 6 | 9 | 10 | 13 | 14 | 15 | ``` 16 | 17 | ::: tip 代码位置 18 | src/components/common/system-logo.vue 19 | ::: 20 | 21 | > 具体实现原理参考 [本地Icon](/zh/guide/icon/intro) 22 | -------------------------------------------------------------------------------- /src/zh/guide/theme/tokens.md: -------------------------------------------------------------------------------- 1 | # 主题 tokens 2 | 3 | ## 类型定义 4 | 5 | ```ts 6 | type ThemeToken = { 7 | colors: ThemeTokenColor; 8 | boxShadow: { 9 | header: string; 10 | sider: string; 11 | tab: string; 12 | }; 13 | }; 14 | ``` 15 | 16 | ::: tip 代码位置 17 | src/typings/app.d.ts 18 | ::: 19 | 20 | ## 基于 tokens 的 css 变量 21 | 22 | 初始化时会在 html 上生成一些 css 变量,这些 css 变量是基于主题 tokens 产出的 23 | 24 | ```ts 25 | /** Theme vars */ 26 | export const themeVars: App.Theme.ThemeToken = { 27 | colors: { 28 | ...colorPaletteVars, 29 | nprogress: 'rgb(var(--nprogress-color))', 30 | container: 'rgb(var(--container-bg-color))', 31 | layout: 'rgb(var(--layout-bg-color))', 32 | inverted: 'rgb(var(--inverted-bg-color))', 33 | base_text: 'rgb(var(--base-text-color))' 34 | }, 35 | boxShadow: { 36 | header: 'var(--header-box-shadow)', 37 | sider: 'var(--sider-box-shadow)', 38 | tab: 'var(--tab-box-shadow)' 39 | } 40 | }; 41 | ``` 42 | 43 | ::: tip 代码位置 44 | src/theme/vars.ts 45 | ::: 46 | 47 | ## tokens 初始化 48 | 49 | ```ts 50 | /** 51 | * Create theme token 52 | * 53 | * @param colors Theme colors 54 | */ 55 | export function createThemeToken(colors: App.Theme.ThemeColor) { 56 | const paletteColors = createThemePaletteColors(colors); 57 | 58 | const themeTokens: App.Theme.ThemeToken = { 59 | colors: { 60 | ...paletteColors, 61 | nprogress: paletteColors.primary, 62 | container: 'rgb(255, 255, 255)', 63 | layout: 'rgb(247, 250, 252)', 64 | inverted: 'rgb(0, 20, 40)', 65 | base_text: 'rgb(31, 31, 31)' 66 | }, 67 | boxShadow: { 68 | header: '0 1px 2px rgb(0, 21, 41, 0.08)', 69 | sider: '2px 0 8px 0 rgb(29, 35, 41, 0.05)', 70 | tab: '0 1px 2px rgb(0, 21, 41, 0.08)' 71 | } 72 | }; 73 | 74 | const darkThemeTokens: App.Theme.ThemeToken = { 75 | colors: { 76 | ...themeTokens.colors, 77 | container: 'rgb(28, 28, 28)', 78 | layout: 'rgb(18, 18, 18)', 79 | base_text: 'rgb(224, 224, 224)' 80 | }, 81 | boxShadow: { 82 | ...themeTokens.boxShadow 83 | } 84 | }; 85 | 86 | return { 87 | themeTokens, 88 | darkThemeTokens 89 | }; 90 | } 91 | ``` 92 | 93 | ::: tip 代码位置 94 | src/store/modules/theme/shared.ts 95 | ::: 96 | -------------------------------------------------------------------------------- /src/zh/guide/theme/ui.md: -------------------------------------------------------------------------------- 1 | # 组件库主题 2 | 3 | ## NaiveUI 主题配置 4 | 5 | **根据主题颜色产出组件库的主题变量** 6 | 7 | ```ts 8 | /** 9 | * Get naive theme 10 | * 11 | * @param colors Theme colors 12 | */ 13 | function getNaiveTheme(colors: App.Theme.ThemeColor) { 14 | const { primary: colorLoading } = colors; 15 | 16 | const theme: GlobalThemeOverrides = { 17 | common: { 18 | ...getNaiveThemeColors(colors) 19 | }, 20 | LoadingBar: { 21 | colorLoading 22 | } 23 | }; 24 | 25 | return theme; 26 | } 27 | 28 | /** Naive theme */ 29 | const naiveTheme = computed(() => getNaiveTheme(themeColors.value)); 30 | ``` 31 | 32 | ::: tip 代码位置 33 | src/store/modules/theme/shared.ts 34 | 35 | src/store/modules/theme/index.ts 36 | ::: 37 | 38 | **应用主题变量** 39 | 40 | ```vue 41 | 54 | ``` 55 | 56 | ::: tip 代码位置 57 | src/App.vue 58 | ::: 59 | 60 | ## AntDesignVue 主题配置 61 | 62 | **根据主题颜色产出组件库的主题变量** 63 | 64 | ```ts 65 | /** 66 | * Get antd theme 67 | * 68 | * @param colors Theme colors 69 | * @param darkMode Is dark mode 70 | */ 71 | function getAntdTheme(colors: App.Theme.ThemeColor, darkMode: boolean) { 72 | const { defaultAlgorithm, darkAlgorithm } = antdTheme; 73 | 74 | const { primary, info, success, warning, error } = colors; 75 | 76 | const theme: ConfigProviderProps['theme'] = { 77 | token: { 78 | colorPrimary: primary, 79 | colorInfo: info, 80 | colorSuccess: success, 81 | colorWarning: warning, 82 | colorError: error 83 | }, 84 | algorithm: [darkMode ? darkAlgorithm : defaultAlgorithm], 85 | components: { 86 | Menu: { 87 | colorSubItemBg: 'transparent' 88 | } 89 | } 90 | }; 91 | 92 | return theme; 93 | } 94 | 95 | /** Antd theme */ 96 | const antdTheme = computed(() => getAntdTheme(themeColors.value, darkMode.value)); 97 | ``` 98 | 99 | ::: tip 代码位置 100 | src/store/modules/theme/shared.ts 101 | 102 | src/store/modules/theme/index.ts 103 | ::: 104 | 105 | **应用主题变量** 106 | 107 | ```vue 108 | 115 | ``` 116 | -------------------------------------------------------------------------------- /src/zh/guide/theme/unocss.md: -------------------------------------------------------------------------------- 1 | # UnoCSS 主题 2 | 3 | 通过 [Theme Tokens](/zh/guide/theme/tokens) 注入到 UnoCSS 的主题配置中, 借助于 UnoCSS 的能力,可以使用类似 `text-primary bg-primary` 等 class 名称进而统一了组件库和 UnoCSS 的主题颜色的应用。 4 | 5 | ```ts 6 | import { themeVars } from './src/theme/vars'; 7 | 8 | export default defineConfig({ 9 | theme: { 10 | ...themeVars 11 | } 12 | }); 13 | ``` 14 | 15 | ::: tip 代码位置 16 | ./uno.config.ts 17 | ::: 18 | 19 | ## UnoCSS 的暗黑模式 20 | 21 | 通过 UnoCSS 提供的预设暗黑模式方案, 只要在 html 上添加 class="dark",则项目中类似于 `dark:text-#000 dark:bg-#333` 的 class 就会生效,从而达到暗黑模式的效果 22 | 23 | ```ts 24 | export default defineConfig({ 25 | presets: [presetUno({ dark: 'class' })] 26 | }); 27 | ``` 28 | 29 | ::: tip 代码位置 30 | ./uno.config.ts 31 | ::: 32 | -------------------------------------------------------------------------------- /src/zh/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: home 3 | 4 | title: SoybeanAdmin 5 | titleTemplate: 一个清新优雅的中后台模版 6 | 7 | hero: 8 | name: SoybeanAdmin 9 | text: 清新优雅的中后台模版 10 | tagline: 基于 Vue3、Vite6、TypeScript 和 UnoCSS 11 | image: 12 | src: /logo.svg 13 | alt: SoybeanAdmin 14 | actions: 15 | - theme: brand 16 | text: 开始 17 | link: /zh/guide/quick-start 18 | - theme: alt 19 | text: 介绍 20 | link: /zh/guide/intro 21 | - theme: alt 22 | text: 在 GitHub 上查看 23 | link: https://github.com/soybeanjs/soybean-admin 24 | - theme: alt 25 | text: React 版本文档 -> 26 | link: https://react-docs.soybeanjs.cn/ 27 | 28 | features: 29 | - icon: 🆕 30 | title: 社区流行的最新技术栈 31 | details: Vue3,Vite6,TypeScript 和 UnoCSS 32 | - icon: 🔄 33 | title: 多框架支持 34 | details: 同时支持 Vue3 和 React,让您可灵活选择前端开发技术栈 35 | - icon: 🎨 36 | title: 多组件库集成 37 | details: 适配 Element Plus、Naive UI、Ant Design、Ant Design Vue 等多种组件库,满足多样化 UI 需求。 38 | - icon: 🦋 39 | title: 清晰的项目结构 40 | details: 采用 pnpm monorepo,结构清晰优雅,易于维护。代码规范性极高 41 | - icon: 🛠️ 42 | title: TypeScript 43 | details: 严格的类型检查,易于团队开发和维护 44 | - icon: 🔩 45 | title: 主题配置 46 | details: 内置丰富的主题配置,轻松结合 UnoCSS进行拓展 47 | - icon: 🔗 48 | title: 文件路由系统 49 | details: 自动化、智能化的文件路由系统 50 | - icon: 🔑 51 | title: 权限路由 52 | details: 支持前端静态路由和后端动态路由 53 | - icon: ⚙️ 54 | title: 扩展 Script 脚本 55 | details: 提供一键升级依赖、自动生成 ChangeLog、生成提交信息等多种脚本功能,显著提升开发效率。 56 | --- 57 | 58 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 149 | 150 | 151 | -------------------------------------------------------------------------------- /src/zh/recommend/alova.md: -------------------------------------------------------------------------------- 1 | # Alova 2 | 3 | ## 相关链接 4 | 5 | - [文档](https://alova.js.org/zh-CN) 6 | - [GitHub](https://github.com/alovajs/alova) 7 | 8 | 9 | ## 介绍 10 | 11 | alova 是一个流程简化的下一代请求工具,它可以将你的 API 集成工作流从 7 个步骤极致地简化为 1 个步骤,你只需要选择 API 即可使用。 12 | 13 | 有别于@tanstack/react-request、swrjs、ahooks的useRequest等库,alova是一个完整的请求方案,alova 让你的请求集成变得非常简单,并且保持更高效的 Client-Server 数据交互。此外,你可以在客户端和服务端环境中(包括 SSR)使用alova。 14 | 15 | 此外,alova 还具有以下特性: 16 | - 与 axios 相似的 api 设计,学习成本更低; 17 | - 高性能的客户端和服务端请求策略,让应用更流畅; 18 | - 灵活性高,alova 可以在任何 js 环境下,与任何 UI 框架协作使用,并且提供了统一的使用体验和完美的代码迁移; 19 | - 多级缓存模式和请求共享机制,提升请求性能并降低服务端压力; 20 | - api 代码的高聚合组织,每个 api 的请求参数、缓存行为、响应数据转换等都将聚集在相同的代码块中,这对于管理大量的 api 有很大的优势; 21 | -------------------------------------------------------------------------------- /src/zh/recommend/index.md: -------------------------------------------------------------------------------- 1 | # 前言 2 | 3 | 在这部分文档中,我们将为您介绍一些我们觉得有意思的各类技术。尽管目前这些技术可能尚未在我们的项目中使用,但我们认为它们是非常有价值的内容。我们希望通过这些介绍,能够帮助到您。 4 | 5 | 我们深知技术的发展日新月异,新的技术层出不穷。虽然我们无法保证这些介绍中的技术一定适用于每个项目,但我们相信它们具有一定的参考价值。无论您是对这些技术感兴趣,还是希望在项目中尝试新的解决方案,我们都希望能够为您提供一些有用的信息。 6 | 7 | 请继续阅读后面的内容,了解更多关于这些技术的介绍。如果其中的介绍或其他信息有误,请随时与我们联系,我们将非常乐意为您提供帮助和纠正。谢谢! 8 | 9 | 祝您阅读愉快! 10 | -------------------------------------------------------------------------------- /src/zh/recommend/klona.md: -------------------------------------------------------------------------------- 1 | # klona 2 | 3 | ## 相关链接 4 | 5 | - [GitHub](https://github.com/lukeed/klona) 6 | 7 | ## 介绍 8 | 9 | `klona` 是一个非常小巧(240B 到 501B)且高效的工具库,用于深拷贝 JavaScript 对象、数组、日期、正则表达式等多种数据类型。 10 | 11 | ### 特性 12 | 13 | - 超小体积和高性能 14 | - 深拷贝/递归复制 15 | - 安全处理复杂数据类型,包括:`Array`, `Date`, `Map`, `Object`, `RegExp`, `Set`, `TypedArray` 等。 16 | 17 | 与浅拷贝(例如 `Object.assign`)不同,深拷贝会递归地遍历源输入并复制其 _值_ —— 而不是其值的 _引用_ —— 到该输入的一个新实例中。结果是一个结构上相同的克隆,它独立于原始源进行操作并控制自己的值。 18 | 19 | > **为什么叫 "klona"?** 这是瑞典语中的 "clone"。 20 | 21 | ## 安装 22 | 23 | ```bash 24 | npm install --save klona 25 | ``` 26 | 27 | ## 不同模式 28 | 29 | `klona` 提供了多种"版本",让你可以只引入你需要的功能! 30 | 31 | #### `klona/json` 32 | 33 | > **大小 (gzip):** 240 字节 34 | > **可用性:** CommonJS, ES Module, UMD 35 | > **能力:** JSON 数据类型 36 | 37 | ```javascript 38 | import { klona } from 'klona/json'; 39 | ``` 40 | 41 | #### `klona/lite` 42 | 43 | > **大小 (gzip):** 354 字节 44 | > **可用性:** CommonJS, ES Module, UMD 45 | > **能力:** 扩展了 `klona/json`,增加了对自定义类、Date 和 RegExp 的支持。 46 | 47 | ```javascript 48 | import { klona } from 'klona/lite'; 49 | ``` 50 | 51 | #### `klona` (默认) 52 | 53 | > **大小 (gzip):** 451 字节 54 | > **可用性:** CommonJS, ES Module, UMD 55 | > **能力:** 扩展了 `klona/lite`,增加了对 Map, Set, DataView, ArrayBuffer, TypedArray 的支持。 56 | 57 | ```javascript 58 | import { klona } from 'klona'; 59 | ``` 60 | 61 | #### `klona/full` 62 | 63 | > **大小 (gzip):** 501 字节 64 | > **可用性:** CommonJS, ES Module, UMD 65 | > **能力:** 扩展了 `klona`,增加了对 Symbol 属性和不可枚举属性的支持。 66 | 67 | ```javascript 68 | import { klona } from 'klona/full'; 69 | ``` 70 | 71 | ## 使用方法 72 | 73 | ```javascript 74 | import { klona } from 'klona'; 75 | 76 | const input = { 77 | foo: 1, 78 | bar: { 79 | baz: 2, 80 | bat: { 81 | hello: 'world' 82 | } 83 | } 84 | }; 85 | 86 | const output = klona(input); 87 | 88 | // 与原始对象完全相同 89 | // assert.deepStrictEqual(input, output); // 在 Node.js 环境中断言 90 | 91 | // 深层更新... 92 | output.bar.bat.hola = 'mundo'; 93 | output.bar.baz = 99; 94 | 95 | // ...不会影响源对象! 96 | console.log(JSON.stringify(input, null, 2)); 97 | // { 98 | // "foo": 1, 99 | // "bar": { 100 | // "baz": 2, 101 | // "bat": { 102 | // "hello": "world" 103 | // } 104 | // } 105 | // } 106 | ``` 107 | 108 | ## API 109 | 110 | ### `klona(input)` 111 | 112 | 返回: `typeof input` 113 | 114 | 返回输入值的深拷贝/克隆。 115 | -------------------------------------------------------------------------------- /src/zh/recommend/page-spy.md: -------------------------------------------------------------------------------- 1 | # PageSpy 2 | 3 | ## 相关链接 4 | 5 | - [GitHub](https://github.com/HuolalaTech/page-spy-web) 6 | - [官方文档](https://pagespy.org) 7 | - [Bilibili 视频](https://space.bilibili.com/3493272492181886/) 8 | 9 | ## 介绍 10 | 11 | ### 背景 12 | 13 | 控制台在日常开发中是必不可少的效率工具,项目问题总是第一时间通过它排查。但有些时候无法使用控制,因此而导致排查问题需要花费很多时间和人力,这就是 PageSpy 想去解决的问题。 14 | 15 | 看看下面的场景你是否遇到过: 16 | 17 | - **真机调试 H5**:以往有些产品提供了可以在 H5 上查看信息的面板,但真机屏幕太小操作不便、显示不友好,以及数据会被截断; 18 | 19 | - **远程办公、异地协同**:传统沟通方式如邮件、电话、视频会议等,沟通问题的周期长、效率不高、故障信息不全面,容易误解误判; 20 | 21 | - **用户设备白屏**:除了需要提前获知出现问题的用户信息,定位问题的方式包括查看数据监控、日志分析,甚至还要跑到客户现场等,这些方式依赖排障人员要理解业务场景、技术实现; 22 | 23 | - **全局的 "问题反馈" 组件**:大多注重用户体验的网站,为了在产品出现故障后能收到反馈并及时解决,会在产品端为用户提供反馈问题的表单组件。从用户的角度这确实会提升好感,但用户提交的内容可能对于排查问题的帮助并不大,根本原因是:用户提交的基本上是文字概述和截图,或许还包含用户信息,但开发者更希望看到的是: 24 | 25 | - 用户的操作轨迹; 26 | - 伴随着操作,程序的运行时行为数据。例如:打印的日志、发出的网络请求以及响应数据等内容; 27 | 28 | 正如本地开发我们就是这样使用控制台的,不是吗? 29 | 30 | ### 能力 31 | 32 | PageSpy 按使用场景分为 **在线实时调试** 和 **离线日志回放** 两种模式,提供了 Console、Network、Page、Storage 以及 System 信息面板,还可以发送代码到项目端上执行;能够让开发者们提升排障的效率,同时也能减少沟通的时间。 33 | 34 | 目前 PageSpy 在 Web / 小程序 / ReactNative / OpenHarmony 平台上都已经有稳定的 SDK。 35 | -------------------------------------------------------------------------------- /src/zh/recommend/soybean-cli.md: -------------------------------------------------------------------------------- 1 | # @soybeanjs/cli 2 | 3 | ## 相关链接 4 | 5 | - [文档](https://github.com/soybeanjs/cli/blob/main/README.md) 6 | - [GitHub](https://github.com/soybeanjs/cli) 7 | 8 | ## 介绍 9 | 10 | SoybeanJS 的命令行工具,包含六种便捷命令: 11 | 12 | | 命令 | 作用 | 13 | |-------------------|--------------------------------------------------------| 14 | | git-commit | 生成符合 Angular 规范的 git 提交信息 (在提交信息添加前缀`!`可以表示破坏性更新的提交) | 15 | | git-commit-verify | 校验 git 的提交信息是否符合 Angular 规范 | 16 | | cleanup | 快速、完整的清空依赖和构建产物 | 17 | | ncu | 命令 npm-check-updates, 升级依赖 | 18 | | changelog | 根据两次 tag 生成 changelog (--total: 根据所有 tag 生成 changelog) | 19 | | release | 发布:更新版本号、生成 changelog、提交代码 | 20 | -------------------------------------------------------------------------------- /src/zh/standard/index.md: -------------------------------------------------------------------------------- 1 | # 代码规范 2 | 3 | 在前端开发过程中,代码的规范化不仅有助于提高代码的可读性和可维护性,还能减少团队协作中的摩擦,提升开发效率。本规范旨在为前端开发提供一套统一的标准,涵盖代码格式化检查、命名规范、Vue写法规范和TypeScript写法规范等方面的内容。 4 | 5 | 通过遵循本规范,开发者可以确保代码的一致性,减少因风格差异引起的代码审查问题,并且在项目的长期维护中受益匪浅。希望本规范能够为您的开发工作提供有力的支持和指导。 6 | -------------------------------------------------------------------------------- /src/zh/standard/lint.md: -------------------------------------------------------------------------------- 1 | # 格式化检查 2 | 3 | ## 使用 ESLint 和 Prettier 进行代码格式化 4 | 5 | SoybeanJS团队使用[`@soybeanjs/eslint-config`](https://github.com/soybeanjs/eslint-config)来进行代码格式化。这个配置包含了ESLint和Prettier的配置,以及一些自定义的规则。 6 | 7 | ## 代码检查 8 | 9 | ### lint-staged 10 | 11 | 安装 `lint-staged`: 12 | 13 | ```bash 14 | pnpm i lint-staged -D 15 | ``` 16 | 17 | 在 `package.json` 中添加: 18 | 19 | ```json 20 | { 21 | "lint-staged": { 22 | "*": "eslint --fix" 23 | } 24 | } 25 | ``` 26 | 27 | ### simple-git-hooks 28 | 29 | 安装 `simple-git-hooks`: 30 | 31 | ```bash 32 | pnpm i simple-git-hooks -D 33 | ``` 34 | 35 | 在 `package.json` 中添加git钩子: 36 | 37 | ```json 38 | { 39 | "simple-git-hooks": { 40 | "commit-msg": "pnpm sa git-commit-verify", 41 | "pre-commit": "pnpm typecheck && pnpm lint-staged" 42 | } 43 | } 44 | ``` 45 | 46 | 在 `package.json` 中添加脚本: 47 | 48 | ```json 49 | { 50 | "scripts": { 51 | "prepare": "simple-git-hooks" 52 | } 53 | } 54 | ``` 55 | 56 | ::: tip 提示 57 | 变更 `simple-git-hooks` 配置或取消 `simple-git-hooks` 时,先更改 `package.json` 中的`simple-git-hooks`对应的配置,然后运行 `pnpm run prepare`使其生效。 58 | ::: 59 | -------------------------------------------------------------------------------- /src/zh/standard/naming.md: -------------------------------------------------------------------------------- 1 | # 命名规范 2 | 3 | - 文件和文件夹命名: 统一用小写加连字符`-`命名,多个单词用连字符连接 4 | 5 | ``` 6 | views 7 | ├── home 8 | │ └── index.vue 9 | 10 | ``` 11 | 12 | - Vue 组件名称 13 | 14 | - 组件名称统一用 PascalCase 法命名,多个单词首字母大写 15 | 16 | ```vue 17 | 22 | ``` 23 | 24 | - iconify 图标组件名称统一用 kebab-case 法命名,多个单词用中划线连接 25 | 26 | ```vue 27 | 30 | ``` 31 | 32 | > 方便iconify插件直接展示图标 33 | 34 | - 构造函数、class 类、TS 类型命名:统一用 PascalCase 法命名,多个单词首字母大写 35 | 36 | ```ts 37 | function Person() {} 38 | 39 | class Person {} 40 | 41 | type Person = { 42 | name: string; 43 | }; 44 | 45 | interface Person { 46 | name: string; 47 | } 48 | ``` 49 | 50 | - 变量、普通函数命名:统一用 camelCase 法命名,多个单词首字母小写 51 | 52 | ```ts 53 | let num: number = 1; 54 | 55 | function getNum() {} 56 | ``` 57 | 58 | - 常量命名:统一用大写字母命名,多个单词用下划线连接 59 | 60 | ```ts 61 | const MAX_COUNT = 10; 62 | ``` 63 | 64 | - 样式的命名:统一用小写字母命名,多个单词用中划线连接 65 | 66 | ```css 67 | .container { 68 | } 69 | 70 | .container-item { 71 | } 72 | ``` 73 | 74 | - 请求函数命名:统一以`fetch`开头,后面跟请求的资源名称 75 | 76 | ```ts 77 | function fetchUser() {} 78 | ``` 79 | -------------------------------------------------------------------------------- /src/zh/standard/synthesis.md: -------------------------------------------------------------------------------- 1 | # 综合 2 | -------------------------------------------------------------------------------- /src/zh/standard/tools.md: -------------------------------------------------------------------------------- 1 | # 工具规范 2 | -------------------------------------------------------------------------------- /src/zh/standard/ts.md: -------------------------------------------------------------------------------- 1 | # TS 写法规范 2 | -------------------------------------------------------------------------------- /src/zh/standard/vue.md: -------------------------------------------------------------------------------- 1 | # Vue 写法规范 2 | 3 | ## SFC顺序 4 | 5 | ### script 6 | 7 | - import 导入语句 8 | 9 | - 建议按照以下依赖顺序: 10 | 11 | 1. vue 12 | 2. vue-router 13 | 3. pinia 14 | 4. @vueuse/core 15 | 5. UI库 16 | 6. 其他依赖 17 | 7. 项目内部依赖(monorepo) 18 | 8. 别名导入 19 | 9. 相对路径导入 20 | 21 | - 类型单独使用 `import type` 导入,并在相同依赖的下面 22 | 23 | 例如: 24 | 25 | ```ts 26 | import { ref } from 'vue'; 27 | import type { Ref } from 'vue'; 28 | ``` 29 | 30 | - defineOptions 31 | 32 | - Props 类型定义 33 | 34 | ```ts 35 | interface Props { 36 | prop1: string; 37 | prop2: number; 38 | } 39 | ``` 40 | 41 | - defineProps 42 | 43 | ```ts 44 | defineProps(); 45 | const props = defineProps(); // 用到props时 46 | ``` 47 | 48 | - Emits 类型定义 49 | 50 | ```ts 51 | interface Emits { 52 | emit1: (arg1: string) => void; 53 | emit2: (arg1: number) => void; 54 | } 55 | 56 | // 或者 57 | interface Emits { 58 | emit1: [arg1: string]; 59 | emit2: [arg1: number]; 60 | } 61 | ``` 62 | 63 | - defineEmits 64 | 65 | ```ts 66 | defineEmits(); 67 | const emit = defineEmits(); // 用到emit时 68 | ``` 69 | 70 | - 导入的hooks函数 71 | 72 | 例如:useRouter, useRoute, 以及自行封装的hooks 73 | 74 | ```ts 75 | const router = useRouter(); 76 | const route = useRoute(); 77 | const appStore = useAppStore(); 78 | const { loading, startLoading, endLoading } = useLoading(); 79 | ``` 80 | 81 | - 组件逻辑定义 82 | 83 | ```ts 84 | const count = ref(0); 85 | const increment = () => { 86 | count.value++; 87 | }; 88 | 89 | const visible = ref(false); 90 | const toggleVisible = () => { 91 | visible.value = !visible.value; 92 | }; 93 | ``` 94 | 95 | - 必要的`init`函数,所有的初始化逻辑都放在这里 96 | 97 | ```ts 98 | async function init() { 99 | await fetchData(); 100 | } 101 | ``` 102 | 103 | - watch和watchEffect 104 | 105 | ```ts 106 | watchEffect(() => { 107 | console.log(count.value); 108 | }); 109 | 110 | watch( 111 | () => count.value, 112 | (newValue, oldValue) => { 113 | console.log(newValue, oldValue); 114 | } 115 | ); 116 | ``` 117 | 118 | - 生命周期钩子 119 | 120 | ```ts 121 | // 相当于在`created`钩子中执行 122 | init(); 123 | 124 | // 或者 125 | onMounted(() => { 126 | init(); 127 | }); 128 | ``` 129 | 130 | - defineExpose 131 | 132 | ```ts 133 | const exposed = { 134 | count, 135 | increment 136 | }; 137 | 138 | defineExpose(exposed); 139 | ``` 140 | -------------------------------------------------------------------------------- /src/zh/tutorial/debug.md: -------------------------------------------------------------------------------- 1 | # 调试 2 | 3 | ## 概述 4 | 5 | 在软件开发的世界里,调试就像是开发者的放大镜和手术刀,它不仅能帮助我们: 6 | 7 | - 🔍 快速定位并修复代码错误 8 | - 🔄 深入理解代码执行流程 9 | - 📊 实时监控变量状态 10 | - 💾 分析内存使用情况 11 | - ⚡ 优化程序性能 12 | 13 | 本文将带你探索如何使用 VSCode 强大的调试功能,让调试过程变得轻松高效。 14 | 15 | ## JavaScript 和 TypeScript 调试 16 | 17 | ### tsx - TypeScript 执行利器 18 | 19 | [`tsx`](https://tsx.is/) 是Node.js对运行TypeScript的增强,它让 TypeScript 代码的执行变得简单直接: 20 | 21 | - 零配置执行 TypeScript 文件 22 | - 支持 ES 模块和 CommonJS 23 | - 内置源码映射支持 24 | - 优秀的性能表现 25 | 26 | ```bash 27 | # 安装 tsx 28 | npm install -g tsx 29 | 30 | # 执行 TypeScript 文件 31 | tsx your-file.ts 32 | ``` 33 | 34 | 通过 VSCode 的调试配置,我们可以轻松实现断点调试、变量监控等高级功能。下一节,我们将详细介绍如何配置 VSCode 的调试环境。 35 | 36 | > 💡 提示:VSCode 的调试功能与 Node.js 的调试器完美集成,让你可以像调试 JavaScript 一样轻松调试 TypeScript 代码。 37 | 38 | ### tsx 调试步骤 39 | 40 | 1. 首先全局安装依赖 `tsx` 41 | 42 | ```bash 43 | npm i -g tsx 44 | ``` 45 | 46 | 2. 添加以下调试配置到项目中 `.vscode/launch.json` 中 47 | 48 | ```json 49 | { 50 | "version": "0.2.0", 51 | "configurations": [ 52 | { 53 | "type": "node", 54 | "request": "launch", 55 | "name": "TS Debugger", 56 | "runtimeExecutable": "tsx", 57 | "skipFiles": ["/**", "${workspaceFolder}/node_modules/**"], 58 | "program": "${file}" 59 | } 60 | ] 61 | } 62 | ``` 63 | 64 | 3. 调试测试 65 | 66 | - 新增文件 `debug.ts` 67 | - 输入以下代码 68 | 69 | ```ts 70 | function transformToKebabCase(input: string): string { 71 | return input.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase(); 72 | } 73 | 74 | function start() { 75 | const input = 'HelloWorld'; 76 | const result = transformToKebabCase(input); 77 | return result; 78 | } 79 | 80 | start(); 81 | ``` 82 | 83 | 4. 按照图片中的步骤进行调试 84 | 85 | ![](../../assets/VSCode调试指南01.png) 86 | ![](../../assets/VSCode调试指南02.png) 87 | 88 | ## Vue 调试 89 | 90 | ### 调试步骤 91 | 92 | 1. 添加以下调试配置到项目中 `.vscode/launch.json` 中 93 | 94 | ```json 95 | { 96 | "version": "0.2.0", 97 | "configurations": [ 98 | { 99 | "type": "chrome", 100 | "request": "launch", 101 | "name": "Vue Debugger", 102 | "url": "http://localhost:9527", 103 | "webRoot": "${workspaceFolder}" 104 | } 105 | ] 106 | } 107 | ``` 108 | 109 | > 配置中的url里的端口号和项目本地开发运行时的端口号保持一致 110 | 111 | 2. 本地启动项目 112 | 3. 测试调试 113 | 114 | - 打开页面文件`about/index.vue`, 在`onMounted`中添加断点 115 | - 选择`Vue Debugger`, 点击启动调试 - 浏览器进入about页面,然后会自动跳转回VSCode 116 | ![](../../assets/VSCode调试指南03.png) 117 | > 同理,例如当测试点击按钮后执行的逻辑,在点击事件中添加相应断点,然后在页面上点击即可触发调试 118 | 119 | ### 断点类型 120 | 121 | - 在组件methods中设置断点 122 | - 在生命周期钩子中设置断点 123 | - 在计算属性中设置断点 124 | - 在watch中设置断点 125 | - 在路由守卫中设置断点 126 | 127 | > 记得在开发环境启用source map以获得最佳调试体验: 128 | 129 | ```ts 130 | // vite.config.ts 131 | export default defineConfig({ 132 | build: { 133 | sourcemap: true 134 | } 135 | ``` 136 | -------------------------------------------------------------------------------- /src/zh/tutorial/git.md: -------------------------------------------------------------------------------- 1 | # Git 2 | 3 | 通过[git](https://git-scm.com/)网站来下载 git 工具 4 | 5 | ## 初始化git 6 | 7 | - 设置用户信息 8 | 9 | ```bash 10 | git config --global user.name "Soybean" 11 | git config --global user.email "soybeanjs@outlook.com" 12 | ``` 13 | 14 | - 生成密钥 15 | 16 | ```bash 17 | ssh-keygen 18 | ``` 19 | 20 | > 选择过程中直接回车 21 | 22 | ::: tip 提示 23 | 完整命令: 24 | 25 | ```bash 26 | ssh-keygen -t rsa -C "soybeanjs@outlook.com" 27 | ``` 28 | 29 | > -t rsa表示生成rsa密钥,-C表示注释,后面跟上注释内容 30 | 31 | ::: 32 | 33 | - 上传git密钥 34 | 35 | 在用户目录下找到 .ssh/id_rsa.pub,打开,将内容复制到git代码平台的ssh keys中 36 | 37 | ## git常见命令 38 | 39 | - 同步main分支最新代码到当前分支 40 | 41 | ```bash 42 | git pull origin main 43 | git rebase origin/main 44 | ``` 45 | 46 | > 如果当前分支是main分支,可以直接使用`git pull --rebase` 47 | 48 | 遇到冲突时,解决冲突后,使用以下命令继续rebase 49 | 50 | ```bash 51 | git add . 52 | git rebase --continue 53 | ``` 54 | 55 | - 修改最近一次commit的时间 56 | 57 | ```bash 58 | git commit --amend --date="2022-07-29T23:45" 59 | ``` 60 | 61 | - 合并多个commit 62 | 63 | ```bash 64 | git rebase -i HEAD~n # n为要合并commit的个数 65 | ``` 66 | 67 | -- 复制commit到当前分支 68 | 69 | ```bash 70 | git cherry-pick 71 | ``` 72 | 73 | > 默认会保持commit的信息,如果需要不产生提交记录,可以使用`git cherry-pick -n ` 74 | -------------------------------------------------------------------------------- /src/zh/tutorial/index.md: -------------------------------------------------------------------------------- 1 | # 教程 2 | 3 | 在现代前端开发中,掌握各种开发工具和环境的安装与配置是至关重要的。无论是版本控制工具Git,还是JavaScript运行环境Node.js,亦或是调试工具,都是前端开发者日常工作中不可或缺的部分。本教程将详细介绍如何在Mac系统上安装和配置这些工具,帮助你快速搭建起高效的前端开发环境。 4 | 5 | 通过本教程,你将学会: 6 | 7 | - Git的安装与基本使用:包括如何安装Git、配置Git以及基本的Git命令使用。 8 | - Node.js的安装与配置:包括如何安装Node.js、配置npm以及使用fnm管理Node.js版本。 9 | - 调试工具的使用:包括如何在VS Code中进行前端代码的调试,设置断点,查看变量等。 10 | 11 | 希望通过本教程,你能够顺利搭建起前端开发环境,提高开发效率,享受前端开发的乐趣。 12 | -------------------------------------------------------------------------------- /src/zh/tutorial/nodejs.md: -------------------------------------------------------------------------------- 1 | # NodeJS 安装教程 2 | 3 | 由于我们在日常开发过程中会遇到很多基于不同 NodeJS 版本开发的项目,有的项目需要使用低版本的 NodeJS,有的项目需要使用高版本的 NodeJS,所以我们需要安装 NodeJS 的版本管理工具。 4 | 5 | 下面推荐几个工具供大家参考 6 | 7 | - ## nvm 8 | 9 | ### 安装 10 | 11 | 1.打开终端,输入以下命令: 12 | 13 | #### macos 14 | 15 | ```bash 16 | curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash 17 | ``` 18 | 19 | #### windows 20 | 21 | ```bash 22 | https://github.com/coreybutler/nvm-windows/releases/download/1.2.2/nvm-setup.exe 23 | ``` 24 | 25 | 2.安装完成后,关闭终端,重新打开终端,输入以下命令: 26 | 27 | ```bash 28 | nvm --version 29 | ``` 30 | 31 | 3.如果出现版本号,则表示安装成功。 32 | 33 | ### 安装 NodeJS 34 | 35 | 1. 输入以下命令,列出所有可用的 NodeJS 版本: 36 | 37 | ```bash 38 | nvm ls-remote 39 | ``` 40 | 41 | 2. 选择一个版本进行安装,例如安装 NodeJS 14.17.0: 42 | 43 | ```bash 44 | nvm install 18.20.5 45 | ``` 46 | 47 | 3. 安装完成后,输入以下命令,切换到该版本: 48 | 49 | ```bash 50 | nvm use 18.20.5 51 | ``` 52 | 53 | 4. 输入以下命令,查看当前使用的 NodeJS 版本: 54 | 55 | ```bash 56 | node -v 57 | ``` 58 | 59 | 5. 输入以下命令,查看所有已安装的 NodeJS 版本: 60 | 61 | ```bash 62 | nvm ls 63 | ``` 64 | 65 | - ## fnm 66 | 67 | ### windows 68 | 69 | #### 安装chocolatey 70 | 71 | 1. 用管理员模式打开 windows Terminal 72 | 73 | 2. 执行下面命令 74 | 75 | ```bash 76 | Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1')) 77 | ``` 78 | 79 | 3. 输入choco -v,测试是否安装成功 80 | 81 | > choco安装软件,都要用管理员模式打开 windows Terminal 82 | 83 | ### 安装fnm 84 | 85 | 1. 以管理员模式打开Terminal 86 | 87 | 2. 执行命令: 88 | 89 | ```bash 90 | choco install fnm 91 | ``` 92 | 93 | ### 测试fnm命令 94 | 95 | 1. 打开Powershell 96 | 97 | 2. 输入 `fnm -h` 测试命令是否正常 98 | 99 | ```bash 100 | fnm -h 101 | ``` 102 | 103 | ### 环境变量配置 104 | 105 | #### Powershell 106 | 107 | 1. 在下面的目录新建profile.ps1文件 108 | 109 | ```other 110 | %USERPROFILE%\Documents\WindowsPowerShell\profile.ps1 111 | ``` 112 | 113 | > %USERPROFILE%: 表示用户目录,直接在文件管理的地址栏输入 %USERPROFILE%,然后回车 114 | 115 | > WindowsPowerShell为新建的目录, 如果安装node后命令仍然无法识别,将文件夹名称改为PowerShell 116 | 117 | 2. 将下面的代码写入到上面的配置文件里面 118 | 119 | ```bash 120 | fnm env --use-on-cd | Out-String | Invoke-Expression 121 | ``` 122 | 123 | #### cmd 124 | 125 | 1. 搜索 cmd 126 | 2. 打开文件所在位置 127 | 3. 对 “命令提示符” 右键,点击属性 128 | 4. 修改 目标 为下面的值 129 | 130 | ```other 131 | %windir%\system32\cmd.exe /k %USERPROFILE%\bashrc.cmd 132 | ``` 133 | 134 | 5. 进入用户目录,添加文件 bashrc.cmd 135 | 6. 将下面的代码写入到上面的配置文件里面 136 | 137 | ```bash 138 | @echo off 139 | FOR /f "tokens=*" %%z IN ('fnm env --use-on-cd') DO CALL %%z 140 | ``` 141 | 142 | #### git bash 143 | 144 | 进入用户目录,在git bash的配置文件 .bash_profile 添加下面的代码 145 | 146 | ```bash 147 | eval $(fnm env | sed 1d) 148 | export PATH=$(cygpath $FNM_MULTISHELL_PATH):$PATH 149 | 150 | if [[ -f .node-version || -f .nvmrc ]]; then 151 | fnm use 152 | fi 153 | ``` 154 | 155 | #### VSCode内置的cmd 156 | 157 | 在配置文件settings.json里面添加如下代码: 158 | 159 | ```json 160 | "terminal.integrated.defaultProfile.windows": "Default Cmd", 161 | "terminal.integrated.profiles.windows": { 162 | "Default Cmd":{ 163 | "path": "C:\\Windows\\System32\\cmd.exe", 164 | "args": ["/k", "%USERPROFILE%\\bashrc.cmd"] 165 | } 166 | } 167 | ``` 168 | 169 | ### Mac 170 | 171 | #### 安装fnm 172 | 173 | ```bash 174 | curl -fsSL https://fnm.vercel.app/install | bash 175 | ``` 176 | 177 | #### 设置fnm环境 178 | 179 | 1. 在.zshrc中加入下面的代码 180 | 181 | ```bash 182 | eval "$(fnm env --use-on-cd)" 183 | ``` 184 | 185 | 2. 刷新.zshrc 186 | 187 | ```bash 188 | source ~/.zshrc 189 | ``` 190 | 191 | #### fnm使用 192 | 193 | #### 安装NodeJS 194 | 195 | ```other 196 | fnm install 16 197 | fnm install 14 198 | fnm install 12 199 | ``` 200 | 201 | #### 使用NodeJS 202 | 203 | ```other 204 | fnm use 16 205 | fnm use 14 206 | fnm use 12 207 | ``` 208 | 209 | #### 测试node命令 210 | 211 | ```other 212 | node -v 213 | ``` 214 | 215 | #### fnm切换node默认版本 216 | 217 | ```other 218 | fnm default 14 #默认使用版本14,每次打开terminal的node版本就是14 219 | ``` 220 | 221 | #### fnm更多用法 222 | 223 | ```other 224 | fnm -h 225 | ``` 226 | 227 | > 或者访问 [https://github.com/Schniz/fnm](https://github.com/Schniz/fnm) 228 | -------------------------------------------------------------------------------- /src/zh/tutorial/other.md: -------------------------------------------------------------------------------- 1 | # 其他教程 2 | -------------------------------------------------------------------------------- /src/zh/tutorial/software.md: -------------------------------------------------------------------------------- 1 | # 软件安装教程 2 | 3 | - ## ApiPost 4 | 5 | 简介:接口调试以及 mock 工具 6 | 7 | [官方网址](https://www.apipost.cn/download.html) 8 | 9 | - ## Postman 10 | 11 | 简介:接口调试工具 12 | 13 | [官方网址](https://www.postman.com/downloads/) 14 | 15 | - ## Charles 16 | 17 | 简介:抓包工具 18 | 19 | [官方网址](https://www.charlesproxy.com/) 20 | [下载地址](https://www.charlesproxy.com/download/) 21 | 22 | - ## Fiddler 23 | 24 | 简介:抓包工具 25 | 26 | [官方网址](https://www.telerik.com/fiddler) 27 | 28 | - ## Typora 29 | 30 | 简介:Markdown 编辑器 31 | 32 | [官方网址](https://typora.io/) 33 | 34 | - ## Xshell 35 | 36 | 简介:远程连接工具 37 | 38 | [官方网址](https://www.netsarang.com/zh/xshell-download/) 39 | 40 | - ## Xftp 41 | 42 | 简介:远程文件传输工具 43 | 44 | [官方网址](https://www.netsarang.com/zh/xftp-download/) 45 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "jsx": "preserve", 5 | "jsxImportSource": "vue", 6 | "lib": ["DOM", "ESNext"], 7 | "baseUrl": ".", 8 | "module": "ESNext", 9 | "moduleResolution": "node", 10 | "resolveJsonModule": true, 11 | "types": ["vite/client", "node"], 12 | "strict": true, 13 | "strictNullChecks": true, 14 | "noUnusedLocals": true, 15 | "outDir": "dist", 16 | "allowSyntheticDefaultImports": true, 17 | "esModuleInterop": true, 18 | "forceConsistentCasingInFileNames": true, 19 | "isolatedModules": true 20 | }, 21 | "include": [".vitepress/**/*.ts"], 22 | "exclude": ["node_modules", "dist"] 23 | } 24 | --------------------------------------------------------------------------------