diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..80a6f4a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,59 @@ +name: CI + +on: + # 每当 push 到 main 分支时触发部署 + push: + branches: [main] + # 手动触发部署 + workflow_dispatch: + +env: # 设置环境变量 + TZ: Asia/Shanghai # 时区(设置时区可使页面中的`最近更新时间`使用该时区时间) + +jobs: + docs: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + with: + # “最近更新时间” 等 git 日志相关信息,需要拉取全部提交记录 + fetch-depth: 0 + + - name: Setup pnpm + uses: pnpm/action-setup@v2 + with: + # 选择要使用的 pnpm 版本 + version: 8 + # 使用 pnpm 安装依赖 + run_install: true + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + # 选择要使用的 node 版本 + node-version: 20 + # 缓存 pnpm 依赖 + cache: pnpm + + # 运行构建脚本 + - name: Build VuePress site + run: pnpm build + + # 查看 workflow 的文档来获取更多信息 + # @see https://github.com/crazy-max/ghaction-github-pages + - name: Deploy to GitHub Pages + uses: crazy-max/ghaction-github-pages@v4 + with: + # 部署到 gh-pages 分支 + target_branch: gh-pages + # 部署目录为 VuePress 的默认输出目录 + build_dir: docs/.vuepress/dist + env: + # @see https://docs.github.com/cn/actions/reference/authentication-in-a-workflow#about-the-github_token-secret + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }} + TARGET_REPO: ronnaces/ronna-admin-doc + TARGET_BRANCH: gh-pages + BUILD_SCRIPT: yarn && yarn run build + BUILD_DIR: docs/.vuepress/dist \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ab4ff40 --- /dev/null +++ b/.gitignore @@ -0,0 +1,40 @@ +# npm +package-lock.json +node_modules +yarn-error.log + +# vscode +.vscode + +#yarn +yarn.lock + +# vuepress +docs/.vuepress/dist + +# 百度链接推送 +urls.txt + +# mac +.DS_Store + +/idea/ +dist +dist-ssr +*.local +.eslintcache +report.html +vite.config.*.timestamp* + +npm-debug.log* +.pnpm-error.log* +.pnpm-debug.log +tests/**/coverage/ + +# Editor directories and files +.idea +*.suo +*.ntvs* +*.njsproj +*.sln +tsconfig.tsbuildinfo \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..800a662 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +## 2.0.0(2024-4-3) + +### 🎫 Chores + +- Release 2.0.0 version diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..16d6732 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019-present gaoyi(Evan) Xu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.MD b/README.MD new file mode 100644 index 0000000..e8f3721 --- /dev/null +++ b/README.MD @@ -0,0 +1,24 @@ +

logo

+ + +

ronna-admin-doc

+ +[查看文档](https://ronnaces.github.io/ronna-admin-doc/) + +## 安装依赖 + +``` +pnpm install +``` + +## 运行 + +``` +pnpm dev +``` + +## 打包 + +``` +pnpm build +``` \ No newline at end of file diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js new file mode 100644 index 0000000..4e2453c --- /dev/null +++ b/docs/.vuepress/config.js @@ -0,0 +1,236 @@ +const baiduCode = require('./config/baiduCode.js'); // 百度统计hm码 +const htmlModules = require('./config/htmlModules.js'); + + +module.exports = { + + theme: 'vdoing', // 使用依赖包主题 + // theme: require.resolve('../../vdoing'), // 使用本地主题 (先将vdoing主题文件下载到本地:https://github.com/ronnaces/ronna-admin-doc) + + title: "ronna-admin-doc", + description: '一个基于VuePress的 知识管理&博客 主题', + base: '/ronna-admin-doc/', // 默认'/'。如果你想将你的网站部署到如 https://foo.github.io/bar/,那么 base 应该被设置成 "/bar/",(否则页面将失去样式等文件) + head: [ // 注入到页面 中的标签,格式[tagName, { attrName: attrValue }, innerHTML?] + ['link', { rel: 'icon', href: '/img/favicon.ico' }], //favicons,资源放在public文件夹 + ['meta', { name: 'keywords', content: 'vuepress,theme,blog,ronnace,ronna-admin' }], + ['meta', { name: 'theme-color', content: '#11a8cd' }], // 移动浏览器主题颜色 + + // ['meta', { name: 'wwads-cn-verify', content: '6c4b761a28b734fe93831e3fb400ce87' }], // 广告相关,你可以去掉 + // ['script', { src: 'https://cdn.wwads.cn/js/makemoney.js', type: 'text/javascript' }], // 广告相关,你可以去掉 + ], + + // 主题配置 + themeConfig: { + nav: [ + { text: '首页', link: '/' }, + { + text: "指南", + link: "/pages/introduction/", + items: [ + { text: "介绍", link: "/pages/introduction/" }, + { text: "快速开始", link: "/pages/start/" }, + { text: "目录结构", link: "/pages/directory/" }, + { text: "vscode文件夹详解", link: "/pages/vscode/" }, + { text: "平台配置", link: "/pages/config/" }, + { text: "布局", link: "/pages/layout/" }, + { text: "路由和菜单", link: "/pages/routerMenu/" }, + { text: "http请求", link: "/pages/request/" }, + { text: "打包和部署", link: "/pages/build/" }, + { + text: "进阶", + items: [ + { text: "图标", link: "/pages/icon/" }, + { text: "主题和暗黑模式", link: "/pages/theme/" }, + { text: "国际化", link: "/pages/i18n/" }, + { text: "Tailwind CSS", link: "/pages/tailwindcss/" }, + { text: "RBAC权限", link: "/pages/RBAC/" }, + { text: "类型声明", link: "/pages/typescript/" }, + { text: "单点登录", link: "/pages/sso/" }, + { text: "自定义免登录", link: "/pages/nologin/" }, + { text: "打包优化", link: "/pages/buildgood/" }, + { text: "vite预构建", link: "/pages/optimize/" }, + ], + }, + { + text: "其他", + items: [ + { text: "常见问题", link: "/pages/FAQ/" }, + { text: "非平台问题跟踪记录", link: "/pages/track/" }, + { text: "问题反馈", link: "/pages/support/" }, + { text: "git常用命令", link: "/pages/git/" }, + { text: "技术网站推荐", link: "/pages/recommendation/" }, + ], + }, + ], + }, + { text: '资源', link: '/pages/db78e2/' }, + { + text: "日志", + items: [ + { + text: "Github日志", + link: "https://github.com/ronnaces/ronna-admin/releases", + }, + ], + }, + { + text: "优质服务", + link: "/pages/service/", + icon: ` + + + `, + }, + { text: '赞助', link: '/pages/1b12ed/' }, + ], + sidebarDepth: 2, // 侧边栏显示深度,默认1,最大2(显示到h3标题) + logo: '/img/logo.png', // 导航栏logo + repo: 'ronnaces/ronna-admin-doc', // 导航栏右侧生成Github链接 + searchMaxSuggestions: 10, // 搜索结果显示最大数 + lastUpdated: '上次更新', // 更新的时间,及前缀文字 string | boolean (取值为git提交时间) + + // docsDir: 'docs', // 编辑的文件夹 + // editLinks: true, // 编辑链接 + // editLinkText: '编辑', + + // 以下配置是Vdoing主题改动的和新增的配置 + sidebar: { mode: 'structuring', collapsable: false }, // 侧边栏 'structuring' | { mode: 'structuring', collapsable: Boolean} | 'auto' | 自定义 温馨提示:目录页数据依赖于结构化的侧边栏数据,如果你不设置为'structuring',将无法使用目录页 + + // sidebarOpen: false, // 初始状态是否打开侧边栏,默认true + updateBar: { // 最近更新栏 + showToArticle: false, // 显示到文章页底部,默认true + // moreArticle: '/archives' // “更多文章”跳转的页面,默认'/archives' + }, + // titleBadge: false, // 文章标题前的图标是否显示,默认true + // titleBadgeIcons: [ // 文章标题前图标的地址,默认主题内置图标 + // '图标地址1', + // '图标地址2' + // ], + + pageStyle: 'line', // 页面风格,可选值:'card'卡片 | 'line' 线(未设置bodyBgImg时才生效), 默认'card'。 说明:card时背景显示灰色衬托出卡片样式,line时背景显示纯色,并且部分模块带线条边框 + + // contentBgStyle: 1, + + category: false, // 是否打开分类功能,默认true。 如打开,会做的事情有:1. 自动生成的frontmatter包含分类字段 2.页面中显示与分类相关的信息和模块 3.自动生成分类页面(在@pages文件夹)。如关闭,则反之。 + tag: false, // 是否打开标签功能,默认true。 如打开,会做的事情有:1. 自动生成的frontmatter包含标签字段 2.页面中显示与标签相关的信息和模块 3.自动生成标签页面(在@pages文件夹)。如关闭,则反之。 + // archive: false, // 是否打开归档功能,默认true。 如打开,会做的事情有:1.自动生成归档页面(在@pages文件夹)。如关闭,则反之。 + + author: { // 文章默认的作者信息,可在md文件中单独配置此信息 String | {name: String, href: String} + name: 'kunlong-luo', // 必需 + href: 'https://github.com/ronnaces' // 可选的 + }, + social: { // 社交图标,显示于博主信息栏和页脚栏 + // iconfontCssFile: '//at.alicdn.com/t/font_1678482_u4nrnp8xp6g.css', // 可选,阿里图标库在线css文件地址,对于主题没有的图标可自由添加 + icons: [ + { + iconClass: 'icon-github', + title: 'GitHub', + link: 'https://github.com/kunlong-luo' + }, + { + iconClass: 'icon-gitee', + title: 'Gitee', + link: 'https://gitee.com/kunlong-luo' + } + ] + }, + footer: { // 页脚信息 + createYear: 2018, // 博客创建年份 + copyrightInfo: 'kunlong-luo | MIT License', // 博客版权信息,支持a标签 + }, + htmlModules, + }, + + // 插件 + plugins: [ + // [require('./plugins/love-me'), { // 鼠标点击爱心特效 + // color: '#11a8cd', // 爱心颜色,默认随机色 + // excludeClassName: 'theme-vdoing-content' // 要排除元素的class, 默认空'' + // }], + + ['fulltext-search'], // 全文搜索 + + // ['thirdparty-search', { // 可以添加第三方搜索链接的搜索框(原官方搜索框的参数仍可用) + // thirdparty: [ // 可选,默认 [] + // { + // title: '在GitHub中搜索', + // frontUrl: 'https://github.com/search?q=', // 搜索链接的前面部分 + // behindUrl: '' // 搜索链接的后面部分,可选,默认 '' + // }, + // { + // title: '在npm中搜索', + // frontUrl: 'https://www.npmjs.com/search?q=', + // }, + // { + // title: '在Bing中搜索', + // frontUrl: 'https://cn.bing.com/search?q=' + // } + // ] + // }], + + [ + 'vuepress-plugin-baidu-tongji', // 百度统计 + { + hm: baiduCode || '01293bffa6c3962016c08ba685c79d78' + } + ], + + ['one-click-copy', { // 代码块复制按钮 + copySelector: ['div[class*="language-"] pre', 'div[class*="aside-code"] aside'], // String or Array + copyMessage: '复制成功', // default is 'Copy successfully and then paste it for use.' + duration: 1000, // prompt message display time. + showInMobile: false // whether to display on the mobile side, default: false. + }], + ['demo-block', { // demo演示模块 https://github.com/xiguaxigua/vuepress-plugin-demo-block + settings: { + // jsLib: ['http://xxx'], // 在线示例(jsfiddle, codepen)中的js依赖 + // cssLib: ['http://xxx'], // 在线示例中的css依赖 + // vue: 'https://jsd.cdn.zzko.cn/npm/vue/dist/vue.min.js', // 在线示例中的vue依赖 + jsfiddle: false, // 是否显示 jsfiddle 链接 + codepen: true, // 是否显示 codepen 链接 + horizontal: false // 是否展示为横向样式 + } + }], + [ + 'vuepress-plugin-zooming', // 放大图片 + { + selector: '.theme-vdoing-content img:not(.no-zoom)', + options: { + bgColor: 'rgba(0,0,0,0.6)' + }, + }, + ], + [ + '@vuepress/last-updated', // "上次更新"时间格式 + { + transformer: (timestamp, lang) => { + const dayjs = require('dayjs') // https://day.js.org/ + return dayjs(timestamp).format('YYYY/MM/DD, HH:mm:ss') + }, + } + ] + ], + + markdown: { + // lineNumbers: true, + extractHeaders: ['h2', 'h3', 'h4', 'h5', 'h6'], // 提取标题到侧边栏的级别,默认['h2', 'h3'] + }, + + // 监听文件变化并重新构建 + extraWatchFiles: [ + '.vuepress/config.js', + '.vuepress/config/htmlModules.js', + ], + configureWebpack: { + resolve: { + alias: { + "@alias": "/docs/.vuepress/public", + }, + }, + }, +} diff --git a/docs/.vuepress/config/baiduCode.js b/docs/.vuepress/config/baiduCode.js new file mode 100644 index 0000000..9dc5fc1 --- /dev/null +++ b/docs/.vuepress/config/baiduCode.js @@ -0,0 +1 @@ +module.exports = ''; diff --git a/docs/.vuepress/config/htmlModules.js b/docs/.vuepress/config/htmlModules.js new file mode 100644 index 0000000..c152228 --- /dev/null +++ b/docs/.vuepress/config/htmlModules.js @@ -0,0 +1,30 @@ +/** 插入自定义html模块 (可用于插入广告模块等) + * { + * homeSidebarB: htmlString, 首页侧边栏底部 + * + * sidebarT: htmlString, 全局左侧边栏顶部 + * sidebarB: htmlString, 全局左侧边栏底部 + * + * pageT: htmlString, 全局页面顶部 + * pageB: htmlString, 全局页面底部 + * pageTshowMode: string, 页面顶部-显示方式:未配置默认全局;'article' => 仅文章页①; 'custom' => 仅自定义页① + * pageBshowMode: string, 页面底部-显示方式:未配置默认全局;'article' => 仅文章页①; 'custom' => 仅自定义页① + * + * windowLB: htmlString, 全局左下角② + * windowRB: htmlString, 全局右下角② + * } + * + * ①注:在.md文件front matter配置`article: false`的页面是自定义页,未配置的默认是文章页(首页除外)。 + * ②注:windowLB 和 windowRB:1.展示区块最大宽高200px*400px。2.请给自定义元素定一个不超过200px*400px的宽高。3.在屏幕宽度小于960px时无论如何都不会显示。 + */ + + +// module.exports = { +// homeSidebarB: `
自定义模块测试
`, +// sidebarT: `
自定义模块测试
`, +// sidebarB: `
自定义模块测试
`, +// pageT: `
自定义模块测试
`, +// pageB: `
自定义模块测试
`, +// windowLB: `
自定义模块测试
`, +// windowRB: `
自定义模块测试
`, +// } diff --git a/docs/.vuepress/enhanceApp.js b/docs/.vuepress/enhanceApp.js new file mode 100644 index 0000000..373bf35 --- /dev/null +++ b/docs/.vuepress/enhanceApp.js @@ -0,0 +1,59 @@ +/** + * to主题使用者:你可以去掉本文件的所有代码 + */ +export default ({ + Vue, // VuePress 正在使用的 Vue 构造函数 + options, // 附加到根实例的一些选项 + router, // 当前应用的路由实例 + siteData, // 站点元数据 + isServer // 当前应用配置是处于 服务端渲染 还是 客户端 +}) => { + + // 用于监控在路由变化时检查广告拦截器 (to主题使用者:你可以去掉本文件的所有代码) + if (!isServer) { + router.afterEach(() => { + //check if wwads' fire function was blocked after document is ready with 3s timeout (waiting the ad loading) + docReady(function () { + setTimeout(function () { + if (window._AdBlockInit === undefined) { + ABDetected(); + } + }, 3000); + }); + + // 删除事件改为隐藏事件 + setTimeout(() => { + const pageAD = document.querySelector('.page-wwads'); + if (!pageAD) return; + const btnEl = pageAD.querySelector('.wwads-hide'); + if (btnEl) { + btnEl.onclick = () => { + pageAD.style.display = 'none'; + } + } + // 显示广告模块 + if (pageAD.style.display === 'none') { + pageAD.style.display = 'flex'; + } + }, 900); + }) + } +} + + +function ABDetected() { + const h = "
为了本站的长期运营,请将我们的网站加入广告拦截器的白名单,感谢您的支持!如何添加白名单?广告
"; + const wwadsEl = document.getElementsByClassName("wwads-cn"); + const wwadsContentEl = document.querySelector('.wwads-content'); + if (wwadsEl[0] && !wwadsContentEl) { + wwadsEl[0].innerHTML = h; + } +}; + +//check document ready +function docReady(t) { + "complete" === document.readyState || + "interactive" === document.readyState + ? setTimeout(t, 1) + : document.addEventListener("DOMContentLoaded", t); +} diff --git a/docs/.vuepress/plugins/love-me/index.js b/docs/.vuepress/plugins/love-me/index.js new file mode 100644 index 0000000..674294c --- /dev/null +++ b/docs/.vuepress/plugins/love-me/index.js @@ -0,0 +1,12 @@ +const path= require('path'); +const LoveMyPlugin = (options={}) => ({ + define () { + const COLOR = options.color || "rgb(" + ~~ (255 * Math.random()) + "," + ~~ (255 * Math.random()) + "," + ~~ (255 * Math.random()) + ")" + const EXCLUDECLASS = options.excludeClassName || '' + return {COLOR, EXCLUDECLASS} + }, + enhanceAppFiles: [ + path.resolve(__dirname, 'love-me.js') + ] +}); +module.exports = LoveMyPlugin; diff --git a/docs/.vuepress/plugins/love-me/love-me.js b/docs/.vuepress/plugins/love-me/love-me.js new file mode 100644 index 0000000..f93855e --- /dev/null +++ b/docs/.vuepress/plugins/love-me/love-me.js @@ -0,0 +1,62 @@ +export default () => { + if (typeof window !== "undefined") { + (function(e, t, a) { + function r() { + for (var e = 0; e < s.length; e++) s[e].alpha <= 0 ? (t.body.removeChild(s[e].el), s.splice(e, 1)) : (s[e].y--, s[e].scale += .004, s[e].alpha -= .013, s[e].el.style.cssText = "left:" + s[e].x + "px;top:" + s[e].y + "px;opacity:" + s[e].alpha + ";transform:scale(" + s[e].scale + "," + s[e].scale + ") rotate(45deg);background:" + s[e].color + ";z-index:99999"); + requestAnimationFrame(r) + } + function n() { + var t = "function" == typeof e.onclick && e.onclick; + + e.onclick = function(e) { + // 过滤指定元素 + let mark = true; + EXCLUDECLASS && e.path && e.path.forEach((item) =>{ + if(item.nodeType === 1) { + typeof item.className === 'string' && item.className.indexOf(EXCLUDECLASS) > -1 ? mark = false : '' + } + }) + + if(mark) { + t && t(), + o(e) + } + } + } + function o(e) { + var a = t.createElement("div"); + a.className = "heart", + s.push({ + el: a, + x: e.clientX - 5, + y: e.clientY - 5, + scale: 1, + alpha: 1, + color: COLOR + }), + t.body.appendChild(a) + } + function i(e) { + var a = t.createElement("style"); + a.type = "text/css"; + try { + a.appendChild(t.createTextNode(e)) + } catch(t) { + a.styleSheet.cssText = e + } + t.getElementsByTagName("head")[0].appendChild(a) + } + // function c() { + // return "rgb(" + ~~ (255 * Math.random()) + "," + ~~ (255 * Math.random()) + "," + ~~ (255 * Math.random()) + ")" + // } + var s = []; + e.requestAnimationFrame = e.requestAnimationFrame || e.webkitRequestAnimationFrame || e.mozRequestAnimationFrame || e.oRequestAnimationFrame || e.msRequestAnimationFrame || + function(e) { + setTimeout(e, 1e3 / 60) + }, + i(".heart{width: 10px;height: 10px;position: fixed;background: #f00;transform: rotate(45deg);-webkit-transform: rotate(45deg);-moz-transform: rotate(45deg);}.heart:after,.heart:before{content: '';width: inherit;height: inherit;background: inherit;border-radius: 50%;-webkit-border-radius: 50%;-moz-border-radius: 50%;position: fixed;}.heart:after{top: -5px;}.heart:before{left: -5px;}"), + n(), + r() + })(window, document) + } +} \ No newline at end of file diff --git a/docs/.vuepress/public/.nojekyll b/docs/.vuepress/public/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/docs/.vuepress/public/CORS b/docs/.vuepress/public/CORS new file mode 100644 index 0000000..f59ec20 --- /dev/null +++ b/docs/.vuepress/public/CORS @@ -0,0 +1 @@ +* \ No newline at end of file diff --git "a/docs/.vuepress/public/audio/higher/\345\205\211\350\276\211\345\262\201\346\234\210.mp3" "b/docs/.vuepress/public/audio/higher/\345\205\211\350\276\211\345\262\201\346\234\210.mp3" new file mode 100644 index 0000000..ecf69bb Binary files /dev/null and "b/docs/.vuepress/public/audio/higher/\345\205\211\350\276\211\345\262\201\346\234\210.mp3" differ diff --git "a/docs/.vuepress/public/audio/higher/\346\265\267\351\230\224\345\244\251\347\251\272.mp3" "b/docs/.vuepress/public/audio/higher/\346\265\267\351\230\224\345\244\251\347\251\272.mp3" new file mode 100644 index 0000000..fed7506 Binary files /dev/null and "b/docs/.vuepress/public/audio/higher/\346\265\267\351\230\224\345\244\251\347\251\272.mp3" differ diff --git "a/docs/.vuepress/public/audio/\345\205\211\350\276\211\345\262\201\346\234\210.mp3" "b/docs/.vuepress/public/audio/\345\205\211\350\276\211\345\262\201\346\234\210.mp3" new file mode 100644 index 0000000..d330244 Binary files /dev/null and "b/docs/.vuepress/public/audio/\345\205\211\350\276\211\345\262\201\346\234\210.mp3" differ diff --git "a/docs/.vuepress/public/audio/\346\265\267\351\230\224\345\244\251\347\251\272.mp3" "b/docs/.vuepress/public/audio/\346\265\267\351\230\224\345\244\251\347\251\272.mp3" new file mode 100644 index 0000000..39bcbe3 Binary files /dev/null and "b/docs/.vuepress/public/audio/\346\265\267\351\230\224\345\244\251\347\251\272.mp3" differ diff --git a/docs/.vuepress/public/iconfont/iconfont.css b/docs/.vuepress/public/iconfont/iconfont.css new file mode 100644 index 0000000..e88e105 --- /dev/null +++ b/docs/.vuepress/public/iconfont/iconfont.css @@ -0,0 +1,59 @@ +@font-face { + font-family: "iconfont"; /* Project id 3114978 */ + src: url('iconfont.woff2?t=1667224389760') format('woff2'), + url('iconfont.woff?t=1667224389760') format('woff'), + url('iconfont.ttf?t=1667224389760') format('truetype'); +} + +.iconfont { + font-family: "iconfont" !important; + font-size: 16px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.icon-xiangxiajiantou:before { + content: "\e65e"; +} + +.icon-xiangzuojiantou:before { + content: "\e660"; +} + +.icon-dagouyouquan:before { + content: "\e630"; +} + +.icon-gantanhao:before { + content: "\e710"; +} + +.icon-info:before { + content: "\e675"; +} + +.icon-cuowu:before { + content: "\e7fa"; +} + +.icon-loading:before { + content: "\e61d"; +} + +.icon-shijian:before { + content: "\e687"; +} + +.icon-award:before { + content: "\e7df"; +} + +.icon-view:before { + content: "\e633"; +} + +.icon-book:before { + content: "\e67c"; +} + diff --git a/docs/.vuepress/public/iconfont/iconfont.js b/docs/.vuepress/public/iconfont/iconfont.js new file mode 100644 index 0000000..a29f1c0 --- /dev/null +++ b/docs/.vuepress/public/iconfont/iconfont.js @@ -0,0 +1 @@ +window._iconfont_svg_string_3114978='',function(e){var t=(t=document.getElementsByTagName("script"))[t.length-1],a=t.getAttribute("data-injectcss"),t=t.getAttribute("data-disable-injectsvg");if(!t){var o,c,i,n,d,l=function(t,a){a.parentNode.insertBefore(t,a)};if(a&&!e.__iconfont__svg__cssinject__){e.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(t){console&&console.log(t)}}o=function(){var t,a=document.createElement("div");a.innerHTML=e._iconfont_svg_string_3114978,(a=a.getElementsByTagName("svg")[0])&&(a.setAttribute("aria-hidden","true"),a.style.position="absolute",a.style.width=0,a.style.height=0,a.style.overflow="hidden",a=a,(t=document.body).firstChild?l(a,t.firstChild):t.appendChild(a))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(o,0):(c=function(){document.removeEventListener("DOMContentLoaded",c,!1),o()},document.addEventListener("DOMContentLoaded",c,!1)):document.attachEvent&&(i=o,n=e.document,d=!1,h(),n.onreadystatechange=function(){"complete"==n.readyState&&(n.onreadystatechange=null,s())})}function s(){d||(d=!0,i())}function h(){try{n.documentElement.doScroll("left")}catch(t){return void setTimeout(h,50)}s()}}(window); \ No newline at end of file diff --git a/docs/.vuepress/public/iconfont/iconfont.json b/docs/.vuepress/public/iconfont/iconfont.json new file mode 100644 index 0000000..69da202 --- /dev/null +++ b/docs/.vuepress/public/iconfont/iconfont.json @@ -0,0 +1,86 @@ +{ + "id": "3114978", + "name": "my_notes", + "font_family": "iconfont", + "css_prefix_text": "icon-", + "description": "", + "glyphs": [ + { + "icon_id": "630092", + "name": "向下箭头", + "font_class": "xiangxiajiantou", + "unicode": "e65e", + "unicode_decimal": 58974 + }, + { + "icon_id": "630095", + "name": "向左箭头", + "font_class": "xiangzuojiantou", + "unicode": "e660", + "unicode_decimal": 58976 + }, + { + "icon_id": "1166351", + "name": "打勾_有圈", + "font_class": "dagouyouquan", + "unicode": "e630", + "unicode_decimal": 58928 + }, + { + "icon_id": "9974757", + "name": "感叹号", + "font_class": "gantanhao", + "unicode": "e710", + "unicode_decimal": 59152 + }, + { + "icon_id": "11686796", + "name": "info", + "font_class": "info", + "unicode": "e675", + "unicode_decimal": 58997 + }, + { + "icon_id": "12148932", + "name": "错误", + "font_class": "cuowu", + "unicode": "e7fa", + "unicode_decimal": 59386 + }, + { + "icon_id": "722473", + "name": "loading", + "font_class": "loading", + "unicode": "e61d", + "unicode_decimal": 58909 + }, + { + "icon_id": "1196167", + "name": "时间", + "font_class": "shijian", + "unicode": "e687", + "unicode_decimal": 59015 + }, + { + "icon_id": "8952406", + "name": "award", + "font_class": "award", + "unicode": "e7df", + "unicode_decimal": 59359 + }, + { + "icon_id": "15205994", + "name": "view", + "font_class": "view", + "unicode": "e633", + "unicode_decimal": 58931 + }, + { + "icon_id": "1355085", + "name": "book", + "font_class": "book", + "unicode": "e67c", + "unicode_decimal": 59004 + } + ] +} diff --git a/docs/.vuepress/public/iconfont/iconfont.ttf b/docs/.vuepress/public/iconfont/iconfont.ttf new file mode 100644 index 0000000..5bfbc58 Binary files /dev/null and b/docs/.vuepress/public/iconfont/iconfont.ttf differ diff --git a/docs/.vuepress/public/iconfont/iconfont.woff b/docs/.vuepress/public/iconfont/iconfont.woff new file mode 100644 index 0000000..4b4b810 Binary files /dev/null and b/docs/.vuepress/public/iconfont/iconfont.woff differ diff --git a/docs/.vuepress/public/iconfont/iconfont.woff2 b/docs/.vuepress/public/iconfont/iconfont.woff2 new file mode 100644 index 0000000..3cc5af1 Binary files /dev/null and b/docs/.vuepress/public/iconfont/iconfont.woff2 differ diff --git a/docs/.vuepress/public/img/Apifox-2.png b/docs/.vuepress/public/img/Apifox-2.png new file mode 100644 index 0000000..bf5f9c3 Binary files /dev/null and b/docs/.vuepress/public/img/Apifox-2.png differ diff --git a/docs/.vuepress/public/img/Apifox-860x320.png b/docs/.vuepress/public/img/Apifox-860x320.png new file mode 100644 index 0000000..a51315c Binary files /dev/null and b/docs/.vuepress/public/img/Apifox-860x320.png differ diff --git a/docs/.vuepress/public/img/bg.jpeg b/docs/.vuepress/public/img/bg.jpeg new file mode 100644 index 0000000..85e53e7 Binary files /dev/null and b/docs/.vuepress/public/img/bg.jpeg differ diff --git a/docs/.vuepress/public/img/bg.jpg b/docs/.vuepress/public/img/bg.jpg new file mode 100644 index 0000000..f093e79 Binary files /dev/null and b/docs/.vuepress/public/img/bg.jpg differ diff --git a/docs/.vuepress/public/img/build/after-gzip.jpg b/docs/.vuepress/public/img/build/after-gzip.jpg new file mode 100644 index 0000000..9782977 Binary files /dev/null and b/docs/.vuepress/public/img/build/after-gzip.jpg differ diff --git a/docs/.vuepress/public/img/build/before-gzip.jpg b/docs/.vuepress/public/img/build/before-gzip.jpg new file mode 100644 index 0000000..69071e9 Binary files /dev/null and b/docs/.vuepress/public/img/build/before-gzip.jpg differ diff --git a/docs/.vuepress/public/img/build/check-nginx-config.jpg b/docs/.vuepress/public/img/build/check-nginx-config.jpg new file mode 100644 index 0000000..d533db7 Binary files /dev/null and b/docs/.vuepress/public/img/build/check-nginx-config.jpg differ diff --git a/docs/.vuepress/public/img/build/dist-small.jpg b/docs/.vuepress/public/img/build/dist-small.jpg new file mode 100644 index 0000000..73b79b8 Binary files /dev/null and b/docs/.vuepress/public/img/build/dist-small.jpg differ diff --git a/docs/.vuepress/public/img/build/dist.jpg b/docs/.vuepress/public/img/build/dist.jpg new file mode 100644 index 0000000..3df7908 Binary files /dev/null and b/docs/.vuepress/public/img/build/dist.jpg differ diff --git a/docs/.vuepress/public/img/build/nginx-config.jpg b/docs/.vuepress/public/img/build/nginx-config.jpg new file mode 100644 index 0000000..a5d6554 Binary files /dev/null and b/docs/.vuepress/public/img/build/nginx-config.jpg differ diff --git a/docs/.vuepress/public/img/build/no-output.jpg b/docs/.vuepress/public/img/build/no-output.jpg new file mode 100644 index 0000000..75c92f2 Binary files /dev/null and b/docs/.vuepress/public/img/build/no-output.jpg differ diff --git a/docs/.vuepress/public/img/build/optimize.jpg b/docs/.vuepress/public/img/build/optimize.jpg new file mode 100644 index 0000000..dd9b3f9 Binary files /dev/null and b/docs/.vuepress/public/img/build/optimize.jpg differ diff --git a/docs/.vuepress/public/img/build/output.jpg b/docs/.vuepress/public/img/build/output.jpg new file mode 100644 index 0000000..cb7a2e4 Binary files /dev/null and b/docs/.vuepress/public/img/build/output.jpg differ diff --git a/docs/.vuepress/public/img/docker/1.jpg b/docs/.vuepress/public/img/docker/1.jpg new file mode 100644 index 0000000..7835636 Binary files /dev/null and b/docs/.vuepress/public/img/docker/1.jpg differ diff --git a/docs/.vuepress/public/img/electron/1.jpg b/docs/.vuepress/public/img/electron/1.jpg new file mode 100644 index 0000000..dbed617 Binary files /dev/null and b/docs/.vuepress/public/img/electron/1.jpg differ diff --git a/docs/.vuepress/public/img/electron/2.jpg b/docs/.vuepress/public/img/electron/2.jpg new file mode 100644 index 0000000..faccbc0 Binary files /dev/null and b/docs/.vuepress/public/img/electron/2.jpg differ diff --git a/docs/.vuepress/public/img/electron/3.jpg b/docs/.vuepress/public/img/electron/3.jpg new file mode 100644 index 0000000..a872d69 Binary files /dev/null and b/docs/.vuepress/public/img/electron/3.jpg differ diff --git a/docs/.vuepress/public/img/ep/dialog-dark.jpg b/docs/.vuepress/public/img/ep/dialog-dark.jpg new file mode 100644 index 0000000..11fdb04 Binary files /dev/null and b/docs/.vuepress/public/img/ep/dialog-dark.jpg differ diff --git a/docs/.vuepress/public/img/ep/dialog.jpg b/docs/.vuepress/public/img/ep/dialog.jpg new file mode 100644 index 0000000..3af7b56 Binary files /dev/null and b/docs/.vuepress/public/img/ep/dialog.jpg differ diff --git a/docs/.vuepress/public/img/ep/drawer-dark.jpg b/docs/.vuepress/public/img/ep/drawer-dark.jpg new file mode 100644 index 0000000..ba7f3c6 Binary files /dev/null and b/docs/.vuepress/public/img/ep/drawer-dark.jpg differ diff --git a/docs/.vuepress/public/img/ep/drawer.jpg b/docs/.vuepress/public/img/ep/drawer.jpg new file mode 100644 index 0000000..0aae517 Binary files /dev/null and b/docs/.vuepress/public/img/ep/drawer.jpg differ diff --git a/docs/.vuepress/public/img/ep/ep1.png b/docs/.vuepress/public/img/ep/ep1.png new file mode 100644 index 0000000..30fb50c Binary files /dev/null and b/docs/.vuepress/public/img/ep/ep1.png differ diff --git a/docs/.vuepress/public/img/ep/ep2.png b/docs/.vuepress/public/img/ep/ep2.png new file mode 100644 index 0000000..04ad122 Binary files /dev/null and b/docs/.vuepress/public/img/ep/ep2.png differ diff --git a/docs/.vuepress/public/img/ep/ep3.png b/docs/.vuepress/public/img/ep/ep3.png new file mode 100644 index 0000000..a88fd95 Binary files /dev/null and b/docs/.vuepress/public/img/ep/ep3.png differ diff --git a/docs/.vuepress/public/img/ep/ep4.png b/docs/.vuepress/public/img/ep/ep4.png new file mode 100644 index 0000000..3e346a3 Binary files /dev/null and b/docs/.vuepress/public/img/ep/ep4.png differ diff --git a/docs/.vuepress/public/img/ep/messagebox-dark.jpg b/docs/.vuepress/public/img/ep/messagebox-dark.jpg new file mode 100644 index 0000000..ef67b98 Binary files /dev/null and b/docs/.vuepress/public/img/ep/messagebox-dark.jpg differ diff --git a/docs/.vuepress/public/img/ep/messagebox.jpg b/docs/.vuepress/public/img/ep/messagebox.jpg new file mode 100644 index 0000000..2ac5ad8 Binary files /dev/null and b/docs/.vuepress/public/img/ep/messagebox.jpg differ diff --git a/docs/.vuepress/public/img/ep/notification-dark.jpg b/docs/.vuepress/public/img/ep/notification-dark.jpg new file mode 100644 index 0000000..7723ab8 Binary files /dev/null and b/docs/.vuepress/public/img/ep/notification-dark.jpg differ diff --git a/docs/.vuepress/public/img/ep/notification.jpg b/docs/.vuepress/public/img/ep/notification.jpg new file mode 100644 index 0000000..1b46b5e Binary files /dev/null and b/docs/.vuepress/public/img/ep/notification.jpg differ diff --git a/docs/.vuepress/public/img/favicon.ico b/docs/.vuepress/public/img/favicon.ico new file mode 100644 index 0000000..6f2e179 Binary files /dev/null and b/docs/.vuepress/public/img/favicon.ico differ diff --git "a/docs/.vuepress/public/img/gif/\347\214\2531.gif" "b/docs/.vuepress/public/img/gif/\347\214\2531.gif" new file mode 100644 index 0000000..e84d8a2 Binary files /dev/null and "b/docs/.vuepress/public/img/gif/\347\214\2531.gif" differ diff --git "a/docs/.vuepress/public/img/gif/\347\214\2532.gif" "b/docs/.vuepress/public/img/gif/\347\214\2532.gif" new file mode 100644 index 0000000..2811459 Binary files /dev/null and "b/docs/.vuepress/public/img/gif/\347\214\2532.gif" differ diff --git "a/docs/.vuepress/public/img/gif/\347\214\2533.gif" "b/docs/.vuepress/public/img/gif/\347\214\2533.gif" new file mode 100644 index 0000000..894372d Binary files /dev/null and "b/docs/.vuepress/public/img/gif/\347\214\2533.gif" differ diff --git "a/docs/.vuepress/public/img/gif/\347\214\2534.gif" "b/docs/.vuepress/public/img/gif/\347\214\2534.gif" new file mode 100644 index 0000000..7b99130 Binary files /dev/null and "b/docs/.vuepress/public/img/gif/\347\214\2534.gif" differ diff --git a/docs/.vuepress/public/img/guide/cloc.jpg b/docs/.vuepress/public/img/guide/cloc.jpg new file mode 100644 index 0000000..0e70213 Binary files /dev/null and b/docs/.vuepress/public/img/guide/cloc.jpg differ diff --git a/docs/.vuepress/public/img/guide/config-logo.jpg b/docs/.vuepress/public/img/guide/config-logo.jpg new file mode 100644 index 0000000..1e45b2e Binary files /dev/null and b/docs/.vuepress/public/img/guide/config-logo.jpg differ diff --git a/docs/.vuepress/public/img/guide/error1.png b/docs/.vuepress/public/img/guide/error1.png new file mode 100644 index 0000000..24836d6 Binary files /dev/null and b/docs/.vuepress/public/img/guide/error1.png differ diff --git a/docs/.vuepress/public/img/guide/eslint.jpg b/docs/.vuepress/public/img/guide/eslint.jpg new file mode 100644 index 0000000..6964caa Binary files /dev/null and b/docs/.vuepress/public/img/guide/eslint.jpg differ diff --git a/docs/.vuepress/public/img/guide/eslint1.jpg b/docs/.vuepress/public/img/guide/eslint1.jpg new file mode 100644 index 0000000..f5b09f5 Binary files /dev/null and b/docs/.vuepress/public/img/guide/eslint1.jpg differ diff --git a/docs/.vuepress/public/img/guide/grey.jpg b/docs/.vuepress/public/img/guide/grey.jpg new file mode 100644 index 0000000..b7f7e51 Binary files /dev/null and b/docs/.vuepress/public/img/guide/grey.jpg differ diff --git a/docs/.vuepress/public/img/guide/hotlog.png b/docs/.vuepress/public/img/guide/hotlog.png new file mode 100644 index 0000000..62ddace Binary files /dev/null and b/docs/.vuepress/public/img/guide/hotlog.png differ diff --git a/docs/.vuepress/public/img/guide/i18n.jpg b/docs/.vuepress/public/img/guide/i18n.jpg new file mode 100644 index 0000000..2991235 Binary files /dev/null and b/docs/.vuepress/public/img/guide/i18n.jpg differ diff --git a/docs/.vuepress/public/img/guide/i18n.png b/docs/.vuepress/public/img/guide/i18n.png new file mode 100644 index 0000000..2e2a48a Binary files /dev/null and b/docs/.vuepress/public/img/guide/i18n.png differ diff --git a/docs/.vuepress/public/img/guide/i18nAlly.jpg b/docs/.vuepress/public/img/guide/i18nAlly.jpg new file mode 100644 index 0000000..c038225 Binary files /dev/null and b/docs/.vuepress/public/img/guide/i18nAlly.jpg differ diff --git a/docs/.vuepress/public/img/guide/i18nRouter.png b/docs/.vuepress/public/img/guide/i18nRouter.png new file mode 100644 index 0000000..118e3df Binary files /dev/null and b/docs/.vuepress/public/img/guide/i18nRouter.png differ diff --git a/docs/.vuepress/public/img/guide/i18nVue.png b/docs/.vuepress/public/img/guide/i18nVue.png new file mode 100644 index 0000000..2c0d82d Binary files /dev/null and b/docs/.vuepress/public/img/guide/i18nVue.png differ diff --git a/docs/.vuepress/public/img/guide/iconfont.png b/docs/.vuepress/public/img/guide/iconfont.png new file mode 100644 index 0000000..aa6ea2c Binary files /dev/null and b/docs/.vuepress/public/img/guide/iconfont.png differ diff --git a/docs/.vuepress/public/img/guide/lodash.png b/docs/.vuepress/public/img/guide/lodash.png new file mode 100644 index 0000000..dd33af7 Binary files /dev/null and b/docs/.vuepress/public/img/guide/lodash.png differ diff --git a/docs/.vuepress/public/img/guide/log.png b/docs/.vuepress/public/img/guide/log.png new file mode 100644 index 0000000..6ec509e Binary files /dev/null and b/docs/.vuepress/public/img/guide/log.png differ diff --git a/docs/.vuepress/public/img/guide/logo.png b/docs/.vuepress/public/img/guide/logo.png new file mode 100644 index 0000000..dbaa5ce Binary files /dev/null and b/docs/.vuepress/public/img/guide/logo.png differ diff --git a/docs/.vuepress/public/img/guide/mac.png b/docs/.vuepress/public/img/guide/mac.png new file mode 100644 index 0000000..fe65101 Binary files /dev/null and b/docs/.vuepress/public/img/guide/mac.png differ diff --git a/docs/.vuepress/public/img/guide/namespace.jpg b/docs/.vuepress/public/img/guide/namespace.jpg new file mode 100644 index 0000000..4db975e Binary files /dev/null and b/docs/.vuepress/public/img/guide/namespace.jpg differ diff --git a/docs/.vuepress/public/img/guide/nodejs.jpg b/docs/.vuepress/public/img/guide/nodejs.jpg new file mode 100644 index 0000000..4e2c9b5 Binary files /dev/null and b/docs/.vuepress/public/img/guide/nodejs.jpg differ diff --git a/docs/.vuepress/public/img/guide/npm1.jpg b/docs/.vuepress/public/img/guide/npm1.jpg new file mode 100644 index 0000000..79eab51 Binary files /dev/null and b/docs/.vuepress/public/img/guide/npm1.jpg differ diff --git a/docs/.vuepress/public/img/guide/npm2.jpg b/docs/.vuepress/public/img/guide/npm2.jpg new file mode 100644 index 0000000..eac8ddb Binary files /dev/null and b/docs/.vuepress/public/img/guide/npm2.jpg differ diff --git a/docs/.vuepress/public/img/guide/npm3.jpg b/docs/.vuepress/public/img/guide/npm3.jpg new file mode 100644 index 0000000..62979e6 Binary files /dev/null and b/docs/.vuepress/public/img/guide/npm3.jpg differ diff --git a/docs/.vuepress/public/img/guide/optimized.png b/docs/.vuepress/public/img/guide/optimized.png new file mode 100644 index 0000000..44ecf3b Binary files /dev/null and b/docs/.vuepress/public/img/guide/optimized.png differ diff --git a/docs/.vuepress/public/img/guide/package.jpg b/docs/.vuepress/public/img/guide/package.jpg new file mode 100644 index 0000000..4730d92 Binary files /dev/null and b/docs/.vuepress/public/img/guide/package.jpg differ diff --git a/docs/.vuepress/public/img/guide/pinia.png b/docs/.vuepress/public/img/guide/pinia.png new file mode 100644 index 0000000..0a4f3b7 Binary files /dev/null and b/docs/.vuepress/public/img/guide/pinia.png differ diff --git a/docs/.vuepress/public/img/guide/rank.png b/docs/.vuepress/public/img/guide/rank.png new file mode 100644 index 0000000..f97b49c Binary files /dev/null and b/docs/.vuepress/public/img/guide/rank.png differ diff --git a/docs/.vuepress/public/img/guide/recommended1.jpg b/docs/.vuepress/public/img/guide/recommended1.jpg new file mode 100644 index 0000000..19a9a91 Binary files /dev/null and b/docs/.vuepress/public/img/guide/recommended1.jpg differ diff --git a/docs/.vuepress/public/img/guide/recommended2.jpg b/docs/.vuepress/public/img/guide/recommended2.jpg new file mode 100644 index 0000000..5105f55 Binary files /dev/null and b/docs/.vuepress/public/img/guide/recommended2.jpg differ diff --git a/docs/.vuepress/public/img/guide/report.jpg b/docs/.vuepress/public/img/guide/report.jpg new file mode 100644 index 0000000..56811f8 Binary files /dev/null and b/docs/.vuepress/public/img/guide/report.jpg differ diff --git a/docs/.vuepress/public/img/guide/routePath.png b/docs/.vuepress/public/img/guide/routePath.png new file mode 100644 index 0000000..8317592 Binary files /dev/null and b/docs/.vuepress/public/img/guide/routePath.png differ diff --git a/docs/.vuepress/public/img/guide/sass.png b/docs/.vuepress/public/img/guide/sass.png new file mode 100644 index 0000000..561c669 Binary files /dev/null and b/docs/.vuepress/public/img/guide/sass.png differ diff --git a/docs/.vuepress/public/img/guide/snip.png b/docs/.vuepress/public/img/guide/snip.png new file mode 100644 index 0000000..b1ca6cf Binary files /dev/null and b/docs/.vuepress/public/img/guide/snip.png differ diff --git a/docs/.vuepress/public/img/guide/snip30.jpg b/docs/.vuepress/public/img/guide/snip30.jpg new file mode 100644 index 0000000..b60b1ec Binary files /dev/null and b/docs/.vuepress/public/img/guide/snip30.jpg differ diff --git a/docs/.vuepress/public/img/guide/snip32.jpg b/docs/.vuepress/public/img/guide/snip32.jpg new file mode 100644 index 0000000..5d9efe4 Binary files /dev/null and b/docs/.vuepress/public/img/guide/snip32.jpg differ diff --git a/docs/.vuepress/public/img/guide/snip33.jpg b/docs/.vuepress/public/img/guide/snip33.jpg new file mode 100644 index 0000000..5f35e8e Binary files /dev/null and b/docs/.vuepress/public/img/guide/snip33.jpg differ diff --git a/docs/.vuepress/public/img/guide/theme.jpg b/docs/.vuepress/public/img/guide/theme.jpg new file mode 100644 index 0000000..5fba50b Binary files /dev/null and b/docs/.vuepress/public/img/guide/theme.jpg differ diff --git a/docs/.vuepress/public/img/guide/unexpected.jpg b/docs/.vuepress/public/img/guide/unexpected.jpg new file mode 100644 index 0000000..a9aa3b2 Binary files /dev/null and b/docs/.vuepress/public/img/guide/unexpected.jpg differ diff --git a/docs/.vuepress/public/img/guide/vite.png b/docs/.vuepress/public/img/guide/vite.png new file mode 100644 index 0000000..a9eb9cb Binary files /dev/null and b/docs/.vuepress/public/img/guide/vite.png differ diff --git a/docs/.vuepress/public/img/guide/vscode-tailwindcss.png b/docs/.vuepress/public/img/guide/vscode-tailwindcss.png new file mode 100644 index 0000000..5794128 Binary files /dev/null and b/docs/.vuepress/public/img/guide/vscode-tailwindcss.png differ diff --git a/docs/.vuepress/public/img/guide/vscode.png b/docs/.vuepress/public/img/guide/vscode.png new file mode 100644 index 0000000..9420261 Binary files /dev/null and b/docs/.vuepress/public/img/guide/vscode.png differ diff --git a/docs/.vuepress/public/img/guide/xrk1.jpg b/docs/.vuepress/public/img/guide/xrk1.jpg new file mode 100644 index 0000000..349ca3e Binary files /dev/null and b/docs/.vuepress/public/img/guide/xrk1.jpg differ diff --git a/docs/.vuepress/public/img/guide/xrk2.jpg b/docs/.vuepress/public/img/guide/xrk2.jpg new file mode 100644 index 0000000..2769aee Binary files /dev/null and b/docs/.vuepress/public/img/guide/xrk2.jpg differ diff --git a/docs/.vuepress/public/img/guide/yarn.png b/docs/.vuepress/public/img/guide/yarn.png new file mode 100644 index 0000000..0221b2c Binary files /dev/null and b/docs/.vuepress/public/img/guide/yarn.png differ diff --git a/docs/.vuepress/public/img/http/type.jpg b/docs/.vuepress/public/img/http/type.jpg new file mode 100644 index 0000000..96711fb Binary files /dev/null and b/docs/.vuepress/public/img/http/type.jpg differ diff --git a/docs/.vuepress/public/img/icon/ant-icon.png b/docs/.vuepress/public/img/icon/ant-icon.png new file mode 100644 index 0000000..fe2ff71 Binary files /dev/null and b/docs/.vuepress/public/img/icon/ant-icon.png differ diff --git a/docs/.vuepress/public/img/icon/ant-install.png b/docs/.vuepress/public/img/icon/ant-install.png new file mode 100644 index 0000000..2eae4dd Binary files /dev/null and b/docs/.vuepress/public/img/icon/ant-install.png differ diff --git a/docs/.vuepress/public/img/icon/ant-install2.png b/docs/.vuepress/public/img/icon/ant-install2.png new file mode 100644 index 0000000..4e53ba9 Binary files /dev/null and b/docs/.vuepress/public/img/icon/ant-install2.png differ diff --git a/docs/.vuepress/public/img/icon/ep-icon.png b/docs/.vuepress/public/img/icon/ep-icon.png new file mode 100644 index 0000000..e49a561 Binary files /dev/null and b/docs/.vuepress/public/img/icon/ep-icon.png differ diff --git a/docs/.vuepress/public/img/icon/icon-online.png b/docs/.vuepress/public/img/icon/icon-online.png new file mode 100644 index 0000000..9cad7e7 Binary files /dev/null and b/docs/.vuepress/public/img/icon/icon-online.png differ diff --git a/docs/.vuepress/public/img/icon/iconfont.png b/docs/.vuepress/public/img/icon/iconfont.png new file mode 100644 index 0000000..e69de29 diff --git a/docs/.vuepress/public/img/icon/menu-if.png b/docs/.vuepress/public/img/icon/menu-if.png new file mode 100644 index 0000000..7016645 Binary files /dev/null and b/docs/.vuepress/public/img/icon/menu-if.png differ diff --git a/docs/.vuepress/public/img/icon/menu-local.jpg b/docs/.vuepress/public/img/icon/menu-local.jpg new file mode 100644 index 0000000..5e9ccf0 Binary files /dev/null and b/docs/.vuepress/public/img/icon/menu-local.jpg differ diff --git a/docs/.vuepress/public/img/icon/menu-local.png b/docs/.vuepress/public/img/icon/menu-local.png new file mode 100644 index 0000000..1f8accd Binary files /dev/null and b/docs/.vuepress/public/img/icon/menu-local.png differ diff --git a/docs/.vuepress/public/img/icon/menu-svg.png b/docs/.vuepress/public/img/icon/menu-svg.png new file mode 100644 index 0000000..9af2ca7 Binary files /dev/null and b/docs/.vuepress/public/img/icon/menu-svg.png differ diff --git a/docs/.vuepress/public/img/icon/online-click.png b/docs/.vuepress/public/img/icon/online-click.png new file mode 100644 index 0000000..754246c Binary files /dev/null and b/docs/.vuepress/public/img/icon/online-click.png differ diff --git a/docs/.vuepress/public/img/icon/online.jpg b/docs/.vuepress/public/img/icon/online.jpg new file mode 100644 index 0000000..2f7eb4c Binary files /dev/null and b/docs/.vuepress/public/img/icon/online.jpg differ diff --git a/docs/.vuepress/public/img/icon/svg.png b/docs/.vuepress/public/img/icon/svg.png new file mode 100644 index 0000000..e69de29 diff --git a/docs/.vuepress/public/img/icon/useRenderIcon.png b/docs/.vuepress/public/img/icon/useRenderIcon.png new file mode 100644 index 0000000..d617bce Binary files /dev/null and b/docs/.vuepress/public/img/icon/useRenderIcon.png differ diff --git a/docs/.vuepress/public/img/icon/vscode-iconify.png b/docs/.vuepress/public/img/icon/vscode-iconify.png new file mode 100644 index 0000000..d9bc15d Binary files /dev/null and b/docs/.vuepress/public/img/icon/vscode-iconify.png differ diff --git a/docs/.vuepress/public/img/icon/vscode-iconify2.png b/docs/.vuepress/public/img/icon/vscode-iconify2.png new file mode 100644 index 0000000..04825b4 Binary files /dev/null and b/docs/.vuepress/public/img/icon/vscode-iconify2.png differ diff --git a/docs/.vuepress/public/img/layout/horizontal-detail.jpg b/docs/.vuepress/public/img/layout/horizontal-detail.jpg new file mode 100644 index 0000000..10bc318 Binary files /dev/null and b/docs/.vuepress/public/img/layout/horizontal-detail.jpg differ diff --git a/docs/.vuepress/public/img/layout/horizontal.jpg b/docs/.vuepress/public/img/layout/horizontal.jpg new file mode 100644 index 0000000..5f50f49 Binary files /dev/null and b/docs/.vuepress/public/img/layout/horizontal.jpg differ diff --git a/docs/.vuepress/public/img/layout/mixNav-detail.jpg b/docs/.vuepress/public/img/layout/mixNav-detail.jpg new file mode 100644 index 0000000..b1eb2d4 Binary files /dev/null and b/docs/.vuepress/public/img/layout/mixNav-detail.jpg differ diff --git a/docs/.vuepress/public/img/layout/mixNav.jpg b/docs/.vuepress/public/img/layout/mixNav.jpg new file mode 100644 index 0000000..b2e9f5b Binary files /dev/null and b/docs/.vuepress/public/img/layout/mixNav.jpg differ diff --git a/docs/.vuepress/public/img/layout/vertical-detail.jpg b/docs/.vuepress/public/img/layout/vertical-detail.jpg new file mode 100644 index 0000000..6548c30 Binary files /dev/null and b/docs/.vuepress/public/img/layout/vertical-detail.jpg differ diff --git a/docs/.vuepress/public/img/layout/vertical.jpg b/docs/.vuepress/public/img/layout/vertical.jpg new file mode 100644 index 0000000..b5a0a3f Binary files /dev/null and b/docs/.vuepress/public/img/layout/vertical.jpg differ diff --git a/docs/.vuepress/public/img/login/no1.jpg b/docs/.vuepress/public/img/login/no1.jpg new file mode 100644 index 0000000..1c51be3 Binary files /dev/null and b/docs/.vuepress/public/img/login/no1.jpg differ diff --git a/docs/.vuepress/public/img/login/no1.png b/docs/.vuepress/public/img/login/no1.png new file mode 100644 index 0000000..3dc04ec Binary files /dev/null and b/docs/.vuepress/public/img/login/no1.png differ diff --git a/docs/.vuepress/public/img/logo.png b/docs/.vuepress/public/img/logo.png new file mode 100644 index 0000000..22edc0d Binary files /dev/null and b/docs/.vuepress/public/img/logo.png differ diff --git a/docs/.vuepress/public/img/more.png b/docs/.vuepress/public/img/more.png new file mode 100644 index 0000000..830613b Binary files /dev/null and b/docs/.vuepress/public/img/more.png differ diff --git a/docs/.vuepress/public/img/other.png b/docs/.vuepress/public/img/other.png new file mode 100644 index 0000000..87f8098 Binary files /dev/null and b/docs/.vuepress/public/img/other.png differ diff --git a/docs/.vuepress/public/img/panda-waving.png b/docs/.vuepress/public/img/panda-waving.png new file mode 100644 index 0000000..20246c6 Binary files /dev/null and b/docs/.vuepress/public/img/panda-waving.png differ diff --git "a/docs/.vuepress/public/img/png/\346\200\235\347\273\264\345\257\274\345\233\276.png" "b/docs/.vuepress/public/img/png/\346\200\235\347\273\264\345\257\274\345\233\276.png" new file mode 100644 index 0000000..819ef70 Binary files /dev/null and "b/docs/.vuepress/public/img/png/\346\200\235\347\273\264\345\257\274\345\233\276.png" differ diff --git "a/docs/.vuepress/public/img/png/\346\225\260\346\215\256\345\272\223.png" "b/docs/.vuepress/public/img/png/\346\225\260\346\215\256\345\272\223.png" new file mode 100644 index 0000000..4d13c3f Binary files /dev/null and "b/docs/.vuepress/public/img/png/\346\225\260\346\215\256\345\272\223.png" differ diff --git "a/docs/.vuepress/public/img/png/\346\225\260\346\215\256\347\273\223\346\236\204.png" "b/docs/.vuepress/public/img/png/\346\225\260\346\215\256\347\273\223\346\236\204.png" new file mode 100644 index 0000000..1bafe96 Binary files /dev/null and "b/docs/.vuepress/public/img/png/\346\225\260\346\215\256\347\273\223\346\236\204.png" differ diff --git "a/docs/.vuepress/public/img/png/\346\234\215\345\212\241\345\231\250.png" "b/docs/.vuepress/public/img/png/\346\234\215\345\212\241\345\231\250.png" new file mode 100644 index 0000000..4127eb5 Binary files /dev/null and "b/docs/.vuepress/public/img/png/\346\234\215\345\212\241\345\231\250.png" differ diff --git "a/docs/.vuepress/public/img/png/\346\234\272\345\231\250\345\255\246\344\271\240.png" "b/docs/.vuepress/public/img/png/\346\234\272\345\231\250\345\255\246\344\271\240.png" new file mode 100644 index 0000000..081c2b8 Binary files /dev/null and "b/docs/.vuepress/public/img/png/\346\234\272\345\231\250\345\255\246\344\271\240.png" differ diff --git "a/docs/.vuepress/public/img/png/\347\256\227\346\263\225.png" "b/docs/.vuepress/public/img/png/\347\256\227\346\263\225.png" new file mode 100644 index 0000000..92fef3f Binary files /dev/null and "b/docs/.vuepress/public/img/png/\347\256\227\346\263\225.png" differ diff --git "a/docs/.vuepress/public/img/png/\347\263\273\347\273\237.png" "b/docs/.vuepress/public/img/png/\347\263\273\347\273\237.png" new file mode 100644 index 0000000..87f0de0 Binary files /dev/null and "b/docs/.vuepress/public/img/png/\347\263\273\347\273\237.png" differ diff --git "a/docs/.vuepress/public/img/png/\347\263\273\347\273\237\345\210\206\346\236\220.png" "b/docs/.vuepress/public/img/png/\347\263\273\347\273\237\345\210\206\346\236\220.png" new file mode 100644 index 0000000..208e259 Binary files /dev/null and "b/docs/.vuepress/public/img/png/\347\263\273\347\273\237\345\210\206\346\236\220.png" differ diff --git "a/docs/.vuepress/public/img/png/\347\274\226\347\250\213.png" "b/docs/.vuepress/public/img/png/\347\274\226\347\250\213.png" new file mode 100644 index 0000000..a8bca76 Binary files /dev/null and "b/docs/.vuepress/public/img/png/\347\274\226\347\250\213.png" differ diff --git "a/docs/.vuepress/public/img/png/\347\275\221\347\273\234\346\212\200\346\234\257.png" "b/docs/.vuepress/public/img/png/\347\275\221\347\273\234\346\212\200\346\234\257.png" new file mode 100644 index 0000000..f81edb7 Binary files /dev/null and "b/docs/.vuepress/public/img/png/\347\275\221\347\273\234\346\212\200\346\234\257.png" differ diff --git "a/docs/.vuepress/public/img/png/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234.png" "b/docs/.vuepress/public/img/png/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234.png" new file mode 100644 index 0000000..63a1819 Binary files /dev/null and "b/docs/.vuepress/public/img/png/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234.png" differ diff --git "a/docs/.vuepress/public/img/png/\350\275\257\344\273\266\345\274\200\345\217\221.png" "b/docs/.vuepress/public/img/png/\350\275\257\344\273\266\345\274\200\345\217\221.png" new file mode 100644 index 0000000..72c5e85 Binary files /dev/null and "b/docs/.vuepress/public/img/png/\350\275\257\344\273\266\345\274\200\345\217\221.png" differ diff --git "a/docs/.vuepress/public/img/png/\351\235\242\345\220\221\345\257\271\350\261\241.png" "b/docs/.vuepress/public/img/png/\351\235\242\345\220\221\345\257\271\350\261\241.png" new file mode 100644 index 0000000..cd13fa3 Binary files /dev/null and "b/docs/.vuepress/public/img/png/\351\235\242\345\220\221\345\257\271\350\261\241.png" differ diff --git "a/docs/.vuepress/public/img/png/\351\241\271\347\233\256\347\256\241\347\220\206.png" "b/docs/.vuepress/public/img/png/\351\241\271\347\233\256\347\256\241\347\220\206.png" new file mode 100644 index 0000000..0467abd Binary files /dev/null and "b/docs/.vuepress/public/img/png/\351\241\271\347\233\256\347\256\241\347\220\206.png" differ diff --git a/docs/.vuepress/public/img/polite.jpg b/docs/.vuepress/public/img/polite.jpg new file mode 100644 index 0000000..3a4b145 Binary files /dev/null and b/docs/.vuepress/public/img/polite.jpg differ diff --git a/docs/.vuepress/public/img/pure.png b/docs/.vuepress/public/img/pure.png new file mode 100644 index 0000000..11cd42f Binary files /dev/null and b/docs/.vuepress/public/img/pure.png differ diff --git a/docs/.vuepress/public/img/python.png b/docs/.vuepress/public/img/python.png new file mode 100644 index 0000000..c3ddebe Binary files /dev/null and b/docs/.vuepress/public/img/python.png differ diff --git a/docs/.vuepress/public/img/qrcode/QQ.jpg b/docs/.vuepress/public/img/qrcode/QQ.jpg new file mode 100644 index 0000000..b23774c Binary files /dev/null and b/docs/.vuepress/public/img/qrcode/QQ.jpg differ diff --git a/docs/.vuepress/public/img/qrcode/QQ.png b/docs/.vuepress/public/img/qrcode/QQ.png new file mode 100644 index 0000000..affcb4b Binary files /dev/null and b/docs/.vuepress/public/img/qrcode/QQ.png differ diff --git a/docs/.vuepress/public/img/qrcode/gzh.jpg b/docs/.vuepress/public/img/qrcode/gzh.jpg new file mode 100644 index 0000000..6d0f980 Binary files /dev/null and b/docs/.vuepress/public/img/qrcode/gzh.jpg differ diff --git a/docs/.vuepress/public/img/qrcode/qqq.webp b/docs/.vuepress/public/img/qrcode/qqq.webp new file mode 100644 index 0000000..87940a5 Binary files /dev/null and b/docs/.vuepress/public/img/qrcode/qqq.webp differ diff --git a/docs/.vuepress/public/img/qrcode/wxq.png b/docs/.vuepress/public/img/qrcode/wxq.png new file mode 100644 index 0000000..38b8db0 Binary files /dev/null and b/docs/.vuepress/public/img/qrcode/wxq.png differ diff --git a/docs/.vuepress/public/img/qrcode/wxzs.jpg b/docs/.vuepress/public/img/qrcode/wxzs.jpg new file mode 100644 index 0000000..67c9076 Binary files /dev/null and b/docs/.vuepress/public/img/qrcode/wxzs.jpg differ diff --git a/docs/.vuepress/public/img/qrcode/wxzz.jpg b/docs/.vuepress/public/img/qrcode/wxzz.jpg new file mode 100644 index 0000000..53afbed Binary files /dev/null and b/docs/.vuepress/public/img/qrcode/wxzz.jpg differ diff --git a/docs/.vuepress/public/img/qrcode/zfbzz.jpg b/docs/.vuepress/public/img/qrcode/zfbzz.jpg new file mode 100644 index 0000000..b8f94c0 Binary files /dev/null and b/docs/.vuepress/public/img/qrcode/zfbzz.jpg differ diff --git a/docs/.vuepress/public/img/rbac/auths.png b/docs/.vuepress/public/img/rbac/auths.png new file mode 100644 index 0000000..405b407 Binary files /dev/null and b/docs/.vuepress/public/img/rbac/auths.png differ diff --git a/docs/.vuepress/public/img/rbac/roles.png b/docs/.vuepress/public/img/rbac/roles.png new file mode 100644 index 0000000..de0ec12 Binary files /dev/null and b/docs/.vuepress/public/img/rbac/roles.png differ diff --git a/docs/.vuepress/public/img/router/async1.jpg b/docs/.vuepress/public/img/router/async1.jpg new file mode 100644 index 0000000..b18d5d6 Binary files /dev/null and b/docs/.vuepress/public/img/router/async1.jpg differ diff --git a/docs/.vuepress/public/img/router/async10.jpg b/docs/.vuepress/public/img/router/async10.jpg new file mode 100644 index 0000000..19639c1 Binary files /dev/null and b/docs/.vuepress/public/img/router/async10.jpg differ diff --git a/docs/.vuepress/public/img/router/async2.jpg b/docs/.vuepress/public/img/router/async2.jpg new file mode 100644 index 0000000..2ee5341 Binary files /dev/null and b/docs/.vuepress/public/img/router/async2.jpg differ diff --git a/docs/.vuepress/public/img/router/async3.jpg b/docs/.vuepress/public/img/router/async3.jpg new file mode 100644 index 0000000..35bc2f0 Binary files /dev/null and b/docs/.vuepress/public/img/router/async3.jpg differ diff --git a/docs/.vuepress/public/img/router/async4.jpg b/docs/.vuepress/public/img/router/async4.jpg new file mode 100644 index 0000000..aaf4866 Binary files /dev/null and b/docs/.vuepress/public/img/router/async4.jpg differ diff --git a/docs/.vuepress/public/img/router/async5.jpg b/docs/.vuepress/public/img/router/async5.jpg new file mode 100644 index 0000000..64bca48 Binary files /dev/null and b/docs/.vuepress/public/img/router/async5.jpg differ diff --git a/docs/.vuepress/public/img/router/async6.jpg b/docs/.vuepress/public/img/router/async6.jpg new file mode 100644 index 0000000..ca012bb Binary files /dev/null and b/docs/.vuepress/public/img/router/async6.jpg differ diff --git a/docs/.vuepress/public/img/router/async7.jpg b/docs/.vuepress/public/img/router/async7.jpg new file mode 100644 index 0000000..9915fd9 Binary files /dev/null and b/docs/.vuepress/public/img/router/async7.jpg differ diff --git a/docs/.vuepress/public/img/router/async8.jpg b/docs/.vuepress/public/img/router/async8.jpg new file mode 100644 index 0000000..0472ee9 Binary files /dev/null and b/docs/.vuepress/public/img/router/async8.jpg differ diff --git a/docs/.vuepress/public/img/router/async9.jpg b/docs/.vuepress/public/img/router/async9.jpg new file mode 100644 index 0000000..90e4ebb Binary files /dev/null and b/docs/.vuepress/public/img/router/async9.jpg differ diff --git a/docs/.vuepress/public/img/router/more.jpg b/docs/.vuepress/public/img/router/more.jpg new file mode 100644 index 0000000..8352a6f Binary files /dev/null and b/docs/.vuepress/public/img/router/more.jpg differ diff --git a/docs/.vuepress/public/img/router/same1.jpg b/docs/.vuepress/public/img/router/same1.jpg new file mode 100644 index 0000000..08d7f4c Binary files /dev/null and b/docs/.vuepress/public/img/router/same1.jpg differ diff --git a/docs/.vuepress/public/img/router/same2.jpg b/docs/.vuepress/public/img/router/same2.jpg new file mode 100644 index 0000000..dcb7cad Binary files /dev/null and b/docs/.vuepress/public/img/router/same2.jpg differ diff --git a/docs/.vuepress/public/img/router/same4.jpg b/docs/.vuepress/public/img/router/same4.jpg new file mode 100644 index 0000000..c53212a Binary files /dev/null and b/docs/.vuepress/public/img/router/same4.jpg differ diff --git a/docs/.vuepress/public/img/router/static1.jpg b/docs/.vuepress/public/img/router/static1.jpg new file mode 100644 index 0000000..3c0eb14 Binary files /dev/null and b/docs/.vuepress/public/img/router/static1.jpg differ diff --git a/docs/.vuepress/public/img/router/static10.jpg b/docs/.vuepress/public/img/router/static10.jpg new file mode 100644 index 0000000..bb5ad53 Binary files /dev/null and b/docs/.vuepress/public/img/router/static10.jpg differ diff --git a/docs/.vuepress/public/img/router/static11.jpg b/docs/.vuepress/public/img/router/static11.jpg new file mode 100644 index 0000000..3b09583 Binary files /dev/null and b/docs/.vuepress/public/img/router/static11.jpg differ diff --git a/docs/.vuepress/public/img/router/static12.jpg b/docs/.vuepress/public/img/router/static12.jpg new file mode 100644 index 0000000..797c72f Binary files /dev/null and b/docs/.vuepress/public/img/router/static12.jpg differ diff --git a/docs/.vuepress/public/img/router/static13.jpg b/docs/.vuepress/public/img/router/static13.jpg new file mode 100644 index 0000000..370d360 Binary files /dev/null and b/docs/.vuepress/public/img/router/static13.jpg differ diff --git a/docs/.vuepress/public/img/router/static14.jpg b/docs/.vuepress/public/img/router/static14.jpg new file mode 100644 index 0000000..6db9001 Binary files /dev/null and b/docs/.vuepress/public/img/router/static14.jpg differ diff --git a/docs/.vuepress/public/img/router/static15.jpg b/docs/.vuepress/public/img/router/static15.jpg new file mode 100644 index 0000000..3e00ad3 Binary files /dev/null and b/docs/.vuepress/public/img/router/static15.jpg differ diff --git a/docs/.vuepress/public/img/router/static16.jpg b/docs/.vuepress/public/img/router/static16.jpg new file mode 100644 index 0000000..e1b4102 Binary files /dev/null and b/docs/.vuepress/public/img/router/static16.jpg differ diff --git a/docs/.vuepress/public/img/router/static2.jpg b/docs/.vuepress/public/img/router/static2.jpg new file mode 100644 index 0000000..e7e39ba Binary files /dev/null and b/docs/.vuepress/public/img/router/static2.jpg differ diff --git a/docs/.vuepress/public/img/router/static3.jpg b/docs/.vuepress/public/img/router/static3.jpg new file mode 100644 index 0000000..d21e112 Binary files /dev/null and b/docs/.vuepress/public/img/router/static3.jpg differ diff --git a/docs/.vuepress/public/img/router/static4.jpg b/docs/.vuepress/public/img/router/static4.jpg new file mode 100644 index 0000000..a42d310 Binary files /dev/null and b/docs/.vuepress/public/img/router/static4.jpg differ diff --git a/docs/.vuepress/public/img/router/static5.jpg b/docs/.vuepress/public/img/router/static5.jpg new file mode 100644 index 0000000..3c4a261 Binary files /dev/null and b/docs/.vuepress/public/img/router/static5.jpg differ diff --git a/docs/.vuepress/public/img/router/static6.jpg b/docs/.vuepress/public/img/router/static6.jpg new file mode 100644 index 0000000..a05984d Binary files /dev/null and b/docs/.vuepress/public/img/router/static6.jpg differ diff --git a/docs/.vuepress/public/img/router/static7.jpg b/docs/.vuepress/public/img/router/static7.jpg new file mode 100644 index 0000000..7565adc Binary files /dev/null and b/docs/.vuepress/public/img/router/static7.jpg differ diff --git a/docs/.vuepress/public/img/router/static8.jpg b/docs/.vuepress/public/img/router/static8.jpg new file mode 100644 index 0000000..81bd902 Binary files /dev/null and b/docs/.vuepress/public/img/router/static8.jpg differ diff --git a/docs/.vuepress/public/img/router/static9.jpg b/docs/.vuepress/public/img/router/static9.jpg new file mode 100644 index 0000000..7db2688 Binary files /dev/null and b/docs/.vuepress/public/img/router/static9.jpg differ diff --git a/docs/.vuepress/public/img/sponsors/aitools.jpg b/docs/.vuepress/public/img/sponsors/aitools.jpg new file mode 100644 index 0000000..04e7b24 Binary files /dev/null and b/docs/.vuepress/public/img/sponsors/aitools.jpg differ diff --git a/docs/.vuepress/public/img/sponsors/aitools.svg b/docs/.vuepress/public/img/sponsors/aitools.svg new file mode 100644 index 0000000..c33b323 --- /dev/null +++ b/docs/.vuepress/public/img/sponsors/aitools.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/docs/.vuepress/public/img/support/addWx.jpg b/docs/.vuepress/public/img/support/addWx.jpg new file mode 100644 index 0000000..58d6320 Binary files /dev/null and b/docs/.vuepress/public/img/support/addWx.jpg differ diff --git a/docs/.vuepress/public/img/support/ali.png b/docs/.vuepress/public/img/support/ali.png new file mode 100644 index 0000000..e188595 Binary files /dev/null and b/docs/.vuepress/public/img/support/ali.png differ diff --git a/docs/.vuepress/public/img/support/alipay.png b/docs/.vuepress/public/img/support/alipay.png new file mode 100644 index 0000000..0990cb7 Binary files /dev/null and b/docs/.vuepress/public/img/support/alipay.png differ diff --git a/docs/.vuepress/public/img/support/chrome_48x48.png b/docs/.vuepress/public/img/support/chrome_48x48.png new file mode 100644 index 0000000..6a6d425 Binary files /dev/null and b/docs/.vuepress/public/img/support/chrome_48x48.png differ diff --git a/docs/.vuepress/public/img/support/edge_48x48.png b/docs/.vuepress/public/img/support/edge_48x48.png new file mode 100644 index 0000000..e3ed827 Binary files /dev/null and b/docs/.vuepress/public/img/support/edge_48x48.png differ diff --git a/docs/.vuepress/public/img/support/firefox_48x48.png b/docs/.vuepress/public/img/support/firefox_48x48.png new file mode 100644 index 0000000..3e1b89f Binary files /dev/null and b/docs/.vuepress/public/img/support/firefox_48x48.png differ diff --git a/docs/.vuepress/public/img/support/safari_48x48.png b/docs/.vuepress/public/img/support/safari_48x48.png new file mode 100644 index 0000000..bcac3d7 Binary files /dev/null and b/docs/.vuepress/public/img/support/safari_48x48.png differ diff --git a/docs/.vuepress/public/img/support/wechat.png b/docs/.vuepress/public/img/support/wechat.png new file mode 100644 index 0000000..a726f4d Binary files /dev/null and b/docs/.vuepress/public/img/support/wechat.png differ diff --git a/docs/.vuepress/public/img/support/wechatpay.png b/docs/.vuepress/public/img/support/wechatpay.png new file mode 100644 index 0000000..e0adec6 Binary files /dev/null and b/docs/.vuepress/public/img/support/wechatpay.png differ diff --git a/docs/.vuepress/public/img/support/wx.jpg b/docs/.vuepress/public/img/support/wx.jpg new file mode 100644 index 0000000..09dfa2f Binary files /dev/null and b/docs/.vuepress/public/img/support/wx.jpg differ diff --git a/docs/.vuepress/public/img/support/wx.png b/docs/.vuepress/public/img/support/wx.png new file mode 100644 index 0000000..22a7cd4 Binary files /dev/null and b/docs/.vuepress/public/img/support/wx.png differ diff --git a/docs/.vuepress/public/img/tauri/1.jpg b/docs/.vuepress/public/img/tauri/1.jpg new file mode 100644 index 0000000..2e4dd94 Binary files /dev/null and b/docs/.vuepress/public/img/tauri/1.jpg differ diff --git a/docs/.vuepress/public/img/type/_com1.jpg b/docs/.vuepress/public/img/type/_com1.jpg new file mode 100644 index 0000000..4176d0b Binary files /dev/null and b/docs/.vuepress/public/img/type/_com1.jpg differ diff --git a/docs/.vuepress/public/img/type/_com1.png b/docs/.vuepress/public/img/type/_com1.png new file mode 100644 index 0000000..045f66f Binary files /dev/null and b/docs/.vuepress/public/img/type/_com1.png differ diff --git a/docs/.vuepress/public/img/type/_com2.jpg b/docs/.vuepress/public/img/type/_com2.jpg new file mode 100644 index 0000000..d7a56e3 Binary files /dev/null and b/docs/.vuepress/public/img/type/_com2.jpg differ diff --git a/docs/.vuepress/public/img/type/_com2.png b/docs/.vuepress/public/img/type/_com2.png new file mode 100644 index 0000000..94a9300 Binary files /dev/null and b/docs/.vuepress/public/img/type/_com2.png differ diff --git a/docs/.vuepress/public/img/type/after.jpg b/docs/.vuepress/public/img/type/after.jpg new file mode 100644 index 0000000..332bf19 Binary files /dev/null and b/docs/.vuepress/public/img/type/after.jpg differ diff --git a/docs/.vuepress/public/img/type/before.jpg b/docs/.vuepress/public/img/type/before.jpg new file mode 100644 index 0000000..bfbc55c Binary files /dev/null and b/docs/.vuepress/public/img/type/before.jpg differ diff --git a/docs/.vuepress/public/img/type/shims-vue1.png b/docs/.vuepress/public/img/type/shims-vue1.png new file mode 100644 index 0000000..3eaa0ff Binary files /dev/null and b/docs/.vuepress/public/img/type/shims-vue1.png differ diff --git a/docs/.vuepress/public/img/type/shims-vue2.jpg b/docs/.vuepress/public/img/type/shims-vue2.jpg new file mode 100644 index 0000000..4891221 Binary files /dev/null and b/docs/.vuepress/public/img/type/shims-vue2.jpg differ diff --git a/docs/.vuepress/public/img/type/shims-vue3.jpg b/docs/.vuepress/public/img/type/shims-vue3.jpg new file mode 100644 index 0000000..6a7feb7 Binary files /dev/null and b/docs/.vuepress/public/img/type/shims-vue3.jpg differ diff --git a/docs/.vuepress/public/img/type/whole.jpg b/docs/.vuepress/public/img/type/whole.jpg new file mode 100644 index 0000000..f7c56cc Binary files /dev/null and b/docs/.vuepress/public/img/type/whole.jpg differ diff --git a/docs/.vuepress/public/img/ui.png b/docs/.vuepress/public/img/ui.png new file mode 100644 index 0000000..617c56d Binary files /dev/null and b/docs/.vuepress/public/img/ui.png differ diff --git a/docs/.vuepress/public/img/watermarks/buildgood.jpg b/docs/.vuepress/public/img/watermarks/buildgood.jpg new file mode 100644 index 0000000..e7ddc38 Binary files /dev/null and b/docs/.vuepress/public/img/watermarks/buildgood.jpg differ diff --git a/docs/.vuepress/public/img/watermarks/rbac.jpg b/docs/.vuepress/public/img/watermarks/rbac.jpg new file mode 100644 index 0000000..11740c4 Binary files /dev/null and b/docs/.vuepress/public/img/watermarks/rbac.jpg differ diff --git a/docs/.vuepress/public/img/web.png b/docs/.vuepress/public/img/web.png new file mode 100644 index 0000000..0a6e27c Binary files /dev/null and b/docs/.vuepress/public/img/web.png differ diff --git a/docs/.vuepress/public/markmap/01.html b/docs/.vuepress/public/markmap/01.html new file mode 100644 index 0000000..28665f6 --- /dev/null +++ b/docs/.vuepress/public/markmap/01.html @@ -0,0 +1,126 @@ + + + + + + + + Markmap + + + + + + + + + + + + diff --git "a/docs/.vuepress/public/pdf/Cookie\345\222\214Session\345\214\272\345\210\253\347\224\250\346\263\225.pdf" "b/docs/.vuepress/public/pdf/Cookie\345\222\214Session\345\214\272\345\210\253\347\224\250\346\263\225.pdf" new file mode 100644 index 0000000..f745f19 Binary files /dev/null and "b/docs/.vuepress/public/pdf/Cookie\345\222\214Session\345\214\272\345\210\253\347\224\250\346\263\225.pdf" differ diff --git a/docs/.vuepress/public/video/ep.mov b/docs/.vuepress/public/video/ep.mov new file mode 100644 index 0000000..6fe6477 Binary files /dev/null and b/docs/.vuepress/public/video/ep.mov differ diff --git a/docs/.vuepress/public/video/layout.mov b/docs/.vuepress/public/video/layout.mov new file mode 100644 index 0000000..0485a4f Binary files /dev/null and b/docs/.vuepress/public/video/layout.mov differ diff --git a/docs/.vuepress/public/video/nologin.mov b/docs/.vuepress/public/video/nologin.mov new file mode 100644 index 0000000..60fb8ee Binary files /dev/null and b/docs/.vuepress/public/video/nologin.mov differ diff --git a/docs/.vuepress/public/video/redirect.mov b/docs/.vuepress/public/video/redirect.mov new file mode 100644 index 0000000..75ea33b Binary files /dev/null and b/docs/.vuepress/public/video/redirect.mov differ diff --git a/docs/.vuepress/public/video/same3.mov b/docs/.vuepress/public/video/same3.mov new file mode 100644 index 0000000..c89eaf9 Binary files /dev/null and b/docs/.vuepress/public/video/same3.mov differ diff --git a/docs/.vuepress/public/video/same5.mov b/docs/.vuepress/public/video/same5.mov new file mode 100644 index 0000000..40c5a22 Binary files /dev/null and b/docs/.vuepress/public/video/same5.mov differ diff --git a/docs/.vuepress/public/video/start.mov b/docs/.vuepress/public/video/start.mov new file mode 100644 index 0000000..e81aad7 Binary files /dev/null and b/docs/.vuepress/public/video/start.mov differ diff --git a/docs/.vuepress/public/video/theme.mov b/docs/.vuepress/public/video/theme.mov new file mode 100644 index 0000000..b9302a0 Binary files /dev/null and b/docs/.vuepress/public/video/theme.mov differ diff --git a/docs/.vuepress/public/video/url.mov b/docs/.vuepress/public/video/url.mov new file mode 100644 index 0000000..e9c1950 Binary files /dev/null and b/docs/.vuepress/public/video/url.mov differ diff --git a/docs/.vuepress/styles/index.styl b/docs/.vuepress/styles/index.styl new file mode 100644 index 0000000..9c157a3 --- /dev/null +++ b/docs/.vuepress/styles/index.styl @@ -0,0 +1,93 @@ +// .home-wrapper .banner .banner-conent .hero h1{ +// font-size 2.8rem!important +// } +// // 文档中适配 +// table +// width auto +// .page >*:not(.footer),.card-box +// box-shadow: none!important + +// .page +// @media (min-width $contentWidth + 80) +// padding-top $navbarHeight!important +// .home-wrapper .banner .banner-conent +// padding 0 2.9rem +// box-sizing border-box +// .home-wrapper .banner .slide-banner .slide-banner-wrapper .slide-item a +// h2 +// margin-top 2rem +// font-size 1.2rem!important +// p +// padding 0 1rem + +// 评论区颜色重置 +.gt-container + .gt-ico-tip + &::after + content: '。( Win + . ) or ( ⌃ + ⌘ + ␣ ) open Emoji' + color: #999 + .gt-meta + border-color var(--borderColor)!important + .gt-comments-null + color var(--textColor) + opacity .5 + .gt-header-textarea + color var(--textColor) + background rgba(180,180,180,0.1)!important + .gt-btn + border-color $accentColor!important + background-color $accentColor!important + .gt-btn-preview + background-color rgba(255,255,255,0)!important + color $accentColor!important + a + color $accentColor!important + .gt-svg svg + fill $accentColor!important + .gt-comment-content,.gt-comment-admin .gt-comment-content + background-color rgba(150,150,150,0.1)!important + &:hover + box-shadow 0 0 25px rgba(150,150,150,.5)!important + .gt-comment-body + color var(--textColor)!important + + +// qq徽章 +.qq + position: relative; +.qq::after + content: "可撩"; + background: $accentColor; + color:#fff; + padding: 0 5px; + border-radius: 10px; + font-size:12px; + position: absolute; + top: -4px; + right: -35px; + transform:scale(0.85); + +// demo模块图标颜色 +body .vuepress-plugin-demo-block__wrapper + &,.vuepress-plugin-demo-block__display + border-color rgba(160,160,160,.3) + .vuepress-plugin-demo-block__footer:hover + .vuepress-plugin-demo-block__expand::before + border-top-color: $accentColor !important; + border-bottom-color: $accentColor !important; + svg + fill: $accentColor !important; + + +// 全文搜索框 +.suggestions + overflow: auto + max-height: calc(100vh - 6rem) + @media (max-width: 719px) { + width: 90vw; + min-width: 90vw!important; + margin-right: -20px; + } + .highlight + color: $accentColor + font-weight: bold diff --git a/docs/.vuepress/styles/palette.styl b/docs/.vuepress/styles/palette.styl new file mode 100644 index 0000000..b65c5e0 --- /dev/null +++ b/docs/.vuepress/styles/palette.styl @@ -0,0 +1,62 @@ + +// 原主题变量已弃用,以下是vdoing使用的变量,你可以在这个文件内修改它们。 + +//***vdoing主题-变量***// + +// // 颜色 + +// $bannerTextColor = #fff // 首页banner区(博客标题)文本颜色 +// $accentColor = #11A8CD +// $arrowBgColor = #ccc +// $badgeTipColor = #42b983 +// $badgeWarningColor = darken(#ffe564, 35%) +// $badgeErrorColor = #DA5961 + +// // 布局 +// $navbarHeight = 3.6rem +// $sidebarWidth = 18rem +// $contentWidth = 860px +// $homePageWidth = 1100px +// $rightMenuWidth = 230px // 右侧菜单 + +// // 代码块 +// $lineNumbersWrapperWidth = 2.5rem + +// 浅色模式 +// .theme-mode-light +// --bodyBg: rgba(255,255,255,1) +// --mainBg: rgba(255,255,255,1) +// --sidebarBg: rgba(255,255,255,.8) +// --blurBg: rgba(255,255,255,.9) +// // --textColor: #004050 +// --textLightenColor: #0085AD +// --borderColor: rgba(0,0,0,.15) +// --codeBg: #f6f6f6 +// --codeColor: #525252 +// codeThemeLight() + +// // 深色模式 +// .theme-mode-dark +// --bodyBg: rgba(30,30,34,1) +// --mainBg: rgba(30,30,34,1) +// --sidebarBg: rgba(30,30,34,.8) +// --blurBg: rgba(30,30,34,.8) +// --textColor: rgb(140,140,150) +// --textLightenColor: #0085AD +// --borderColor: #2C2C3A +// --codeBg: #252526 +// --codeColor: #fff +// codeThemeDark() + +// // 阅读模式 +// .theme-mode-read +// --bodyBg: rgba(245,245,213,1) +// --mainBg: rgba(245,245,213,1) +// --sidebarBg: rgba(245,245,213,.8) +// --blurBg: rgba(245,245,213,.9) +// --textColor: #004050 +// --textLightenColor: #0085AD +// --borderColor: rgba(0,0,0,.15) +// --codeBg: #282c34 +// --codeColor: #fff +// codeThemeDark() diff --git "a/docs/01.\346\214\207\345\215\227/01.\346\214\207\345\215\227/01.\344\273\213\347\273\215.md" "b/docs/01.\346\214\207\345\215\227/01.\346\214\207\345\215\227/01.\344\273\213\347\273\215.md" new file mode 100644 index 0000000..4949d41 --- /dev/null +++ "b/docs/01.\346\214\207\345\215\227/01.\346\214\207\345\215\227/01.\344\273\213\347\273\215.md" @@ -0,0 +1,30 @@ +--- +title: 介绍 +article: false +date: 2022-11-07 +permalink: /pages/introduction +--- + +[ronna-admin](https://github.com/ronnaces/ronna-admin) 是一款开源完全免费且开箱即用的中后台管理系统模版。完全采用 `ECMAScript` 模块(`ESM`)规范来编写和组织代码,使用了最新的 `Vue3`、`Vite`、`Element-Plus`、`TypeScript`、`Pinia`、`Tailwindcss` 等主流技术开发 + +## 在线预览 + +- [ronna-admin](https://ronna.ronnaces.com/) + +## 完整版本 + +- [点我查看完整版本](https://github.com/ronnaces/ronna-admin) + +## 浏览器支持 + +本地开发推荐使用 `Chrome`、`Edge`、`Firefox` 浏览器,作者常用的是最新版 `Chrome` 浏览器 +实际使用中感觉 `Firefox` 在动画上要比别的浏览器更加丝滑,只是作者用 `Chrome` 已经习惯了,看个人爱好选择吧 +更详细的浏览器兼容性支持请看 [Vue 支持哪些浏览器?](https://cn.vuejs.org/about/faq.html#what-browsers-does-vue-support) 和 [Vite 浏览器兼容性](https://cn.vitejs.dev/guide/build#browser-compatibility) + +| [ Edge](http://godban.github.io/browsers-support-badges/)
IE | [ Edge](http://godban.github.io/browsers-support-badges/)
Edge | [Firefox](http://godban.github.io/browsers-support-badges/)
Firefox | [Chrome](http://godban.github.io/browsers-support-badges/)
Chrome | [Safari](http://godban.github.io/browsers-support-badges/)
Safari | +| :-------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| 不支持 | 最后两个版本 | 最后两个版本 | 最后两个版本 | 最后两个版本 | + +## 维护者 + +[kunlong-luo](https://github.com/kunlong-luo)、[suzilong666](https://github.com/suzilong666) diff --git "a/docs/01.\346\214\207\345\215\227/01.\346\214\207\345\215\227/02.\345\277\253\351\200\237\345\274\200\345\247\213.md" "b/docs/01.\346\214\207\345\215\227/01.\346\214\207\345\215\227/02.\345\277\253\351\200\237\345\274\200\345\247\213.md" new file mode 100644 index 0000000..c887b9c --- /dev/null +++ "b/docs/01.\346\214\207\345\215\227/01.\346\214\207\345\215\227/02.\345\277\253\351\200\237\345\274\200\345\247\213.md" @@ -0,0 +1,70 @@ +--- +title: 快速开始 +article: false +date: 2022-11-07 +permalink: /pages/start +--- + +## 开发环境 + +从 `ronna-admin v2.0.0` 版本后,规定 `node` 版本应不小于 `18.18.0` (推荐优先安装长期维护`LTS`版,如下图),`pnpm` 版本应不小于 `8.6.10` + +[nodejs 官网](https://nodejs.org/en) 当然也可以安装 [.nvmrc](https://raw.githubusercontent.com/ronnaces/ronna-admin/main/.nvmrc) 推荐的 `node` 版本 + +![nodejs](~@alias/img/guide/nodejs.jpg) + +如果您还没安装 `pnpm`,请执行下面命令进行安装(`mac` 用户遇到安装报错请在命令前加上 `sudo`) + +``` +npm install -g pnpm +``` + +如果您需要安装多个 `node` 版本环境,请参考 [Node.js 版本管理工具](/pages/FAQ/#平台要求-node-版本应不小于-18-18-0-、pnpm-版本应不小于-8-6-10-但是实际开发有的项目需要比这些低的版本怎么解决呢) + +如果您觉得安装平台依赖慢,请参考 [npmmirror](/pages/FAQ/#安装依赖慢-如何解决) + +## `IDE` + +如果您使用的 `IDE` 是 [vscode](https://code.visualstudio.com/) (推荐),[请点击这里并安装推荐的插件](/pages/vscode/#extensions-json),可提高开发效率 + +## 拉取代码 + +### 从 `GitHub` 上拉取 + +#### 完整版前端代码 + +``` +git clone https://github.com/ronnaces/ronna-admin.git +``` + +## 本地开发 + +#### 安装依赖 + +``` +pnpm install +``` + +#### 启动平台 + +``` +pnpm dev +``` + +#### 项目打包 + +``` +pnpm build +``` + +#### 安装一个包 + +``` +pnpm add 包名 +``` + +#### 卸载一个包 + +``` +pnpm remove 包名 +``` diff --git "a/docs/01.\346\214\207\345\215\227/01.\346\214\207\345\215\227/03.\347\233\256\345\275\225\347\273\223\346\236\204.md" "b/docs/01.\346\214\207\345\215\227/01.\346\214\207\345\215\227/03.\347\233\256\345\275\225\347\273\223\346\236\204.md" new file mode 100644 index 0000000..c792731 --- /dev/null +++ "b/docs/01.\346\214\207\345\215\227/01.\346\214\207\345\215\227/03.\347\233\256\345\275\225\347\273\223\346\236\204.md" @@ -0,0 +1,145 @@ +--- +title: 目录结构 +article: false +date: 2022-12-03 +permalink: /pages/directory +--- + +[完整版](https://github.com/ronnaces/ronna-admin)目录结构 + +``` +├── .github # GitHub 配置文件 +│ ├── ISSUE_TEMPLATE # 问题提交参考模板 +│ ├── workflows git # 工作流 +├── .husky # 代码提交前校验配置文件 +├── .vscode # IDE 工具推荐配置文件 +│ │ ├── extensions.json # 一键安装平台推荐的 vscode 插件 +│ │ ├── settings.json # 设置扩展程序或 vscode 编辑器的一些属性 +│ │ ├── vue3.0.code-snippets # vue3.0 代码片段 +│ │ └── vue3.2.code-snippets # vue3.2 代码片段 +│ │ └── vue3.3.code-snippets # vue3.3 代码片段 +├── build # 构建工具 +│ │ ├── cdn.ts # 打包时采用 cdn 模式 +│ │ ├── compress.ts # 打包时启用 gzip 压缩或 brotli 压缩 +│ │ ├── info.ts # 输出打包信息(大小、用时) +│ │ ├── optimize.ts # vite 依赖预构建配置项 +│ │ ├── plugins.ts # vite 相关插件存放处 +│ │ ├── utils.ts # 构建工具常用方法抽离 +├── locales # 国际化文件存放处 +│ │ ├── en.yaml # 英文配置 +│ │ ├── zh-CN.yaml # 中文配置 +├── mock # mock 模拟后台数据 +│ │ ├── asyncRoutes.ts # 模拟后台返回动态路由 +│ │ ├── ... +├── node_modules # 模块依赖 +├── public # 静态资源 +│ │ ├── audio # 音频文件 +│ │ ├── html # 静态 iframe 页面 +│ │ ├── wasm # wasm 文件以及胶水代码 +│ │ ├── favicon.ico # favicon +│ │ ├── logo.svg # logo +│ │ ├── platform-config.json # 全局配置文件(打包后修改也可生效) +├── src +│ ├── api # 接口请求统一管理 +│ ├── assets # 字体、图片等静态资源 +│ ├── components # 自定义通用组件 +│ │ ├── ReAnimateSelector # [animate.css](https://animate.style/) 选择器组件 +│ │ ├── ReAuth # 按钮级别权限组件 +│ │ ├── ReBarcode # 条形码组件 +│ │ ├── ReCol # 封装 element-plus 的 el-col 组件 +│ │ ├── ReCountTo # 数字动画组件 +│ │ ├── ReCropper # 图片裁剪组件 +│ │ ├── ReDialog # 基于 element-plus 中 el-dialog 组件开发的函数式弹框 +│ │ ├── ReFlicker # 圆点、方形闪烁动画组件 +│ │ ├── ReFlop # 时间翻牌组件 +│ │ ├── ReFlowChart # LogicFlow 流程图组件 +│ │ ├── ReIcon # 图标组件 +│ │ ├── ReImageVerify # 图形验证码组件 +│ │ ├── ReMap # 高德地图组件 +│ │ ├── RePureTableBar # 配合 `@pureadmin/table` 实现快速便捷的表格操作 https://github.com/ronnacespure-admin-table */ +│ │ ├── ReQrcode # 二维码组件 +│ │ ├── ReSeamlessScroll # 无缝滚动组件 +│ │ ├── ReSegmented # 分段控制器组件 +│ │ ├── ReSelector # 选择器组件 +│ │ ├── ReSplitPane # 切割面板组件 +│ │ ├── ReText # 支持 Tooltip 提示的文本省略组件 +│ │ ├── ReTreeLine # 树形连接线组件(基于element-plus) +│ │ ├── ReTypeit # 打字机效果组件 +│ ├── config # 获取平台动态全局配置 +│ ├── directives # 自定义指令 +│ │ ├── auth # 按钮级别权限指令 +│ │ ├── copy # 文本复制指令(默认双击复制) +│ │ ├── longpress # 长按指令 +│ │ ├── optimize # 防抖、节流指令 +│ ├── layout # 主要页面布局 +│ ├── plugins # 处理一些库或插件,导出更方便的 api +│ ├── router # 路由配置 +│ ├── store # pinia 状态管理 +│ ├── style # 全局样式 +│ │ ├── dark.scss # 暗黑模式样式适配文件 +│ │ ├── element-plus.scss # 全局覆盖 element-plus 样式文件 +│ │ ├── reset.scss # 全局重置样式文件 +│ │ ├── sidebar.scss # layout 布局样式文件 +│ │ ├── tailwind.css # tailwindcss 自定义样式配置文件 +│ │ ├── ... +│ ├── utils # 全局工具方法 +│ │ ├── http # 封装 axios 文件 +│ │ ├── localforage # 二次封装 localforage (https://localforage.docschina.org/) 支持设置过期时间,提供完整的类型提示 +│ │ ├── progress # 封装 nprogress +│ │ └── auth.ts # 处理用户信息和 token 相关 +│ │ └── chinaArea.ts # 汉字转区域码 +│ │ └── globalPolyfills.ts # 解决项目可能因为安装某个依赖出现 `global is not defined` 报错 +│ │ └── message.ts # 消息提示函数 +│ │ ├── mitt.ts # 触发公共事件,类似 EventBus +│ │ ├── preventDefault.ts # 阻止键盘F12、浏览器默认右键菜单、页面元素选中、图片默认可拖动的方法 +│ │ ├── print.ts # 打印函数 +│ │ ├── propTypes.ts # 二次封装 vue 的 propTypes +│ │ ├── responsive.ts # 全局响应式 storage 配置 +│ │ ├── sso.ts # 前端单点登录逻辑处理 +│ │ ├── tree.ts # 树结构相关处理函数 +│ ├── views # 存放编写业务代码页面 +│ ├── App.vue # 入口页面 +│ ├── main.ts # 入口文件 +├── types # 全局 TS 类型配置 +│ │ ├── global-components.d.ts # 自定义全局组件获得 Volar 提示(自定义的全局组件需要在这里声明下才能获得 Volar 类型提示哦) +│ │ ├── global.d.ts # 全局类型声明,无需引入直接在 `.vue` 、`.ts` 、`.tsx` 文件使用即可获得类型提示 +│ │ ├── index.d.ts # 此文件跟同级目录的 global.d.ts 文件一样也是全局类型声明,只不过这里存放一些零散的全局类型,无需引入直接在 .vue 、.ts 、.tsx 文件使用即可获得类型提示 +│ │ ├── router.d.ts # 全局路由类型声明 +│ │ ├── shims-tsx.d.ts # 该文件是为了给 .tsx 文件提供类型支持,在编写时能正确识别语法 +│ │ └── shims-vue.d.ts # .vue、.scss 文件不是常规的文件类型,typescript 无法识别,所以我们需要通过下图的代码告诉 typescript 这些文件的类型,防止类型报错 +├── .browserslistrc # 配置目标浏览器的环境 +├── .dockerignore # 排除不需要上传到 docker 服务端的文件或目录 +├── .editorconfig # 编辑器读取文件格式及样式定义配置 https://editorconfig.org/ +├── .env # 全局环境变量配置(当 .env 文件与 .env.development、.env.production、.env.staging 这三个文件之一存在相同的配置 key 时,.env 优先级更低) +├── .env.development # 开发环境变量配置 +├── .env.production # 生产环境变量配置 +├── .env.staging # 预发布环境变量配置 +├── .eslintignore # eslint 语法检查忽略文件 +├── .gitattributes # 自定义指定文件属性 +├── .gitignore # git 提交忽略文件 +├── .gitpod.yml # gitpod 部署配置 +├── .lintstagedrc # lint-staged 配置 +├── .markdownlint.json # markdown 格式检查配置 +├── .npmrc # npm 配置文件 +├── .nvmrc # 用于指定在使用 Node Version Manager(NVM)时要使用的特定 Node.js 版本 +├── .prettierignore # prettier 语法检查忽略文件 +├── .prettierrc.js # prettier 插件配置 +├── .stylelintignore # stylelint 语法检查忽略文件 +├── CHANGELOG.en_US.md # 版本更新日志(英文版) +├── CHANGELOG.md # 版本更新日志(英文版) +├── CHANGELOG.zh_CN.md # 版本更新日志(中文版) +├── commitlint.config.js # git 提交前检查配置 +├── Dockerfile # 用来构建 docker 镜像 +├── eslint.config.js # eslint 语法检查配置 +├── index.html # html 主入口 +├── LICENSE # 证书 +├── package.json # 依赖包管理以及命令配置 +├── pnpm-lock.yaml # 依赖包版本锁定文件 +├── postcss.config.js # postcss 插件配置 +├── README.en-US.md # README(英文版) +├── README.md # README +├── stylelint.config.js # stylelint 配置 +├── tailwind.config.ts # tailwindcss 配置 +├── tsconfig.json # typescript 配置 +└── vite.config.ts # vite 配置 +``` diff --git "a/docs/01.\346\214\207\345\215\227/01.\346\214\207\345\215\227/04.vscode\346\226\207\344\273\266\345\244\271\350\257\246\350\247\243.md" "b/docs/01.\346\214\207\345\215\227/01.\346\214\207\345\215\227/04.vscode\346\226\207\344\273\266\345\244\271\350\257\246\350\247\243.md" new file mode 100644 index 0000000..d005cc7 --- /dev/null +++ "b/docs/01.\346\214\207\345\215\227/01.\346\214\207\345\215\227/04.vscode\346\226\207\344\273\266\345\244\271\350\257\246\350\247\243.md" @@ -0,0 +1,42 @@ +--- +title: .vscode文件夹详解 +article: false +date: 2022-11-07 +permalink: /pages/vscode/ +--- + +平台内置很多实用的 [vscode 插件](https://github.com/ronnaces/ronna-admin/blob/main/.vscode/extensions.json),为了提高开发效率,您可以选择使用 [vscode](https://code.visualstudio.com/) 编辑器 + +## extensions.json + +一键安装平台推荐的 `vscode` 插件,安装方法如下图 + +![recommended1](~@alias/img/guide/recommended1.jpg) + +![recommended2](~@alias/img/guide/recommended2.jpg) + +## settings.json + +设置扩展程序或 `vscode` 编辑器的一些属性 + +## vue3.0.code-snippets + +`vue3.0` 版本代码片段。在 `.vue` 文件输入 `vue` 即可看到如下图的选项,选择 `Vue3.0` 即可生成 + +![snip3.0](~@alias/img/guide/snip30.jpg) + +## vue3.2.code-snippets + +`vue3.2` 版本代码片段(支持 ` +``` + +#### `.vue` 文件中使用(非 `setup` 语法) + +```Vue + +``` + +#### `.ts` 或 `.vue` 中使用 + +具体实现代码位置 [config/index.ts](https://github.com/ronnaces/ronna-admin/blob/main/src/config/index.ts#L11) + +```Ts +import { getConfig } from "@/config"; + +console.log("Version:", getConfig()?.Version) +``` + +### 如何添加自定义配置 + +比如要添加的自定义配置为 `Handsome: true` + +① 在 `platform-config.json` 中加入 `Handsome: true`,具体如下 + +```json +{ + "Handsome": true // 自定义配置 +} +``` + +② 加入类型支持,在 [interface PlatformConfigs](https://github.com/ronnaces/ronna-admin/blob/main/types/global.d.ts#L84) 里加上 `Handsome?: boolean`,具体如下 + +```Ts +interface PlatformConfigs { + Handsome?: boolean; // 根据实际类型编写 +} +``` + +## `package.json` + +[package.json](https://github.com/ronnaces/ronna-admin/blob/main/package.json#L6-24) 文件中的 `scripts` 配置中存放平台的各种命令,具体如下 + +```json +{ + "scripts": { + "dev": "NODE_OPTIONS=--max-old-space-size=4096 vite", // 启动平台 + "serve": "pnpm dev", // 启动平台(有人喜欢dev、有人喜欢serve) + "build": "rimraf dist && NODE_OPTIONS=--max-old-space-size=8192 vite build", // 打包平台(rimraf 包的作用:以包的形式包装rm -rf命令,用来删除文件和文件夹的,不管文件夹是否为空,都可删除) + "build:staging": "rimraf dist && vite build --mode staging", // 打包平台(预发布环境) + "report": "rimraf dist && vite build", // 打包平台并生产平台包文件大小图形化分析 + "preview": "vite preview", // 预览平台,需先打包(无需安装live-server等工具,vite自带预览功能) + "preview:build": "pnpm build && vite preview", // 打包并预览平台(无需安装live-server等工具,vite自带预览功能) + "typecheck": "tsc --noEmit && vue-tsc --noEmit --skipLibCheck", // 使用vue-tsc工具对指定的.ts、.tsx、.vue文件进行类型校验 + "svgo": "svgo -f . -r", // 压缩当前目录下的所有SVG文件,更多详情看 https://github.com/ronnaces/ronna-admin/commit/a114dbb4652d6316853d75ff127180fc07d07d2b#commitcomment-136451628 + "cloc": "NODE_OPTIONS=--max-old-space-size=4096 cloc . --exclude-dir=node_modules --exclude-lang=YAML", // 平台文件、语言分析 + "clean:cache": "rimraf .eslintcache && rimraf node_modules && pnpm install", // 删除node_modules、清空eslint缓存并重新安装平台依赖 + "lint:eslint": "eslint --cache --max-warnings 0 \"{src,mock,build}/**/*.{vue,js,ts,tsx}\" --fix", // eslint修复 + "lint:prettier": "prettier --write \"src/**/*.{js,ts,json,tsx,css,scss,vue,html,md}\"", // prettier格式化 + "lint:stylelint": "stylelint --cache --fix \"**/*.{html,vue,css,scss}\" --cache --cache-location node_modules/.cache/stylelint/", // stylelint格式化修复 + "lint": "pnpm lint:eslint && pnpm lint:prettier && pnpm lint:stylelint", // 平台整体lint格式化并修复 + "prepare": "husky", // 自动生成husky(https://typicode.github.io/husky/#/) + "preinstall": "npx only-allow pnpm" // 只允许运行pnpm命令,如果您换成yarn、npm需要把这行删除(https://pnpm.io/zh/only-allow-pnpm) + } +} +``` diff --git "a/docs/01.\346\214\207\345\215\227/01.\346\214\207\345\215\227/06.\345\270\203\345\261\200.md" "b/docs/01.\346\214\207\345\215\227/01.\346\214\207\345\215\227/06.\345\270\203\345\261\200.md" new file mode 100644 index 0000000..b1e31c7 --- /dev/null +++ "b/docs/01.\346\214\207\345\215\227/01.\346\214\207\345\215\227/06.\345\270\203\345\261\200.md" @@ -0,0 +1,46 @@ +--- +title: 布局 +article: false +date: 2022-11-07 +permalink: /pages/layout/ +--- + +## 左侧菜单模式 + +![vertical](~@alias/img/layout/vertical.jpg) + +::: details 查看介绍 + +[代码实现](https://github.com/ronnaces/ronna-admin/blob/main/src/layout/components/sidebar/vertical.vue) + +![vertical-detail](~@alias/img/layout/vertical-detail.jpg) + +::: + +## 顶部菜单模式 + +![horizontal](~@alias/img/layout/horizontal.jpg) + +::: details 查看介绍 + +[代码实现](https://github.com/ronnaces/ronna-admin/blob/main/src/layout/components/sidebar/horizontal.vue) + +![horizontal-detail](~@alias/img/layout/horizontal-detail.jpg) + +::: + +## 综合菜单模式 + +![mixNav](~@alias/img/layout/mixNav.jpg) + +::: details 查看介绍 + +[代码实现](https://github.com/ronnaces/ronna-admin/blob/main/src/layout/components/sidebar/mixNav.vue) + +![mixNav-detail](~@alias/img/layout/mixNav-detail.jpg) + +::: + +## 左侧双栏模式 + +[计划中](https://github.com/ronnaces/ronna-admin/issues) diff --git "a/docs/01.\346\214\207\345\215\227/01.\346\214\207\345\215\227/07.\350\267\257\347\224\261\345\222\214\350\217\234\345\215\225.md" "b/docs/01.\346\214\207\345\215\227/01.\346\214\207\345\215\227/07.\350\267\257\347\224\261\345\222\214\350\217\234\345\215\225.md" new file mode 100644 index 0000000..f25ee16 --- /dev/null +++ "b/docs/01.\346\214\207\345\215\227/01.\346\214\207\345\215\227/07.\350\267\257\347\224\261\345\222\214\350\217\234\345\215\225.md" @@ -0,0 +1,1139 @@ +--- +title: 路由和菜单 +article: false +date: 2022-12-07 +permalink: /pages/routerMenu/ +--- + +路由和菜单是极为重要的,配置正确很关键,平台尽最大可能详细描述 + +## 路由和菜单配置 + +::: details 点击查看完整路由和菜单配置 + +```Ts +interface RouteConfigsTable { + // 路由路径 + path: string; + // 路由名称(必须保持唯一) + name: string; + // 路由重定向(默认跳转地址) + redirect: string; + // 路由元信息,通俗来说就是路由上的额外信息 https://router.vuejs.org/zh/guide/advanced/meta.html#%E8%B7%AF%E7%94%B1%E5%85%83%E4%BF%A1%E6%81%AF + meta: { + // 菜单名称(兼容国际化、非国际化,如果用国际化的写法就必须在根目录的locales文件夹下对应添加) + title: string; + // 菜单图标 + icon: string | FunctionalComponent | IconifyIcon; + // 是否在菜单中显示 + showLink: boolean; + // 菜单排序,值越高排的越后(只针对顶级路由) + rank: number; + }; + // 子路由配置项 + children: [ + { + // 路由路径 + path: string; + // 路由名称(必须唯一并且和当前路由component字段对应的页面里用defineOptions包起来的name保持一致) + name: string; + // 路由重定向 + redirect: string; + // 按需加载需要展示的页面 + component: RouteComponent; + // 路由元信息 + meta: { + // 菜单名称(兼容国际化、非国际化,如果用国际化的写法就必须在根目录的locales文件夹下对应添加) + title: string; + // 菜单图标 + icon: string | FunctionalComponent | IconifyIcon; + // 菜单名称右侧的额外图标 + extraIcon: string | FunctionalComponent | IconifyIcon; + // 是否显示该菜单 + showLink: boolean; + // 是否显示父级菜单 + showParent: boolean; + // 页面级别权限设置 + roles: Array; + // 按钮级别权限设置 + auths: Array; + // 是否缓存该路由页面(开启后,会保存该页面的整体状态,刷新后会清空状态) + keepAlive: boolean; + // 需要内嵌的iframe链接地址 + frameSrc: string; + // 内嵌的iframe页面是否开启首次加载动画 + frameLoading: boolean; + // 页面加载动画(两种模式,第二种权重更高,第一种直接采用vue内置的transitions动画,第二种是使用animate.css编写进、离场动画,平台更推荐使用第二种模式,已经内置了animate.css,直接写对应的动画名即可) + transition: { + // 当前页面动画,这里是第一种模式,比如 name: "fade" 更具体看后面链接 https://cn.vuejs.org/api/built-in-components.html#transition + name: string; + // 当前页面进场动画,这里是第二种模式,比如 enterTransition: "animate__fadeInLeft" + enterTransition: string; + // 当前页面离场动画,这里是第二种模式,比如 leaveTransition: "animate__fadeOutRight" + leaveTransition: string; + }; + // 当前菜单名称或自定义信息禁止添加到标签页 + hiddenTag: boolean; + // 显示在标签页的最大数量,需满足后面的条件:不显示在菜单中的路由并且是通过query或params传参模式打开的页面。在完整版全局搜dynamicLevel即可查看代码演示 + dynamicLevel: number; + // 将某个菜单激活(主要用于通过query或params传参的路由,当它们通过配置showLink: false后不在菜单中显示,就不会有任何菜单高亮,而通过设置activePath指定激活菜单即可获得高亮,activePath为指定激活菜单的path) + activePath: string; + }; + }, + ], +}; +``` + +::: + +## 静态路由 + +在前端代码里写上固定的路由即静态路由。平台支持任意层级菜单格式,下面列举最常用的菜单层级模式,更深层级按照下面格式即可 + +:::tip 阅读前须知 +一般来说一级菜单代表无任何子菜单的菜单,二级菜单代表一级菜单下面有子菜单,三级菜单代表二级菜单下面有子菜单 以此类推 +::: + +### 如何生成一级菜单 + +::: details + +比如我们要生成一个名为 `加油` 的菜单 + +1. 新建 `src/router/modules/welcome.ts` 文件,加入如下代码 + +`fighting.ts` + +```Ts +// 最简代码,也就是这些字段必须有 +export default { + path: "/", + name: "Home", + component: Layout, + redirect: "/welcome", + meta: { + icon: "ep:home-filled", + title: $t("menus.hshome"), + rank: home + }, + children: [ + { + path: "/welcome", + name: "Welcome", + component: () => import("@/views/welcome/index.vue"), + meta: { + title: $t("menus.hshome"), + showLink: VITE_HIDE_HOME === "true" ? false : true + } + } + ] +} satisfies RouteConfigsTable; +``` + +2. 新建 `src/views/fighting/index.vue` 文件,加入如下代码 + +`index.vue` + +```Vue + + + +``` + +上面所写代码如下图效果 + +![static1](~@alias/img/router/static1.jpg) + +::: + +### 如何生成二级菜单(两种模式) + +#### 第一种(该模式针对父级菜单下只有一个子菜单的情况,在子菜单的 `meta` 属性中加上 `showParent: true` 即可) + +::: details 点击查看 + +```Ts +// 最简代码,也就是这些字段必须有 +export default { + path: "/fighting", + meta: { + title: "励志" + }, + children: [ + { + path: "/fighting/index", + name: "Fighting", + component: () => import("@/views/fighting/index.vue"), + meta: { + title: "加油", + // 通过设置showParent为true,显示父级 + showParent: true + } + } + ] +}; +``` + +如下图效果 + +![static2](~@alias/img/router/static2.jpg) + +::: + +#### 第二种(该模式针对父级菜单下有大于或等于两个子菜单的情况) + +::: details 点击查看 + +```Ts +// 最简代码,也就是这些字段必须有 +export default { + path: "/fighting", + meta: { + title: "励志" + }, + children: [ + { + path: "/fighting/index", + name: "Fighting", + component: () => import("@/views/fighting/index.vue"), + meta: { + title: "加油" + } + }, + { + path: "/fighting/effort", + name: "Effort", + component: () => import("@/views/fighting/effort.vue"), + meta: { + title: "努力" + } + } + ] +}; +``` + +如下图效果 + +![static3](~@alias/img/router/static3.jpg) + +::: + +### 如何生成三级菜单(两种模式) + +#### 第一种(该模式针对父级菜单下只有一个子菜单的情况,在子菜单的 `meta` 属性中加上 `showParent: true` 即可) + +::: details 点击查看 + +```Ts +// 最简代码,也就是这些字段必须有 +export default { + path: "/nested", + meta: { + title: "多级菜单" + }, + children: [ + { + path: "/nested/menu1", + meta: { + title: "菜单1" + }, + children: [ + { + path: "/nested/menu1/menu1-1", + component: () => import("@/views/nested/menu1/menu1-1/index.vue"), + name: "Menu1-1", + meta: { + title: "菜单1-1", + // 通过设置showParent为true,显示父级 + showParent: true + } + } + ] + } + ] +}; +``` + +如下图效果 + +![static4](~@alias/img/router/static7.jpg) + +::: + +#### 第二种(该模式针对父级菜单下有大于或等于两个子菜单的情况) + +::: details 点击查看 + +```Ts +// 最简代码,也就是这些字段必须有 +export default { + path: "/nested", + meta: { + title: "多级菜单" + }, + children: [ + { + path: "/nested/menu1", + meta: { + title: "菜单1" + }, + children: [ + { + path: "/nested/menu1/menu1-1", + component: () => import("@/views/nested/menu1/menu1-1/index.vue"), + name: "Menu1-1", + meta: { + title: "菜单1-1" + } + }, + { + path: "/nested/menu1/menu1-2", + component: () => import("@/views/nested/menu1/menu1-2/index.vue"), + name: "Menu1-2", + meta: { + title: "菜单1-2" + } + } + ] + } + ] +}; +``` + +如下图效果 + +![static5](~@alias/img/router/static7.jpg) + +::: + +### 如何生成四级菜单(两种模式) + +#### 第一种(该模式针对父级菜单下只有一个子菜单的情况,在子菜单的 `meta` 属性中加上 `showParent: true` 即可) + +::: details 点击查看 + +```Ts +// 最简代码,也就是这些字段必须有 +export default { + path: "/nested", + meta: { + title: "多级菜单" + }, + children: [ + { + path: "/nested/menu1", + meta: { + title: "菜单1" + }, + children: [ + { + path: "/nested/menu1/menu1-1", + meta: { + title: "菜单1-1" + }, + children: [ + { + path: "/nested/menu1/menu1-1/menu1-1-1", + component: () => + import("@/views/nested/menu1/menu1-1/menu1-1-1/index.vue"), + name: "Menu1-1-1", + meta: { + title: "菜单1-1-1", + // 通过设置showParent为true,显示父级 + showParent: true + } + } + ] + } + ] + } + ] +}; +``` + +如下图效果 + +![static6](~@alias/img/router/static7.jpg) + +::: + +#### 第二种(该模式针对父级菜单下有大于或等于两个子菜单的情况) + +::: details 点击查看 + +```Ts +// 最简代码,也就是这些字段必须有 +export default { + path: "/nested", + meta: { + title: "多级菜单" + }, + children: [ + { + path: "/nested/menu1", + meta: { + title: "菜单1" + }, + children: [ + { + path: "/nested/menu1/menu1-1", + meta: { + title: "菜单1-1" + }, + children: [ + { + path: "/nested/menu1/menu1-1/menu1-1-1", + component: () => + import("@/views/nested/menu1/menu1-1/menu1-1-1/index.vue"), + name: "Menu1-1-1", + meta: { + title: "菜单1-1-1" + } + }, + { + path: "/nested/menu1/menu1-1/menu1-1-2", + component: () => + import("@/views/nested/menu1/menu1-1/menu1-1-2/index.vue"), + name: "Menu1-1-2", + meta: { + title: "菜单1-1-2" + } + } + ] + } + ] + } + ] +}; +``` + +如下图效果 + +![static7](~@alias/img/router/static7.jpg) + +::: + +### 注意点 + +#### 国际化 + +只需要在路由 `meta` 的 `title` 字段中使用国际化写法即可,比如 `title: "menus.hsabnormal"` +这个 `menus.hsabnormal` 必须在 `locales` 文件夹下进行配置哦,如下图 + +![static12](~@alias/img/router/static12.jpg) + +#### 重定向 + +可以看到上面生成菜单的路由配置项我并没有加上 `redirect` 属性,当使用 `fighting` 路径跳转时,就会跑到 `404` 页面 + + +所以我们最好在写静态路由配置时将父级加上 `redirect` 属性,`redirect` 可以填写您想要重定向的 `path` 即可,具体可以参考 [src/router/modules/nested.ts](https://github.com/ronnaces/ronna-admin/blob/main/src/router/modules/nested.ts) + +#### 类型提示 + +分两种 + +1. `export default` 后跟 `{}`,这也是最常用的一种,在路由的配置项最后加上 `satisfies RouteConfigsTable` 即可获得类型提示,如下图 + +![static10](~@alias/img/router/static10.jpg) + +2. `export default` 后跟 `[]`,在路由的配置项最后加上 `as Array` 即可获得类型提示,如下图 + +![static11](~@alias/img/router/static11.jpg) + +:::tip 您肯定想问 RouteConfigsTable 是哪里来的呢? +[我在这呢,快快点我查看 😊](https://github.com/ronnaces/ronna-admin/blob/main/types/global.d.ts#L223) +::: + +#### 添加无 `layout` 的页面 + +使用场景:需要外嵌平台某个页面,不需要展示菜单导航以及额外模块,只需要展示业务内容模块 +无 `layout` 页面也就相当于一个全屏空白页面,没有菜单导航以及额外模块 + +如何添加? + +1. 在 `src/router/modules/remaining.ts` 文件添加对应路由 [具体参考](https://github.com/ronnaces/ronna-admin/blob/main/src/router/modules/remaining.ts#L32) + +2. 添加对应业务代码页面 [具体参考](https://github.com/ronnaces/ronna-admin/tree/main/src/views/empty) + +:::tip 温馨提示 +必须在 `src/router/modules/remaining.ts` 文件添加哦 +::: + +#### 禁止修改或删除的路由 + +`src/router/modules` 文件夹里的 `home.ts`、`remaining.ts`、`error.ts` 这三个文件不可修改或删除,因为平台的某些核心逻辑是根据这三个文件作处理 + +![static8](~@alias/img/router/static8.jpg) + +如果不想在页面显示,在顶级路由的 `meta` 属性加上 `showLink: false` 即可,如下图 + +![static9](~@alias/img/router/static9.jpg) + +### 如何只要静态路由 + +平台在登录时默认会走 [getAsyncRoutes](https://github.com/ronnaces/ronna-admin/blob/main/src/router/utils.ts#L30) 接口请求后端返回的动态路由,默认用 [mock](https://github.com/ronnaces/ronna-admin/blob/main/mock/asyncRoutes.ts) 模拟返回,如果只要静态路由,按照下面两个步骤修改即可 + +1. 在 `src/views/login/index.vue` 文件作如下改动 + +```Vue + +``` + +![static13](~@alias/img/router/static13.jpg) + +2. 在 `src/router/index.ts` 文件作如下改动 + +```ts +import { addPathMatch } from "./utils"; + +// 使用下面方法替换initRouter +usePermissionStoreHook().handleWholeMenus([]); +addPathMatch(); +if (!useMultiTagsStoreHook().getMultiTagsCache) { + const { path } = to; + const route = findRouteByPath(path, router.options.routes[0].children); + // query、params模式路由传参数的标签页不在此处处理 + if (route && route.meta?.title) { + useMultiTagsStoreHook().handleTags("push", { + path: route.path, + name: route.name, + meta: route.meta, + }); + } +} +``` + +![static15](~@alias/img/router/static15.jpg) +![static16](~@alias/img/router/static16.jpg) + +## 动态路由 + +后端返回的路由即动态路由。平台支持任意层级菜单格式,下面列举最常用的菜单层级模式,更深层级按照下面格式即可 + +平台用 `mock` 模拟后端,下面举例也是用 `mock` 举例哦,当然和后端返回的路由格式是一模一样的 + +:::tip 阅读前须知 + +后端传 `path` 或传 `component`,平台对这两种模式都做了兼容 [具体实现代码 1](https://github.com/ronnaces/ronna-admin/blob/main/src/router/utils.ts#L27) [具体实现代码 2](https://github.com/ronnaces/ronna-admin/blob/main/src/router/utils.ts#L296) + +`第一种`:下面所有生成菜单例子中的 `path` 都有个规则:如果这个 `path` 对应的是实际业务 `.vue` 或 `.tsx` 代码,就必须跟实际业务 `.vue` 或 `.tsx` 代码路径保持一致 + +`第二种`:菜单的 `component` 对应实际业务 `.vue` 或 `.tsx` 代码路径,这时 `path` 可以随便写啦,但是前面必须有个 `/` ,比如 `path: '/anything'` (这种情况我只在 [如何生成一级菜单](#如何生成一级菜单-2) 里举例,多级菜单写法类似) + +::: details 点击查看具体实现代码逻辑解析 + +```Ts {4,14,28,29,30,31} +// 具体实现代码1高亮处解析: +// 将/src/views/文件里所有的.vue和.tsx文件塞进modulesRoutes变量 +// 当然这里只匹配了`.vue`和`.tsx`,如果您想匹配别的在下面 {} 加上即可,记得用 , 分开 +const modulesRoutes = import.meta.glob("/src/views/**/*.{vue,tsx}"); + +// 具体实现代码2高亮处解析: +// addAsyncRoutes函数作用为过滤后端传来的动态路由,重新生成规范路由, +// 先读取后端返回的所有路由,从中过滤出component和path字段,然后在modulesRoutesKeys中对应匹配, +// 如果对应路由同时匹配到component和path,优先以component为主,这样您的path路径就可以随便写啦, +// 如果匹配到path未匹配到component,path必须按上面提到的跟实际业务`.vue`或`.tsx`代码路径保持一致, +// 如果匹配到component未匹配到path或者两个都未匹配到,我想问问您咱能好好玩不😭 +function addAsyncRoutes(arrRoutes: Array) { + if (!arrRoutes || !arrRoutes.length) return; + const modulesRoutesKeys = Object.keys(modulesRoutes); + arrRoutes.forEach((v: RouteRecordRaw) => { + // 将backstage属性加入meta,标识此路由为后端返回路由 + v.meta.backstage = true; + // 父级的redirect属性取值:如果子级存在且父级的redirect属性不存在,默认取第一个子级的path;如果子级存在且父级的redirect属性存在,取存在的redirect属性,会覆盖默认值 + if (v?.children && v.children.length && !v.redirect) + v.redirect = v.children[0].path; + // 父级的name属性取值:如果子级存在且父级的name属性不存在,默认取第一个子级的name;如果子级存在且父级的name属性存在,取存在的name属性,会覆盖默认值(注意:测试中发现父级的name不能和子级name重复,如果重复会造成重定向无效(跳转404),所以这里给父级的name起名的时候后面会自动加上`Parent`,避免重复) + if (v?.children && v.children.length && !v.name) + v.name = (v.children[0].name as string) + "Parent"; + if (v.meta?.frameSrc) { + v.component = IFrame; + } else { + // 对后端传component组件路径和不传做兼容(如果后端传component组件路径,那么path可以随便写,如果不传,component组件路径会跟path保持一致) + const index = v?.component + ? modulesRoutesKeys.findIndex(ev => ev.includes(v.component as any)) + : modulesRoutesKeys.findIndex(ev => ev.includes(v.path)); + v.component = modulesRoutes[modulesRoutesKeys[index]]; + } + if (v?.children && v.children.length) { + addAsyncRoutes(v.children); + } + }); + return arrRoutes; +} +``` + +::: + +### 如何生成一级菜单 + +#### 只传 `path` 模式 + +::: details + +比如我们要生成一个名为 `加油` 的菜单 + +1. 来到 `mock/asyncRoutes.ts` 文件,加入如下代码 + +`asyncRoutes.ts` + +```Ts +// 最简代码,也就是这些字段必须有 +const fightingRouter = { + path: "/fighting", + meta: { + title: "加油" + }, + children: [ + { + path: "/fighting/index", + name: "Fighting", + meta: { + title: "加油" + } + } + ] +}; +``` + +2. 新建 `src/views/fighting/index.vue` 文件,加入如下代码 + +`index.vue` + +```Vue + + + +``` + +上面所写代码如下图效果 + +![async1](~@alias/img/router/static11.jpg) + +::: + +#### 传 `path` 和 `component` 模式 + +::: details + +比如我们要生成一个名为 `加油` 的菜单 + +1. 来到 `mock/asyncRoutes.ts` 文件,加入如下代码 + +`asyncRoutes.ts` + +```Ts +// 最简代码,也就是这些字段必须有 +const fightingRouter = { + path: "/fighting", + meta: { + title: "加油" + }, + children: [ + { + // path随便写,但前面必须有个 `/` + path: "/anything", + // component对应的值前不需要加 / 值对应的是实际业务 `.vue` 或 `.tsx` 代码路径 + component: "fighting/index", + name: "Fighting", + meta: { + title: "加油" + } + } + ] +}; +``` + +2. 新建 `src/views/fighting/index.vue` 文件,加入如下代码 + +`index.vue` + +```Vue + + + +``` + +上面所写代码如下图效果 + +![async2](~@alias/img/router/static11.jpg) + +:::tip 猜您可能有这种想法 🤔️ + +![async3](~@alias/img/router/static11.jpg) + +::: + +### 如何生成二级菜单(两种模式) + +#### 第一种(该模式针对父级菜单下只有一个子菜单的情况,在子菜单的 `meta` 属性中加上 `showParent: true` 即可) + +::: details 点击查看 + +```Ts +// 最简代码,也就是这些字段必须有 +const fightingRouter = { + path: "/fighting", + meta: { + title: "励志" + }, + children: [ + { + path: "/fighting/index", + name: "Fighting", + meta: { + title: "加油", + // 通过设置showParent为true,显示父级 + showParent: true + } + } + ] +}; +``` + +如下图效果 + +![async4](~@alias/img/router/static11.jpg) + +::: + +#### 第二种(该模式针对父级菜单下有大于或等于两个子菜单的情况) + +::: details 点击查看 + +```Ts +// 最简代码,也就是这些字段必须有 +const fightingRouter = { + path: "/fighting", + meta: { + title: "励志" + }, + children: [ + { + path: "/fighting/index", + name: "Fighting", + meta: { + title: "加油" + } + }, + { + path: "/fighting/effort", + name: "Effort", + meta: { + title: "努力" + } + } + ] +}; +``` + +如下图效果 + +![async5](~@alias/img/router/static11.jpg) + +::: + +### 如何生成三级菜单(两种模式) + +#### 第一种(该模式针对父级菜单下只有一个子菜单的情况,在子菜单的 `meta` 属性中加上 `showParent: true` 即可) + +::: details 点击查看 + +```Ts +// 最简代码,也就是这些字段必须有 +const nestedRouter = { + path: "/nested", + meta: { + title: "多级菜单" + }, + children: [ + { + path: "/nested/menu1", + meta: { + title: "菜单1" + }, + children: [ + { + path: "/nested/menu1/menu1-1/index", + name: "Menu1-1", + meta: { + title: "菜单1-1", + // 通过设置showParent为true,显示父级 + showParent: true + } + } + ] + } + ] +}; +``` + +如下图效果 + +![async6](~@alias/img/router/static11.jpg) + +::: + +#### 第二种(该模式针对父级菜单下有大于或等于两个子菜单的情况) + +::: details 点击查看 + +```Ts +// 最简代码,也就是这些字段必须有 +const nestedRouter = { + path: "/nested", + meta: { + title: "多级菜单" + }, + children: [ + { + path: "/nested/menu1", + meta: { + title: "菜单1" + }, + children: [ + { + path: "/nested/menu1/menu1-1/index", + name: "Menu1-1", + meta: { + title: "菜单1-1" + } + }, + { + path: "/nested/menu1/menu1-2/index", + name: "Menu1-2", + meta: { + title: "菜单1-2" + } + } + ] + } + ] +}; +``` + +如下图效果 + +![async7](~@alias/img/router/static11.jpg) + +::: + +### 如何生成四级菜单(两种模式) + +#### 第一种(该模式针对父级菜单下只有一个子菜单的情况,在子菜单的 `meta` 属性中加上 `showParent: true` 即可) + +::: details 点击查看 + +```Ts +// 最简代码,也就是这些字段必须有 +const nestedRouter = { + path: "/nested", + meta: { + title: "多级菜单" + }, + children: [ + { + path: "/nested/menu1", + meta: { + title: "菜单1" + }, + children: [ + { + path: "/nested/menu1/menu1-1", + meta: { + title: "菜单1-1" + }, + children: [ + { + path: "/nested/menu1/menu1-1/menu1-1-1/index", + name: "Menu1-1-1", + meta: { + title: "菜单1-1-1", + // 通过设置showParent为true,显示父级 + showParent: true + } + } + ] + } + ] + } + ] +}; +``` + +如下图效果 + +![async8](~@alias/img/router/static11.jpg) + +::: + +#### 第二种(该模式针对父级菜单下有大于或等于两个子菜单的情况) + +::: details 点击查看 + +```Ts +// 最简代码,也就是这些字段必须有 +const nestedRouter = { + path: "/nested", + meta: { + title: "多级菜单" + }, + children: [ + { + path: "/nested/menu1", + meta: { + title: "菜单1" + }, + children: [ + { + path: "/nested/menu1/menu1-1", + meta: { + title: "菜单1-1" + }, + children: [ + { + path: "/nested/menu1/menu1-1/menu1-1-1/index", + name: "Menu1-1-1", + meta: { + title: "菜单1-1-1" + } + }, + { + path: "/nested/menu1/menu1-1/menu1-1-2/index", + name: "Menu1-1-2", + meta: { + title: "菜单1-1-2" + } + } + ] + } + ] + } + ] +}; +``` + +如下图效果 + +![async9](~@alias/img/router/static11.jpg) + +::: + +### 注意点 + +#### 动态路由缓存本地 + +平台在 `v2.0.0` 版本 [默认关闭 CachingAsyncRoutes 动态路由缓存本地](https://github.com/ronnaces/ronna-admin/blob/main/public/platform-config.json#L19) 使其在开发环境下调试更方便,不用每次修改动态路由都要先清空本地缓存的动态路由,更推荐在生产环境开启 + +开启动态路由缓存本地后会优先读取本地缓存的路由 [点击查看具体实现代码](https://github.com/ronnaces/ronna-admin/blob/main/src/router/utils.ts#L195) 如果您在开发环境下开启,每次修改动态路由都需要先清空 `async-routes` 这个键名的 `sessionStorage` [点击查看参考代码](https://github.com/ronnaces/ronna-admin/blob/main/src/views/permission/page/index.vue#L37) + +#### 国际化 + +只需要在路由 `meta` 的 `title` 字段中使用国际化写法即可,比如 `title: "menus.hssysManagement"` +这个 `menus.hssysManagement` 必须在 `locales` 文件夹下进行配置哦,如下图 + +![async10](~@alias/img/router/async10.jpg) + +#### 重定向 + +动态路由无需填写 `redirect` 重定向属性 +平台自动处理,逻辑为:如果子级存在且父级的 `redirect` 属性不存在,默认取第一个子级的 `path` 作为父级的 `redirect` + +当然您也可以指定父级的 `redirect` 重定向属性,平台监测到存在指定父级的 `redirect` 后,会取指定的属性 + +[点击查看具体实现代码](https://github.com/ronnaces/ronna-admin/blob/main/src/router/utils.ts#L302-L304) + +#### 重置路由 + +平台的重置路由功能只针对动态路由 + +##### 常用场景 + +用户切换角色或退出登录时需调用重置路由功能,将路由和菜单恢复到初始化状态 + +##### 基础用法 + +```Ts +import { resetRouter } from "@/router"; + +resetRouter(); +``` + +##### 具体实现代码 + +[点击查看具体实现代码](https://github.com/ronnaces/ronna-admin/blob/main/src/router/index.ts#L83) + +## 静态路由、动态路由相同的配置 + +下面以动态路由返回举例,静态路由也是相同的配置,区别是静态路由需写在 `src/router/modules` 里 + +### 内嵌 `iframe` 和外链 + +::: details 点击查看 + +读重点:内嵌 `iframe` 将地址写进 `frameSrc` 属性里;外链将地址写进 `name` 属性里 +具体代码实现:[内嵌 `iframe`](https://github.com/ronnaces/ronna-admin/blob/main/src/layout/frameView.vue) [外链](https://github.com/ronnaces/ronna-admin/blob/main/src/router/index.ts#L130) + +```Ts +// 最简代码,也就是这些字段必须有 +const frameRouter = { + path: "/iframe", + meta: { + title: "内嵌 iframe 和外链" + }, + children: [ + // 内嵌 iframe + { + path: "/iframe/pure", + // name必须写,写法随意 + name: "anything", + meta: { + title: "内嵌 iframe", + // 需要内嵌页面的地址 + frameSrc: "https://yiming_chang.github.io/pure-admin-doc", + // 内嵌的iframe页面是否开启首次加载动画,默认true,下面可以不写,如果内嵌的iframe页面已经存在首加载动画,可以将frameLoading设为false + // frameLoading: true + } + }, + // 外链 + { + // path必须写,必须以 / 开头,推荐格式 / 后跟随意单词,不同的外链path不要重复哦 + path: "/anything", + // 外链地址写在name属性里 + name: "https://yiming_chang.github.io/pure-admin-doc", + meta: { + title: " 外链" + } + } + ] +}; +``` + +如下图效果 + +![same1](~@alias/img/router/same1.jpg) + +::: + +### 菜单排序 `rank` + +在路由的 `meta` 里加入 `rank` 字段即可对菜单进行排序,`rank` 可不写、可为 `null`、可为 `undefined`、可为空值,但是平台推荐 `rank` 最好加上,对菜单进行有序排列使其看起来整齐,而且还能通过排序把您想要第一眼看到的菜单放到最前面 + +[点击查看具体实现代码](https://github.com/ronnaces/ronna-admin/blob/main/src/router/utils.ts#L32-L53) + +:::tip 温馨提示 +菜单排序 `rank` 只对顶级菜单生效 [点击查看为何如此设计](https://github.com/ronnaces/ronna-admin/issues/154#issuecomment-996571156) +::: + +### 菜单图标 `icon` + +[点击查看如何配置菜单图标](/pages/icon/#导航菜单的-icon-如何配置) + +### 路由页面缓存 `keepAlive` + +在路由的 `meta` 里加入 `keepAlive: true` 即可对当前路由页面进行缓存,被缓存的路由页面不会被销毁 + +生效前提:对应页面 `name` 必须与路由的 `name` 保持一致 + +![same4](~@alias/img/router/same4.jpg) + +虽然 `vue-router` 官方只支持到二级 `keep-alive` 缓存,但平台对路由进行了 [处理](https://github.com/ronnaces/ronna-admin/blob/main/src/router/utils.ts#L248),只要对当前路由设置了 `keepAlive: true`,并且对应的页面 `name` 与路由的 `name` 保持一致,不管层级多深都会支持 `keep-alive` 缓存 + +### 页面进场、离场动画定制化 `transition` + +在路由的 `meta` 里加入下面代码即可定制化单个页面进场、离场动画,平台内置了 `Animate.css` ,所以您直接在 [Animate.css](https://animate.style/) 最右侧复制所需动画即可 + +```Ts +transition: { + // 页面进场动画 + enterTransition: "animate__fadeInRight", + // 页面离场动画 + leaveTransition: "animate__fadeOutDown" +} +``` + +[点击查看具体实现代码](https://github.com/ronnaces/ronna-admin/blob/main/src/layout/components/appMain.vue#L41-L73) + +### 页面和按钮级别权限设置 + +平台内置 `RBAC` 权限模式,无论静态还是动态路由,配置都会生效,点击查看具体 [RBAC 权限讲解](/pages/RBAC/) + +## 常见疑问 + +### 为什么路由的 `name` 必写,而且必须唯一 + +1. 没有硬编码的 `URL` ;`params` 的自动编码/解码;防止在 `url` 中出现打字错误;绕过路径排序(如显示一个) [点击了解具体](https://router.vuejs.org/zh/guide/essentials/named-routes.html#%E5%91%BD%E5%90%8D%E8%B7%AF%E7%94%B1) +2. 虽然跳转路由有很多方式,但平台只推荐使用 `name` 跳转,如下面写法。优点:一是写法简单,尤其当 `path` 稍长时优点更突出,因为 `name` 只有一个单词;二是规范统一,都用 `name` 跳转也方便维护。尤其当项目过大时对整体维护起关键作用 + +```Vue + +``` + +3. 平台的某些关键模块(路由模块、标签模块等)都依赖 `name`,所以独一无二的 `name` 对平台的稳定性起关键作用 + +### 为什么路由的 `name` 需和页面的 `name` 保持一致? + +正常情况下这并不是硬性要求,而是一种规范,方便维护查找,通过路由 `name` 全局搜索即可知道对应页面代码位置,通过页面对应的 `name` 也可知道其对应哪个路由 + +当然,如果当前路由页面需要 [路由页面缓存 keepAlive](#路由页面缓存-keepalive) 就必须保持一致 + +## 更多路由跳转示例代码 + +[点击查看示例代码](https://github.com/ronnaces/ronna-admin/tree/main/src/views/tabs) + +效果如下 + +![more](~@alias/img/router/more.jpg) diff --git "a/docs/01.\346\214\207\345\215\227/01.\346\214\207\345\215\227/08.http\350\257\267\346\261\202.md" "b/docs/01.\346\214\207\345\215\227/01.\346\214\207\345\215\227/08.http\350\257\267\346\261\202.md" new file mode 100644 index 0000000..a8077c4 --- /dev/null +++ "b/docs/01.\346\214\207\345\215\227/01.\346\214\207\345\215\227/08.http\350\257\267\346\261\202.md" @@ -0,0 +1,395 @@ +--- +title: http请求 +article: false +date: 2022-11-10 +permalink: /pages/request/ +--- + +## Mock + +平台使用 [vite-plugin-fake-server](https://github.com/condorheroblog/vite-plugin-fake-server) 插件并集成了 [@faker-js/faker](https://www.npmjs.com/package/@faker-js/faker),支持常用的 `post`、`get` 请求方式,仅用于本地开发,生产环境请务必删除 `mock` + +### 基础用法 + +① 来到 [mock](https://github.com/ronnaces/ronna-admin/tree/main/mock) 文件存放目录,比如添加 `login` 接口,采用 `post` 请求,参考下面代码。 + +::: details + +```ts +import { MockMethod } from "vite-plugin-mock"; + +export default [ + { + url: "/login", + method: "post", + response: ({ body }) => { + return { + success: true, + data: {}, + }; + }, + }, +] as MockMethod[]; +``` + +::: + +② 上面我们添加了 `login` 接口,接着来到 [api](https://github.com/ronnaces/ronna-admin/tree/main/src/api) 目录,比如添加 `user.ts` 文件,参考下面代码 + +::: details + +```ts +import { http } from "@/utils/http"; + +// 这里定义返回值类型,使接口拥有良好的类型推导 +export type UserResult = { + /** 是否请求成功 */ + success: boolean; + data: { + /** 用户名 */ + username: string; + /** 当前登陆用户的角色 */ + roles: Array; + /** `token` */ + accessToken: string; + /** 用于调用刷新`accessToken`的接口时所需的`token` */ + refreshToken: string; + /** `accessToken`的过期时间(格式'xxxx/xx/xx xx:xx:xx') */ + expires: Date; + }; +}; + +/** 登录接口 */ +export const getLogin = (data?: object) => { + return http.request("post", "/login", { data }); +}; +``` + +::: + +③ 上面导出了 `getLogin` 接口,接下来我们来到需要使用这个接口的地方导入,参考下面代码 + +::: details + +```ts + + + +``` + +::: + +您可以注意到我们在上面 `②` 步骤中定义了接口返回值类型 `UserResult`,在使用时就会获得良好的类型推导,如下图 + +![type](~@alias/img/http/type.jpg) + +### 如何快速删除 `mock` + +来到 [build/plugins.ts](https://github.com/ronnaces/ronna-admin/blob/main/build/plugins.ts#L6) 文件,将 `import { viteMockServe } from "vite-plugin-mock";` 注释,最后把 [这里选中](https://github.com/ronnaces/ronna-admin/blob/main/build/plugins.ts#L43-52) 的都注释即可 + +## Axios + +#### 中文文档 + +[点击查看中文文档](https://www.axios-http.cn/) + +#### 基本请求方式 + +平台封装了 [axios](https://github.com/ronnaces/ronna-admin/tree/main/src/utils/http),支持的请求方式请看 [具体参考](https://github.com/ronnaces/ronna-admin/blob/main/src/utils/http/types.d.ts#L14),下面举例常用的四种请求方式 + +##### `get` 请求 + +::: details + +```ts +import { http } from "@/utils/http"; + +// params传参 +export const textRequest = (params?: object) => { + return http.request("get", "/xxx", { params }); +}; + +// url拼接传参 +export const textRequest = (params?: object) => { + return http.request("get", "/xxx?message=" + params); +}; +``` + +::: + +##### `post` 请求 + +::: details + +```ts +import { http } from "@/utils/http"; + +// params传参 +export const textRequest = (params?: object) => { + return http.request("post", "/xxx", { params }); +}; + +// data传参 +export const textRequest = (data?: object) => { + return http.request("post", "/xxx", { data }); +}; +``` + +::: + +##### `delete` 请求 + +::: details + +```ts +import { http } from "@/utils/http"; + +// params传参 +export const textRequest = (params?: object) => { + return http.request("delete", "/xxx", { params }); +}; + +// data传参 +export const textRequest = (data?: object) => { + return http.request("delete", "/xxx", { data }); +}; +``` + +::: + +##### `put` 请求 + +::: details + +```ts +import { http } from "@/utils/http"; + +// params传参 +export const textRequest = (params?: object) => { + return http.request("put", "/xxx", { params }); +}; + +// data传参 +export const textRequest = (data?: object) => { + return http.request("put", "/xxx", { data }); +}; +``` + +::: + +##### `http.request` 传参解析 + +[http.request 源码](https://github.com/ronnaces/ronna-admin/blob/main/src/utils/http/index.ts#L149),参数解析如下 + +| **参数属性** | **说明** | **类型** | +| ------------- | ----------------- | ----------------------- | +| `method` | 请求方式 | `RequestMethods` | +| `url` | 请求地址 | `string` | +| `param` | 请求参数 | `AxiosRequestConfig` | +| `axiosConfig` | 自定义`axios`配置 | `PureHttpRequestConfig` | + +:::tip +当然平台不仅提供了 `http.request` 方法让您发送请求,还提供两种额外的请求方式 [http.post](https://github.com/ronnaces/ronna-admin/blob/main/src/utils/http/index.ts#L176)、[http.get](https://github.com/ronnaces/ronna-admin/blob/main/src/utils/http/index.ts#L185),当然这两种也是基于 `http.request` 封装的,也会走请求拦截和响应拦截,如果您需要脱离平台封装的请求,可以直接使用 `axios`,类似参考 [src/views/welcome/index.vue](https://github.com/ronnaces/ronna-admin/blob/main/src/views/welcome/index.vue#L66) +::: + +#### 如何与后台联调 + +##### 跨域与解决办法 + +###### 什么是跨域 + +跨域本质是浏览器基于同源策略的一种安全手段。同源策略(Sameoriginpolicy),是一种约定,它是浏览器最核心也最基本的安全功能。当协议(protocol)、主机(host)、端口(port)其中一项不相同的时候就会产生跨域。跨域只产生在浏览器,这也是为什么您用 `postman` 请求接口时不会有跨域问题的原因 + +###### 解决办法 + +① 本地开发的话,我们来到 [vite.config.ts](https://github.com/ronnaces/ronna-admin/blob/main/vite.config.ts#L46),参考下面代码配置本地跨域代理即可 + +```ts +proxy: { + "/api": { + // 这里填写后端地址 + target: "http://127.0.0.1:3000", + changeOrigin: true, + rewrite: path => path.replace(/^\/api/, "") + } +} +``` + +② 配置好上面的跨域代理后,来到 [src/api](https://github.com/ronnaces/ronna-admin/tree/main/src/api) 目录,这里我们先新建一个 `utils.ts` 文件用来配置环境,参考下面代码 + +注意:这里又分两种写法 + +第一种(也是最常用的一种,满足大多数场景,首选这种写法哦):比如后端使用 `spring cloud` 微服务架构,不同服务可能会部署在不同机器上,这时候前端必定产生跨域,推荐部署前端项目首选 [nginx](https://www.nginx.com/resources/wiki/),可以利用 `nginx` 的代理转发功能来解决跨域问题 + +utils.ts + +```ts +export const baseUrlApi = (url: string) => `/api/${url}`; +``` + +第二种:前端打包直接丢给后端,放到后端项目里一起部署,协议、主机、端口都相同了,就没有跨域问题 + +utils.ts + +```ts +export const baseUrlApi = (url: string) => + process.env.NODE_ENV === "development" + ? `/api/${url}` + : `http://127.0.0.1:3000/${url}`; +``` + +③ 写完上面的 `utils.ts` 后,继续在 [src/api](https://github.com/ronnaces/ronna-admin/tree/main/src/api) 目录,我们再建一个 `user.ts` 文件,导出这个接口,供页面调用,参考下面代码 + +user.ts + +```ts +import { http } from "@/utils/http"; +import { baseUrlApi } from "./utils"; + +/** 登录 */ +export const getLogin = (data?: object) => { + return http.request("post", baseUrlApi("login"), { data }); +}; +``` + +④ 上面都完成后,我们在需要调用该接口的地方调用即可,参考 [src/store/modules/user.ts](https://github.com/ronnaces/ronna-admin/blob/main/src/store/modules/user.ts#L33) + +##### 多个后端地址如何联调 + +大致步骤和上面差不多,这里我们就简单写一下,具体对比上面的就行 + +① 在 `vite.config.ts` 写入下面代码 + +```ts +proxy: { + // 第一个代理后端地址 + "/api": { + target: "http://127.0.0.1:3000", + changeOrigin: true, + rewrite: path => path.replace(/^\/api/, "") + }, + // 第二个代理后端地址 + "/otherApi": { + target: "http://127.0.0.1:3290", + changeOrigin: true, + rewrite: path => path.replace(/^\/otherApi/, "") + }, + // websocket地址(知识点:wss只能在https安全协议下使用) + // "/wsApi": { + // target: "ws://localhost:3000", + // ws: true, + // }, + // ...依此类推,有几个后端地址就写几个后端地址 +} +``` + +② 在 `utils.ts` 里我们采用第一种写法,参考下面代码 + +utils.ts + +```ts +// 第一个代理后端地址 +export const baseUrlApi = (url: string) => `/api/${url}`; +// 第二个代理后端地址 +export const baseUrlOtherApi = (url: string) => `/otherApi/${url}`; +``` + +③ 第一个代理后端地址上面建的是 `user.ts` 文件,那么第二个代理后端地址我们就建个 `other.ts` 文件吧,参考下面代码 + +other.ts + +```ts +import { http } from "@/utils/http"; +import { baseUrlOtherApi } from "./utils"; + +/** 该接口采用 http://127.0.0.1:3290 后端地址 */ +export const getOther = (data?: object) => { + return http.request("get", baseUrlOtherApi("other"), { data }); +}; +``` + +最后,需要在哪里调用,引入使用即可 + +#### 如何声明接口返回值类型 + +可以看到上面的写法 `http.request` 后面跟的都是 `any`,这很不友好,参考下面友好类型写法即可 + +```ts +import { http } from "@/utils/http"; +import { baseUrlApi } from "./utils"; + +// 定义 login 接口返回值类型为 UserResult +export type UserResult = { + /** 是否请求成功 */ + success: boolean; + data: { + /** 用户名 */ + username: string; + /** 当前登陆用户的角色 */ + roles: Array; + /** `token` */ + accessToken: string; + /** 用于调用刷新`accessToken`的接口时所需的`token` */ + refreshToken: string; + /** `accessToken`的过期时间(格式'xxxx/xx/xx xx:xx:xx') */ + expires: Date; + }; +}; + +/** 登录 */ +export const getLogin = (data?: object) => { + return http.request("post", baseUrlApi("login"), { data }); +}; +``` + +#### 平台封装的请求可以设置额外的 axios 配置吗 + +当然可以。[点击查看这里](#http-request-传参解析),可以看到自定义 `axios` 配置中 `axiosConfig` 作为最后一个参数 + +```ts +import { http } from "@/utils/http"; +import { baseUrlApi } from "./utils"; + +export const testRequest = (data?: object) => { + return http.request( + "post", + baseUrlApi("login"), + { data }, + // 自定义的axios配置在下面对象填写即可 + { + headers: { + "Content-Type": "application/x-www-form-urlencoded", + }, + } + ); +}; +``` + +#### `JWT Token`(内置无感刷新 `token` 解决方案) + +实现原理:后端返回两个 `token`(一个用来请求,一个用来刷新)和过期时间,前端将其进行本地存储,每当接口请求时,把本地存储的过期时间与本地当前时间对比,如果 `token` 过期就把当前请求暂存,然后去请求刷新 `token` 接口,获取到新 `token` 后,再 [触发](https://github.com/ronnaces/ronna-admin/blob/main/src/utils/http/index.ts#L51) 暂存的请求 + +##### 信息存储 + +具体看 [src/utils/auth](https://github.com/ronnaces/ronna-admin/blob/main/src/utils/auth.ts) 文件,里面有很详细的备注 + +##### 细节处理 + +① 不需要携带 `token` 的接口我们设置了 [请求白名单](https://github.com/ronnaces/ronna-admin/blob/main/src/utils/http/index.ts#L76) + +② 当 `token` 过期后,平台会暂存请求,直到拿到新 `token` 才会请求,避免了当页面有多个请求会重复刷新 `token` 的问题。核心代码有三处:[一](https://github.com/ronnaces/ronna-admin/blob/main/src/utils/http/index.ts#L51)、[二](https://github.com/ronnaces/ronna-admin/blob/main/src/utils/http/index.ts#L93)、[三](https://github.com/ronnaces/ronna-admin/blob/main/src/utils/http/index.ts#L100) + +:::tip 生产环境 Mock 可以和真实接口共存吗? +当然可以共存,不过可能会遇到 `Mock` 干扰真实接口的问题。如果您在开发环境接口没问题,但是到生产环境出问题了,在排除后端问题前提下可以尝试 [删除 Mock](#如何快速删除-mock) +::: diff --git "a/docs/01.\346\214\207\345\215\227/01.\346\214\207\345\215\227/09.\346\211\223\345\214\205\345\222\214\351\203\250\347\275\262.md" "b/docs/01.\346\214\207\345\215\227/01.\346\214\207\345\215\227/09.\346\211\223\345\214\205\345\222\214\351\203\250\347\275\262.md" new file mode 100644 index 0000000..1b1a725 --- /dev/null +++ "b/docs/01.\346\214\207\345\215\227/01.\346\214\207\345\215\227/09.\346\211\223\345\214\205\345\222\214\351\203\250\347\275\262.md" @@ -0,0 +1,281 @@ +--- +title: 打包和部署 +article: false +date: 2022-11-07 +permalink: /pages/build/ +--- + +### 本地环境打包预览 + +``` +pnpm preview:build +``` + +### 预发布打包 + +[.env.staging](https://github.com/ronnaces/ronna-admin/blob/main/.env.staging) 文件为预发布打包前的配置文件,[预发布](https://cn.vitejs.dev/guide/env-and-mode.html#modes) + +``` +pnpm build:staging +``` + +### 正式环境打包 + +[.env.production](https://github.com/ronnaces/ronna-admin/blob/main/.env.production) 文件为正式环境打包前的配置文件 + +``` +pnpm build +``` + +### 打包分析 + +``` +pnpm report +``` + +![report](~@alias/img/guide/report.jpg) + +### 平台文件、语言分析 + +分析平台采用了哪些语言以及代码量 + +``` +pnpm cloc +``` + +![image-cloc](~@alias/img/guide/cloc.jpg) + +:::tip 打包优化 +点击查看更多 [打包优化](/pages/buildgood/) +::: + +## 部署 + +### `nginx` + +在 [http 请求篇](/pages/request/#什么是跨域),平台主推使用 `nginx` 部署,因为可以满足绝大多数场景,下面我们讲一下如何配置 + +#### 打包 + +平台提供了全局打包路径 [VITE_PUBLIC_PATH](https://github.com/ronnaces/ronna-admin/blob/main/.env.production#L2) ,默认 `/`,可根据需求自行修改。比如平台的预览地址是 `https://github.com/ronnaces/ronna-admin/#/login`,可以看到根目录 `https://github.com/ronnaces` 后面又跟了个 `/ronna-admin/` 子目录,那么我们打包时就应该把 `VITE_PUBLIC_PATH` 改成 `/ronna-admin/`,然后执行 `pnpm build` 就行,打包完后观察平台根目录会多出个 `dist` 目录,如下图 + +![dist-small](~@alias/img/build/dist-small.jpg) + +#### `nginx` 配置 + +拿 `mac` 举例,配置都一样,可能您们对应的目录不一样,根据实际情况修改即可 + +① 上面打包好后,来到 `/usr/local/var/www` 目录下,将打包后 `dist` 文件里的静态资源都放进去即可,如下图 + +![dist](~@alias/img/build/dist.jpg) + +② 比如我们在 `vite.config.ts` 配置了两个后端地址,如下 + +```ts +proxy: { + // 第一个代理后端地址 + "/api": { + target: "http://127.0.0.1:3000", + changeOrigin: true, + rewrite: path => path.replace(/^\/api/, "") + }, + // 第二个代理后端地址 + "/otherApi": { + target: "http://127.0.0.1:3290", + changeOrigin: true, + rewrite: path => path.replace(/^\/otherApi/, "") + }, +} +``` + +来到 `/usr/local/etc/nginx/nginx.conf` 这个 `nginx` 的配置文件,修改成如下配置即可 + +nginx.config + +``` +location / { + root html; + index index.html index.htm; + # 用于配合前端路由为h5模式使用,防止刷新404 https://router.vuejs.org/zh/guide/essentials/history-mode.html#nginx + try_files $uri $uri/ /index.html; +} + +# 第一个代理后端地址(vite.config.ts里叫 /api,这里也要保持一致) +location /api { + # 如果后端在本地比如127.0.0.1或者localhost请解开下面的rewrite注释即可 + # rewrite ^.+api/?(.*)$ /$1 break; + # 这里填写后端地址(后面一定不要忘记添加 / ) + proxy_pass http://127.0.0.1:3000/; + proxy_set_header Host $host; + proxy_set_header Cookie $http_cookie; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_redirect default; + add_header Access-Control-Allow-Origin *; + add_header Access-Control-Allow-Headers X-Requested-With; + add_header Access-Control-Allow-Methods GET,POST,OPTIONS; +} + +# 第二个代理后端地址(vite.config.ts里叫 /otherApi,这里也要保持一致) +location /otherApi { + # 如果后端在本地比如127.0.0.1或者localhost请解开下面的rewrite注释即可 + # rewrite ^.+otherApi/?(.*)$ /$1 break; + # 这里填写后端地址(后面一定不要忘记添加 / ) + proxy_pass http://127.0.0.1:3290/; + proxy_set_header Host $host; + proxy_set_header Cookie $http_cookie; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_redirect default; + add_header Access-Control-Allow-Origin *; + add_header Access-Control-Allow-Headers X-Requested-With; + add_header Access-Control-Allow-Methods GET,POST,OPTIONS; +} +``` + +将上面的配置放到 `server` 里,如下图 + +![nginx-config](~@alias/img/build/nginx-config.jpg) + +:::tip 上面的配置是平台的 VITE_PUBLIC_PATH = / 情况,也就是只有跟目录的情况。下面的配置为有子目录情况,比如子目录叫 `ronna-admin` + +① 来到 [.env.production](https://github.com/ronnaces/ronna-admin/blob/main/.env.production#L2),将 `VITE_PUBLIC_PATH` 等于 `/ronna-admin`,如下 + +``` +# 线上环境平台打包路径 +VITE_PUBLIC_PATH = /ronna-admin/ +``` + +② 配置 `nginx.config` 如下,可以看到多了个 `location /ronna-admin/` 配置 + +nginx.config + +::: details + +``` +location / { + root html; + index index.html index.htm; + try_files $uri $uri/ /index.html; +} + +location /ronna-admin/ { + root html; + index index.html index.htm; + try_files $uri $uri/ /ronna-admin/index.html; +} + +location /api { + # 如果后端在本地比如127.0.0.1或者localhost请解开下面的rewrite注释即可 + # rewrite ^.+api/?(.*)$ /$1 break; + # 这里填写后端地址(后面一定不要忘记添加 / ) + proxy_pass http://127.0.0.1:3000/; + proxy_set_header Host $host; + proxy_set_header Cookie $http_cookie; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_redirect default; + add_header Access-Control-Allow-Origin *; + add_header Access-Control-Allow-Headers X-Requested-With; + add_header Access-Control-Allow-Methods GET,POST,OPTIONS; +} + +location /otherApi { + # 如果后端在本地比如127.0.0.1或者localhost请解开下面的rewrite注释即可 + # rewrite ^.+otherApi/?(.*)$ /$1 break; + # 这里填写后端地址(后面一定不要忘记添加 / ) + proxy_pass http://127.0.0.1:3290/; + proxy_set_header Host $host; + proxy_set_header Cookie $http_cookie; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_redirect default; + add_header Access-Control-Allow-Origin *; + add_header Access-Control-Allow-Headers X-Requested-With; + add_header Access-Control-Allow-Methods GET,POST,OPTIONS; +} +``` + +::: + +#### 开启 `gzip`、`brotli` 压缩 + +① 来到 [.env.production](https://github.com/ronnaces/ronna-admin/blob/main/.env.production#L16),将 `VITE_COMPRESSION` 等于 `both`,如下 + +``` +# 同时开启 gzip 与 brotli 压缩 +VITE_COMPRESSION = "both" +``` + +② 配置 `nginx.config` 如下 + +nginx.config + +``` +http { + # 开启gzip + gzip on; + # https://blog.csdn.net/fxss5201/article/details/106535475 + gzip_static on; + gzip_proxied any; + # 低于1kb的资源不压缩 + gzip_min_length 1k; + gzip_buffers 4 16k; + gzip_comp_level 2; + # 需要压缩的类型 + gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png; + # 配置禁用gzip条件,支持正则。此处表示ie6及以下不启用gzip(因为ie低版本不支持) + gzip_disable "MSIE [1-6]\."; + # 是否添加“Vary: Accept-Encoding”响应头 + gzip_vary off; + + # 开启brotli压缩,与gzip共存不会冲突,nginx默认不支持ngx_brotli模块,需要自行编译,参考 https://cloud.tencent.com/developer/article/2071894 + brotli on; + brotli_comp_level 6; + brotli_buffers 16 8k; + brotli_min_length 20; + brotli_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript image/svg+xml; +} +``` + +下面两张图是平台非国际化精简版开启 `gzip` 前后对比 + +未开启 `gzip`(资源大小 `2.6MB`) + +![before-gzip](~@alias/img/build/before-gzip.jpg) + +开启 `gzip`(资源被压缩,大小 `684kb`,比未开启时少了约 `2MB` 🐮) + +![after-gzip](~@alias/img/build/after-gzip.jpg) + +#### `nginx` 常用命令 + +##### 启动 `nginx` + +``` +sudo nginx +``` + +##### 重启 `nginx` + +``` +sudo nginx -s reload +``` + +##### 停止运行 `nginx` + +``` +sudo nginx -s stop +``` + +##### 判断 `nginx.config` 配置文件语法是否正确 + +常用于当您配置 `nginx.config` 文件保存重启后却不生效时 + +``` +sudo nginx -t +``` + +当出现 `ok`、`successful` 的字眼时说明配置文件语法没问题 + +![check-nginx-config](~@alias/img/build/check-nginx-config.jpg) diff --git "a/docs/01.\346\214\207\345\215\227/02.\350\277\233\351\230\266/01.\345\233\276\346\240\207.md" "b/docs/01.\346\214\207\345\215\227/02.\350\277\233\351\230\266/01.\345\233\276\346\240\207.md" new file mode 100644 index 0000000..ddddbe7 --- /dev/null +++ "b/docs/01.\346\214\207\345\215\227/02.\350\277\233\351\230\266/01.\345\233\276\346\240\207.md" @@ -0,0 +1,344 @@ +--- +title: 图标 +article: false +date: 2022-11-07 +permalink: /pages/icon/ +--- + +图标是文字的隐喻,可以实现视觉引导和功能划分。平台内置多种图标解决方案,满足 `99.99%` 的图标场景需求 + +## iconify + +在开始之前,我们先来了解下 `iconify` 。它是统一的图标框架,超过 `100` 多个图标集都集中在这一个库,超过 `100,000` 个开源矢量图标,并且会定期更新图标。您可以在 [iconify](https://icon-sets.iconify.design/) 或者 [icones](https://icones.js.org/) 中看到所有的图标集。平台也对 `iconify`。 + +::: tip 关于 element-plus 图标集成 + +问:平台虽然使用了 `element-plus` 作为主要 `ui` 框架,但是并没有引入官网推荐的 [@element-plus/icons-vue](https://element-plus.org/zh-CN/component/icon.html#%E4%BD%BF%E7%94%A8%E5%8C%85%E7%AE%A1%E7%90%86%E5%99%A8) 图标库,那该如何使用 `element-plus` 的图标呢? + +答:`iconify` 非常强大,已经把 `element-plus` 的图标集成进去了。平台使用了 [@iconify-icons/ep](https://www.npmjs.com/package/@iconify-icons/ep) 完全替代了 [@element-plus/icons-vue](https://www.npmjs.com/package/@element-plus/icons-vue) , 具体看 [iconify/ep](https://icon-sets.iconify.design/ep/) 或者 [icones/ep](https://icones.js.org/collection/ep) + +::: + +## 本地图标 + +本地图标是指通过本地安装各类图标库依赖包或者本地引入静态资源(比如 `iconfont`、`svg` )的图标 + +### iconfont 的引入 + +#### 存放目录 + +可以看到下图,平台将 `iconfont` 放到了 [src/assets/iconfont](https://github.com/ronnaces/ronna-admin/tree/main/src/assets/iconfont) 文件夹里,这是平台内置的 `iconfont` ,最好不要删除。如果您项目也用到了 `iconfont` ,可以在同级目录`src/assets`下新建文件夹,比如`iconfont-business`,用来存放您项目的 `iconfont` 文件 + +![iconfont](~@alias/img/icon/iconfont.png) + +#### 如何导入 + +来到 `src/main.ts` 文件下参考 [导入](https://github.com/ronnaces/ronna-admin/blob/main/src/main.ts#L22-L23) 即可 + +#### 组件使用 + +平台对 `iconfont` 进行了组件的封装 [FontIcon](https://github.com/ronnaces/ronna-admin/blob/main/src/components/ReIcon/src/iconfont.ts) + +::: details + +```Vue + +``` + +::: + +### svg 的引入 + +#### 存放目录 + +可以看到下图,平台将 `svg` 放到了 [src/assets/svg](https://github.com/ronnaces/ronna-admin/tree/main/src/assets/svg) 文件夹里,该文件夹作为 `svg` 文件统一存放处 + +![svg](~@alias/img/icon/svg.png) + +#### 基础用法 + +- 平台引入了 [vite-svg-loader](https://www.npmjs.com/package/vite-svg-loader) `vite`插件 , 您可以像引入 `vue` 组件一样引入 `svg` + +```Vue + + + +``` + +### iconify 相关图标的引入 + +#### 分为两个步骤 + +##### 安装本地依赖图标包 + +比如要使用 `element-plus` 的图标,就使用如下命令安装 `@iconify-icons/ep` + + + + ```bash + pnpm add @iconify-icons/ep -D + ``` + + + + ```bash + yarn add @iconify-icons/ep -D + ``` + + + + ```bash + npm install @iconify-icons/ep -D + ``` + + + +安装完成后,来到 `package.json` 文件,看到如下图出现 `@iconify-icons/ep` 代表安装成功(当然平台已经内置了,您就不需要安装了) + +:::tip 温馨提示 +安装完成后,还应该将其引入到 [exclude](https://github.com/ronnaces/ronna-admin/blob/main/build/optimize.ts#L25) 配置里哦 😊 +::: + +![ep-icon](~@alias/img/icon/ep-icon.png) + +#### 基础用法 + +- [iconifyIconOffline](https://github.com/ronnaces/ronna-admin/blob/main/src/components/ReIcon/src/iconifyIconOffline.ts) + +```Vue + + + +``` + +#### 如何找到更多的图标集 + +上面提到过 [iconify](#iconify) 集成了 `100` 多个图标集,可以来到这里 [iconify](https://icon-sets.iconify.design/) 或者 [icones](https://icones.js.org/) 中看到所有的图标集,比如我们想找 [ant-design](https://ant.design/components/icon-cn/) 的图标集(其他图标集类似做法),如下图输入 `ant` 第一个就是,然后 [点进去](https://icones.js.org/collection/ant-design) + +![ant-icon](~@alias/img/icon/ant-icon.png) + +接着上面讲,点进去之后,我们应该先安装它,才能引入、使用,安装分为两个小步骤 + +① 点进去之后,随便找个图标点开,然后取冒号前的名字,将其复制一下 + +![ant-install](~@alias/img/icon/ant-install.png) + +② 然后来到 [npm](https://www.npmjs.com/search?q=%40iconify-icons%2Fant-design) , 总是以 `@iconify-icons/` 开头,然后将刚刚复制的名称放在后面,搜索结果如下图 + +![ant-install2](~@alias/img/icon/ant-install2.png) + +接下来您就可以按照 [这里](#安装本地依赖图标包) 安装使用啦 + +## 在线图标 + +在线图标是指可以通过公网访问的图标 + +### 基础用法 + +- [IconifyIconOnline](https://github.com/ronnaces/ronna-admin/blob/main/src/components/ReIcon/src/iconifyIconOnline.ts) + +```Vue + +``` + +![icon-online](~@alias/img/icon/icon-online.png) + +如何找到更多的图标集 [参考](#如何找到更多的图标集),区别是不需要再安装图标集了,直接复制图标名字就行了,参考下图 + +![online-click](~@alias/img/icon/online-click.png) + +::: tip 图标请求地址 +在线图标走的请求地址是 `https://api.iconify.design`,第一次加载会走接口,然后默认将图标文件存入 `localstorage` ,之后加载图标走 `localstorage` +::: + +## 离线图标 + +离线图标是指只能通过内网访问的图标 + +因为涉及的知识稍微多了点,不方便以文字的形式展现,所以平台出了个视频教程 [离线部署图标方案](https://www.bilibili.com/video/BV17S4y1J79d?p=5&vd_source=5a992808de6229d78e7810536c5f9ab3) [代码地址](https://github.com/xiaoxian521/iconify-offline-arrange) + +## 通用图标 `useRenderIcon` (hooks) + +- [useRenderIcon](https://github.com/ronnaces/ronna-admin/blob/main/src/components/ReIcon/src/hooks.ts) + +### 参数 + +- 接收二个参数,第一个参数 `icon` ,第二个参数 `attrs` ,返回值类型 `FunctionalComponent` + +| **参数属性** | **说明** | **类型** | +| ------------ | --------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | +| `icon` | 图标 | `FunctionalComponent` 、`string` | +| `attrs` | 图标属性、样式配置,拥有十四个属性 [查看详情](https://github.com/ronnaces/ronna-admin/blob/main/src/components/ReIcon/src/types.ts#L1) | `iconType` | + +### 基础用法 + +::: details + +```Vue + + + +``` + +::: + +### 类型 + +::: details + +```ts +export interface iconType { + // iconify (https://docs.iconify.design/icon-components/vue/#properties) + inline?: boolean; + width?: string | number; + height?: string | number; + horizontalFlip?: boolean; + verticalFlip?: boolean; + flip?: string; + rotate?: number | string; + color?: string; + horizontalAlign?: boolean; + verticalAlign?: boolean; + align?: string; + onLoad?: Function; + includes?: Function; + // all icon + style?: object; +} +``` + +::: + +## 导航菜单的 `icon` 如何配置 + +如下图,平台导航菜单的 `icon` 渲染都是用的 `useRenderIcon` 函数 + +![useRenderIcon](~@alias/img/icon/useRenderIcon.png) + +### svg + +`svg` 模式只支持前端配置菜单 `icon`,不支持后端返回哦(因为在这里 `svg` 是函数组件类型,而不是字符串) + +![menu-svg](~@alias/img/icon/menu-svg.png) + +### iconfont + +推荐使用 [font-class](https://www.iconfont.cn/help/detail?spm=a313x.7781069.1998910419.20&helptype=code) 模式 + +![menu-if](~@alias/img/icon/menu-if.png) + +### 本地图标 + +只需要在 `src/components/ReIcon/src/offlineIcon.ts` 文件引入然后使用 `addIcon` 注册一下即可使用 + +![menu-local](~@alias/img/icon/menu-local.jpg) + +:::tip 温馨提示 +只要在 `src/components/ReIcon/src/offlineIcon.ts` 注册过的图标,不仅菜单可以使用,在全局都能直接使用哦,无需引入。比如下面这种用法 + +```vue + + + +``` + +但是平台并不推荐把所有图标都引入到该文件,因为该文件会在页面登录进去之后(非首屏加载哦)一次性加载里面的所有图标,所以这里最好只引入菜单相关的图标,至于非菜单图标怎么用您可以查看这里 [基础用法](#基础用法-2) +::: + +### 在线图标 + +使用非常简单,我们在 [icones](https://icones.js.org/) 找到所需的图标,复制放到 `icon` 属性里就行,如下图 + +:::warning +需注意在线图标的共性是都有一个 `:` 符号,所以这也要求您在使用本地图标时,本地图标名绝对不能存在 `:` 可以使用驼峰写法 [具体逻辑代码](https://github.com/ronnaces/ronna-admin/blob/main/src/components/ReIcon/src/hooks.ts#L53) +::: + +## 图标插件 + +您可能好奇 `vscode` 里代码居然可以直接显示图标,如下图 + +![vscode-iconify](~@alias/img/icon/vscode-iconify.png) + +其实这是一款 `vscode` 插件,来到 `vscode` 扩展商店输入 `antfu.iconify` 搜索安装即可,如下图 + +![vscode-iconify2](~@alias/img/icon/vscode-iconify2.png) + +::: tip 温馨提示 ❤️ +`IconifyIconOffline`、`IconifyIconOnline`、`FontIcon` 这三个图标组件比较常用,所以均已 [全局注册](https://github.com/ronnaces/ronna-admin/blob/main/src/main.ts#L34-L41),可直接在 `vue` 文件中引入即可,不需要在局部注册了 +::: diff --git "a/docs/01.\346\214\207\345\215\227/02.\350\277\233\351\230\266/02.\344\270\273\351\242\230\345\222\214\346\232\227\351\273\221\346\250\241\345\274\217.md" "b/docs/01.\346\214\207\345\215\227/02.\350\277\233\351\230\266/02.\344\270\273\351\242\230\345\222\214\346\232\227\351\273\221\346\250\241\345\274\217.md" new file mode 100644 index 0000000..f7421a9 --- /dev/null +++ "b/docs/01.\346\214\207\345\215\227/02.\350\277\233\351\230\266/02.\344\270\273\351\242\230\345\222\214\346\232\227\351\273\221\346\250\241\345\274\217.md" @@ -0,0 +1,67 @@ +--- +title: 主题和暗黑模式 +article: false +date: 2022-11-07 +permalink: /pages/theme/ +--- + +内置丰富的主题可供选择,也可自行配置主题并且适配了暗黑模式 + +## 内置主题 + +![theme](~@alias/img/guide/theme.jpg) + +从左往右:[道奇蓝(默认)](https://github.com/ronnaces/ronna-admin/blob/main/src/layout/theme/index.ts#L9) [亮白色](https://github.com/ronnaces/ronna-admin/blob/main/src/layout/theme/index.ts#L20) [猩红色](https://github.com/ronnaces/ronna-admin/blob/main/src/layout/theme/index.ts#L31) [橙红色](https://github.com/ronnaces/ronna-admin/blob/main/src/layout/theme/index.ts#L42) [金色](https://github.com/ronnaces/ronna-admin/blob/main/src/layout/theme/index.ts#L53) [绿宝石](https://github.com/ronnaces/ronna-admin/blob/main/src/layout/theme/index.ts#L64) [酸橙绿](https://github.com/ronnaces/ronna-admin/blob/main/src/layout/theme/index.ts#L75) [深粉色](https://github.com/ronnaces/ronna-admin/blob/main/src/layout/theme/index.ts#L86) [深紫罗兰色](https://github.com/ronnaces/ronna-admin/blob/main/src/layout/theme/index.ts#L97) + +## 自定义主题 + +### 添加自定义主题 + +① 将您需要的主题色加入 [themeColors](https://github.com/ronnaces/ronna-admin/blob/main/src/layout/hooks/useDataThemeChange.ts#L15) 数组里,`color` 为主题色值,`themeColor` 为您给主题色取的别名 + +② 上一步完成后,我们将主题色在 [themeColors](https://github.com/ronnaces/ronna-admin/blob/main/src/layout/theme/index.ts#L8) 对象里进行充分适配,上面的 `themeColor` 作为当前自定义主题色的 `key`,然后参考下面的字段解析,进行样式调试即可 + +### 字段解析 + +```ts +// 菜单激活时字体和图标的颜色 +subMenuActiveText; +// 菜单未激活时的整体背景色 +menuBg; +// 顶部、综合菜单模式下最右上角 搜索、告警、用户名、设置鼠标覆盖后的背景色 +menuHover; +// 子菜单未激活时的背景色 +subMenuBg; +// 子菜单激活时的背景色 +subMenuActiveBg; +// 菜单未激活时字体和图标的颜色 +menuText; +// logo 的背景色 +sidebarLogo; +// 鼠标覆盖到菜单时字体和图标的颜色 +menuTitleHover; +// 左侧、综合菜单模式下左边菜单 ::before 元素的背景色 +menuActiveBefore; +``` + +## `element-plus` 主题色 + +具体实现代码参考 [setEpThemeColor](https://github.com/ronnaces/ronna-admin/blob/main/src/layout/hooks/useDataThemeChange.ts#L70) + +## 暗黑模式 + +### 页面如何打开暗黑模式 + +### 具体实现 + +具体实现代码参考 [dataThemeChange](https://github.com/ronnaces/ronna-admin/blob/main/src/layout/hooks/useDataThemeChange.ts#L82) + +### 样式兼容 + +① 如果您想适配自己组件的暗黑样式,只需要在 [dark.scss](https://github.com/ronnaces/ronna-admin/blob/main/src/style/dark.scss) 添加即可,当然这种方法也是当 `Tailwind CSS` 无法实现或者实现不易的情况下才选用 + +② 使用 `Tailwind CSS` (推荐),在需要兼容暗黑模式的类名上加上 `dark:` 即可,比如下面代码,更具体的可以参考这里 [tailwindcss](/pages/tailwindcss/#_5-暗黑模式) + +```Vue +

Fighting!!!

+``` diff --git "a/docs/01.\346\214\207\345\215\227/02.\350\277\233\351\230\266/03.\345\233\275\351\231\205\345\214\226.md" "b/docs/01.\346\214\207\345\215\227/02.\350\277\233\351\230\266/03.\345\233\275\351\231\205\345\214\226.md" new file mode 100644 index 0000000..aaf2c02 --- /dev/null +++ "b/docs/01.\346\214\207\345\215\227/02.\350\277\233\351\230\266/03.\345\233\275\351\231\205\345\214\226.md" @@ -0,0 +1,140 @@ +--- +title: 国际化 +article: false +date: 2022-11-07 +permalink: /pages/i18n/ +--- + +平台内置了国际化,支持自定义国际化、`element-plus` 国际化 + +[pure-admin 完整版](https://github.com/ronnaces/ronna-admin) 只有国际化版本 + +## `vscode` 插件 + +在 `vscode` 插件商店搜 `lokalise.i18n-ally` 进行安装,可以带来更友好的国际化提示 + +![i18nAlly](~@alias/img/guide/i18nAlly.jpg) + +当然不要忘记把下面的 `json` 代码添加到您 `vscode` 的 `settings.json` 中 + +```json +"i18n-ally.localesPaths": "locales", +"i18n-ally.keystyle": "nested", +"i18n-ally.sortKeys": true, +"i18n-ally.namespace": true, +"i18n-ally.enabledParsers": ["yaml", "js"], +"i18n-ally.sourceLanguage": "en", +"i18n-ally.displayLanguage": "zh-CN", +"i18n-ally.enabledFrameworks": ["vue"] +``` + +## 注入国际化 + +平台使用 [@intlify/unplugin-vue-i18n](https://www.npmjs.com/package/@intlify/unplugin-vue-i18n) 这款国际化 `vite` 插件配合 [vue-i18n](https://www.npmjs.com/package/vue-i18n)来实现国际化,国际化文件采用了 `yaml` 格式 [点击查看更多格式](https://github.com/intlify/bundle-tools/blob/main/packages/vite-plugin-vue-i18n/README.md#include) + +中文添加到 [zh-CN.yaml](https://github.com/ronnaces/ronna-admin/blob/main/locales/zh-CN.yaml) 文件里,英文添加到 [en.yaml](https://github.com/ronnaces/ronna-admin/blob/main/locales/en.yaml) 文件里,支持嵌套结构,嵌套层级越深性能越低,如下图 + +![i18n](~@alias/img/guide/i18n.png) + +## 基础用法 + +### `.vue` 文件中使用 + +① 使用 `vue-i18n` 中 `useI18n` 函数 + +```Vue + + + +``` + +② 使用平台提供的 [transformI18n](https://github.com/ronnaces/ronna-admin/blob/main/src/plugins/i18n.ts#L37) 函数 + +```Vue + + + +``` + +### `.ts` 文件中使用 + +在 `.ts` 文件中推荐使用平台提供的 [transformI18n](https://github.com/ronnaces/ronna-admin/blob/main/src/plugins/i18n.ts#L37) 函数,因为 `useI18n` 必须在 `setup` 中使用,具体原因请看 [vue-i18n 文档](https://vue-i18n.intlify.dev/guide/advanced/composition.html#basic-usage) + +```ts +import { transformI18n } from "@/plugins/i +transformI18n("buttons.hsLoginOut"); +``` + +:::tip +`transformI18n` 会自动读取 [locales](https://github.com/ronnaces/ronna-admin/tree/main/locales) 下的国际化语言,如果匹配到则返回,匹配不到的话就是您传什么就返回什么,这样避免报错。这也是为什么平台路由的 `title` 字段支持传 `国际化` 和 `非国际化` 两种写法的原因 +::: + +## 平台提供的 `$t` + +这里的 [$t](https://github.com/ronnaces/ronna-admin/blob/main/src/plugins/i18n.ts#L61) 是指平台提供的函数,是配合 `i18n Ally` 插件在 `vscode` 里带来智能提示,无实际意义,只对提示起作用,而非 `vue-i18n` 里的 + +### `.vue` 文件中使用 + +对于 `i18n Ally` 插件来说要想得到智能提示必须使用带有 `t` 的别名而且 `t` 永远在最后一位,例如 `$$t` 、 `&t` 类似格式都是生效的,而 `$t$` 、 `t&` 不生效 + +```Vue + + + +``` + +效果如下图 + +![i18n](~@alias/img/guide/i18nVue.png) + +### `.ts` 文件中使用 + +```ts +import { $t } from "/@/plugins/i18n"; +$t("menus.hslogin"); +``` + +效果如下图 + +![i18n](~@alias/img/guide/i18nRouter.png) + +## 当前的国际化环境 + +当前的国际化环境是指当前系统正在使用中文还是英文(`zh`:中文、`en`:英文) + +### `.vue` 文件中使用 + +```Vue + +``` + +### `.ts` 文件中使用 + +因为 `useI18n` 只能在 `setup` 中使用,所以平台将当前的国际化环境在 [localStorage](https://github.com/ronnaces/ronna-admin/blob/main/src/utils/responsive.ts#L12) 里存了一份 + +```ts +import type { StorageConfigs } from "/#/index"; +import { storageLocal } from "@pureadmin/utils"; + +const locale = + storageLocal.getItem("responsive-locale")?.locale; +console.log(`当前系统采用的语言是:${locale}`); +``` \ No newline at end of file diff --git "a/docs/01.\346\214\207\345\215\227/02.\350\277\233\351\230\266/04.Tailwind CSS.md" "b/docs/01.\346\214\207\345\215\227/02.\350\277\233\351\230\266/04.Tailwind CSS.md" new file mode 100644 index 0000000..4fb210b --- /dev/null +++ "b/docs/01.\346\214\207\345\215\227/02.\350\277\233\351\230\266/04.Tailwind CSS.md" @@ -0,0 +1,133 @@ +--- +title: Tailwind CSS +article: false +date: 2022-11-07 +permalink: /pages/tailwindcss/ +--- + +平台内置了 [Tailwind CSS](https://tailwindcss.com/docs/installation) , 可通过各种 `程序类` 快速构建自定义用户界面,再也不用写那些 "裹脚布" 似的 `css` 啦 + +## `Tailwind CSS` 的 `vscode` 插件 + +在 `vscode` 插件商店搜 `bradlc.vscode-tailwindcss` 安装后,鼠标覆盖到对应的类名,即可带来智能提示 + +## `Tailwind CSS` 文档 + +[官方英文文档](https://tailwindcss.com/docs) `Tailwind CSS 最新版本` +[非官方中文文档](https://www.tailwindcss.cn/) + +## `Tailwind CSS` 使用技巧 + +### 1. 自定义属性值 + +拿最常用的 `width` 属性来举例,`tailwindcss` 内置了这些 [width#class-reference](https://tailwindcss.com/docs/width#class-reference) 类名,有时候用户想写任意宽度值怎么做呢,比如给 `div` 一个 `666px` 的宽度 ,只需要按照下面的写法。当然不仅仅是宽度可以自定义,所有属性都支持这种模式,你只需要在自定义的时候用 `[ ]`包起来即可。 + +```html +
+``` + +### 2. `!important` 权重,这里我们分为 `三` 步走 + +#### 2-1. 单个实用程序类加 `!important` + +- 比如给 `p` 标签 一个 `black !important` 的高权重字体颜色,只需要按照下面的写法。也就是某个属性,你需要加权重,那么就在其前面加上 `!` 这个感叹号即可。 + +```html +

+ This will be medium even though bold comes later in the CSS. +

+``` + +#### 2-2. `!` 总是在实用程序名称的开头,在任何变体之后,但在任何前缀之前 + +- 比如下面的 `有效代码` ,解释一下代码的意思,就是当鼠标覆盖上去,字体变成白色。 `hover:` 代表 `变体` ,`text-white` 代表程序名称(任何前缀)。 + + - 有效代码 + + ```html +
+ ``` + + - 无效代码 + + ```html +
+ ``` + +#### 2-3. 全局配置`!important` + +- 在 `tailwind.config.js` 文件中如下配置即可,具体参考 [configuration#important](https://tailwindcss.com/docs/configuration#important) + +```js +module.exports = { + important: true, +}; +``` + +::: tip 温馨提示 ❤️ +全局配置 `!important` 后,`Tailwind` 的所有实用程序类都将生成为 `!important`,当然不推荐这里做,因为在合并向元素添加内联样式的第三方 `JS` 库时,设置 `important` 为可能会引入一些问题,`Tailwind` 的 `!important` 实用程序会破坏内联样式,这可能会破坏您的预期设计,不过也有解决办法,具体参考 [configuration#selector-strategy](https://tailwindcss.com/docs/configuration#selector-strategy) +::: + +### 3. 悬停、焦点和其他状态 + +- 具体看这里 [hover-focus-and-other-states](https://tailwindcss.com/docs/hover-focus-and-other-states) + +### 4. 响应式设计 + +- 具体看这里 [responsive-design](https://tailwindcss.com/docs/responsive-design) + +### 5. 暗黑模式 + +- 比如在 `非暗黑` 模式时给 `div` 标签一个 `白` 色背景( `bg-white` ),在 `暗黑` 模式时给 `div` 标签一个 `黑` 色背景( `bg-black` ),只需要在程序类前面加上 `dark:` 即可。 + +```html +
+``` + +### 5. 重用样式 + +当项目越来越大时,如果不规范使用 `tailwindcss` ,很容易造成项目难以维护。这里平台有两点提议,如下: + +- ① 将重复的模块,抽离成组件 +- ② 使用 `@apply` 提取类,参考 [src/style/tailwind.css](https://github.com/ronnaces/ronna-admin/blob/main/src/style/tailwind.css#L5),代码解释如下: + +```css +@layer components { + .flex-c { + @apply flex justify-center items-center; + } +} +``` + +上面的代码意思是,将 `flex` 、 `justify-center` 、 `items-center` 都提取到自定义的 `flex-c` 这个程序类里,然后我们可以向下面代码一样使用: + +```html +
+``` + +### 6. 定制化 `Tailwind CSS` + +- 具体看这里 [configuration](https://tailwindcss.com/docs/configuration) + +## `CSSNANO` + +- [cssnano 中文文档](https://www.cssnano.cn/) +- 平台集成了 `cssnano` [集成代码位置](https://github.com/ronnaces/ronna-admin/blob/main/postcss.config.js#L7) ,它是一款基于 `postcss` 构建的 `css` 优化开源工具。`cssnano` 能为你的 `CSS` 文件做多方面(多余的空白被删除、标识符被压缩、清理无用的 `CSS` 代码)的的优化,以确保最终生成的 `CSS` 文件对生产环境来说体积是最小的。 + +## `Autoprefixer` + +- 平台集成了 `Autoprefixer` [集成代码位置](https://github.com/ronnaces/ronna-admin/blob/main/postcss.config.js#L6) ,它是一款自动管理浏览器前缀(`-webkit-` 、 `-moz-` 、 `-ms-`)的插件,它可以解析 `CSS` 文件并且添加浏览器前缀到 `CSS` 内容里,也就是说写 `CSS` 的时候,你不用考虑前缀了,会自动加上前缀。 + +## `PostCSS` + +- `postcss` 是一款通过 `js` 插件来转换 `css` 的开源工具,通过这些插件可以支持变量和混合,可以通过追加浏览器前缀生成兼容性的样式,也可以通过 [polyfill](https://zhuanlan.zhihu.com/p/71640183) 把新的样式特性处理成通用的样式,可以使用 `css` 模块以及样式的规则校验,关于 `postcss` 更多的内容点 [这里](https://github.com/postcss/postcss/blob/main/docs/README-cn.md) 去了解。 + +::: tip CSS 框架选型经历 + +平台其实在 `CSS 框架` 选型中一共经历了`三`个阶段。 + +- 第一阶段:[windicss](https://windicss.org) 起初选这个的原因是当时 `tailwindcss` 还没有升级到 `v3.0` 版本 +- 第二阶段:[unocss](https://unocss.dev/) 选择这个的原因是 `windicss` 好久没有维护了,并且 `windicss` 还有本地开发内存溢出等问题 +- 第三阶段:[tailwindcss](https://tailwindcss.com/docs/installation) 选择这个的原因是虽然 `unocss` 很强大,功能也多,但是可能就是因为功能太多,带来的问题也就越多吧。其实,平台只是需要一个稳定的纯 `CSS` 框架。`tailwindcss` 在 `vite` 中使用不需要安装什么插件,只需要安装 `tailwindcss` 即可,并且 `tailwindcss` 未处理的 [issues](https://github.com/tailwindlabs/tailwindcss/issues) 极少,维护很及时,经过再三考虑和一些实践,最终选择了稳定的 `tailwindcss` + +::: diff --git "a/docs/01.\346\214\207\345\215\227/02.\350\277\233\351\230\266/05.RBAC\346\235\203\351\231\220.md" "b/docs/01.\346\214\207\345\215\227/02.\350\277\233\351\230\266/05.RBAC\346\235\203\351\231\220.md" new file mode 100644 index 0000000..5552de9 --- /dev/null +++ "b/docs/01.\346\214\207\345\215\227/02.\350\277\233\351\230\266/05.RBAC\346\235\203\351\231\220.md" @@ -0,0 +1,131 @@ +--- +title: RBAC权限 +article: false +date: 2022-11-07 +permalink: /pages/RBAC/ +--- + +所谓 `RBAC`(Role Based Access Control)权限指的是基于角色的访问控制 + +![rbac](~@alias/img/watermarks/rbac.jpg) + +## 用户 + +平台用 `mock` 模拟出两个账号,一个是 [admin](https://github.com/ronnaces/ronna-admin/blob/main/mock/login.ts#L13),另一个是 [common](https://github.com/ronnaces/ronna-admin/blob/main/mock/login.ts#L25),用户名字段为 `username` ,为字符串类型,当然平台将用户名在 `pinia` 的 [state](https://github.com/ronnaces/ronna-admin/blob/main/src/store/modules/user.ts#L16) 里存了一份 + +## 角色 + +平台用 `mock` 模拟出两个角色,一个是 [admin](https://github.com/ronnaces/ronna-admin/blob/main/mock/login.ts#L15),另一个是 [common](https://github.com/ronnaces/ronna-admin/blob/main/mock/login.ts#L27),角色存放在 `roles` 字段中,为数组类型,可支持多个角色,当然平台将 `当前登录用户的角色` 在 `pinia` 的 [state](https://github.com/ronnaces/ronna-admin/blob/main/src/store/modules/user.ts#L19) 里也存了一份 + +## 权限 + +整体分为 [粗粒度权限](#粗粒度权限) 和 [细粒度权限](#细粒度权限) + +### 粗粒度权限 + +#### 菜单权限 + +##### 实现原理、代码 + +页面整体的菜单存放在 [wholeMenus](https://github.com/ronnaces/ronna-admin/blob/main/src/store/modules/permission.ts#L13),所以我们只需要控制 `wholeMenus` 就能控制菜单的显示、隐藏。通过 [filterNoPermissionTree](https://github.com/ronnaces/ronna-admin/blob/main/src/router/utils.ts#L85) 函数从菜单中过滤无权限的菜单 + +##### 如何配置 + +只需要通过返回路由的 `roles` 配置项,赋予该菜单权限即可,如下图 + +![roles](~@alias/img/rbac/roles.png) + +:::tip 实现细节 +将菜单与路由解藕,这样可以更灵活的控制二者,不会造成一方改动必会影响另一方 +::: + +#### `url` 链接权限 + +##### 实现原理、代码 + +平台在路由的 [beforeEach](https://github.com/ronnaces/ronna-admin/blob/main/src/router/index.ts#L98) 钩子函数中,通过对比当前用户的角色和当前路由中 `roles` 字段来判断是否有无权限,无权限跳转 [403](https://github.com/ronnaces/ronna-admin/blob/main/src/views/error/403.vue) 页面 + +##### 如何配置 + +您不需要做任何配置,只需要像上图一样配置好权限就行,平台会根据有无权限自行判断,如下面视频,当有 `admin` 权限时可以看到系统管理目录以及里面的菜单页面并且可以通过 `url` 跳转,当然也可以在 [菜单搜索](https://github.com/ronnaces/ronna-admin/tree/main/src/layout/components/search) 中找到,当无 `admin` 权限时反之 + + +#### 按钮、组件、类方法权限 + +针对这三类权限判断,平台提供三种方法 [组件方式判断权限](#组件方式判断权限)、[函数方式判断权限](#函数方式判断权限)、[指令方式判断权限](#指令方式判断权限) + +在使用这三种方法前,需要通过返回路由的 `auths` 配置项,赋予该页面按钮级别权限,如下图 + +![auths](~@alias/img/rbac/auths.png) + +##### 组件方式判断权限 + +- 按钮、组件权限可用 + +###### 实现原理、代码 + +通过 [hasAuth](https://github.com/ronnaces/ronna-admin/blob/main/src/router/utils.ts#L354) 函数,进行权限组件的封装,使用 `Vue` 提供的 [Fragment](https://cn.vuejs.org/guide/extras/rendering-mechanism.html#patch-flags) 标签进行包裹,这样可让被包裹的组件无多余标签,减少渲染成本。[查看具体代码](https://github.com/ronnaces/ronna-admin/blob/main/src/components/ReAuth/src/auth.tsx) + +###### 如何配置 + +具体参考 [views/permission/button/index.vue](https://github.com/ronnaces/ronna-admin/blob/main/src/views/permission/button/index.vue#L23-L38) + +```Vue + + 拥有code:'btn_add' 权限可见 + +``` + +::: tip +平台已经全局注册 [Auth](https://github.com/ronnaces/ronna-admin/blob/main/src/main.ts#L44-L45) 组件,无需重复注册 +::: + +##### 函数方式判断权限 + +- 按钮、组件、类方法权限都可用 + +###### 实现原理、代码 + +通过 [hasAuth](https://github.com/ronnaces/ronna-admin/blob/main/src/router/utils.ts#L354) 函数判断某些按钮、组件、类方法是否有按钮级别的权限 + +###### 如何配置 + +具体参考 [views/permission/button/index.vue](https://github.com/ronnaces/ronna-admin/blob/main/src/views/permission/button/index.vue#L40-L56) + +```Vue + + 拥有code:'btn_add' 权限可见 + +``` + +```ts +hasAuth("btn_add") ? "显示" : "隐藏"; +``` + +##### 指令方式判断权限 + +- 按钮、组件权限可用。指令方式不能动态修改权限 + +###### 实现原理、代码 + +通过 [hasAuth](https://github.com/ronnaces/ronna-admin/blob/main/src/router/utils.ts#L354) 函数,进行权限指令的封装。[查看具体代码](https://github.com/ronnaces/ronna-admin/blob/main/src/directives/auth/index.ts) + +###### 如何配置 + +具体参考 [views/permission/button/index.vue](https://github.com/ronnaces/ronna-admin/blob/main/src/views/permission/button/index.vue#L58-L73) + +```Vue + + 拥有code:'btn_add' 权限可见 + +``` + +### 细粒度权限 + +#### 数据权限 + +数据权限对页面的要求就非常简单了,比如可以将数据权限的配置功能放在 `角色管理` 页面进行配置即可 + + diff --git "a/docs/01.\346\214\207\345\215\227/02.\350\277\233\351\230\266/06.\347\261\273\345\236\213\345\243\260\346\230\216.md" "b/docs/01.\346\214\207\345\215\227/02.\350\277\233\351\230\266/06.\347\261\273\345\236\213\345\243\260\346\230\216.md" new file mode 100644 index 0000000..61a368a --- /dev/null +++ "b/docs/01.\346\214\207\345\215\227/02.\350\277\233\351\230\266/06.\347\261\273\345\236\213\345\243\260\346\230\216.md" @@ -0,0 +1,64 @@ +--- +title: 类型声明 +article: false +date: 2022-12-01 +permalink: /pages/typescript/ +--- + +[TypeScript](https://www.tslang.cn/docs/home.html)作为 JavaScript 的超集,拥有强大的类型提示给我们的开发带来了极大的便利,尤其体现在团队合作开发中 + +## 全局类型声明 + +在 [global.d.ts](https://github.com/ronnaces/ronna-admin/blob/main/types/global.d.ts) 和 [index.d.ts](https://github.com/ronnaces/ronna-admin/blob/main/types/index.d.ts) 文件中编写的类型可直接在 `.ts`、`.tsx`、`.vue` 中使用 + +![whole](~@alias/img/type/whole.jpg) + +## `types/shims-tsx.d.ts` + +该文件是为了给 `.tsx` 文件提供类型支持,在编写时能正确识别语法 + +## `types/shims-vue.d.ts` + +`.vue`、`.scss` 文件不是常规的文件类型,`typescript` 无法识别,所以我们需要通过下图的代码告诉 `typescript` 这些文件的类型,防止类型报错 + +![shims-vue](~@alias/img/type/shims-vue1.png) + +项目开发,我们可能需要安装一些库或者插件什么的,当它们对 `typescript` 支持不是很友好的时候,就会出现下图的情况 + +![shims-vue](~@alias/img/type/shims-vue2.jpg) + +解决办法就是将这些通过 `declare module "包名"` 的形式添加到 [types/shims-vue.d.ts](https://github.com/ronnaces/ronna-admin/blob/main/types/shims-vue.d.ts#L12-16) 中去,如下图 + +![shims-vue](~@alias/img/type/shims-vue3.jpg) + +## 全局导入的组件如何获取类型提示 + +### 从 [npm](https://www.npmjs.com/) 下载的组件库或者第三方库 + +也就是您使用 `pnpm add` 添加的包,比如 [vue-router](https://router.vuejs.org/),我们只需要将这个包提供的全局类声明文件导入到 [tsconfig.json](https://github.com/ronnaces/ronna-admin/blob/main/tsconfig.json#L30) 的 `types` 配置项,然后重启编辑器即可,如下图导入前和导入后的效果对比 + +导入前,`pure-table` 无高亮且鼠标覆盖无类型提示 + +![before](~@alias/img/type/before.jpg) + +导入后,`pure-table` 高亮且鼠标覆盖有类型提示 + +![after](~@alias/img/type/after.jpg) + +:::tip +当然这个导入前提是这个组件库或者第三方库是有导出全局类声明文件的。 +::: + +### 平台内自定义的全局组件 + +拿平台封装的 [Auth](https://github.com/ronnaces/ronna-admin/tree/main/src/components/ReAuth) 组件举例 + +① 我们将 `Auth` 组件在 [main.ts](https://github.com/ronnaces/ronna-admin/blob/main/src/main.ts#L44-L45) 中进行了全局注册 + +② 然后将 `Auth` 组件在 [global-components.d](https://github.com/ronnaces/ronna-admin/blob/main/types/global-components.d.ts#L9) 中引入,所有的全局组件都应该在 `GlobalComponents` 下引入才可获得类型支持,如下图 + +![component](~@alias/img/type/_com1.png) + +③ 最后我们直接写 `xxx` 就可以得到类型提示啦,如下图 + +![component](~@alias/img/type/_com2.png) diff --git "a/docs/01.\346\214\207\345\215\227/02.\350\277\233\351\230\266/07.\345\215\225\347\202\271\347\231\273\345\275\225.md" "b/docs/01.\346\214\207\345\215\227/02.\350\277\233\351\230\266/07.\345\215\225\347\202\271\347\231\273\345\275\225.md" new file mode 100644 index 0000000..b95d40b --- /dev/null +++ "b/docs/01.\346\214\207\345\215\227/02.\350\277\233\351\230\266/07.\345\215\225\347\202\271\347\231\273\345\275\225.md" @@ -0,0 +1,40 @@ +--- +title: 单点登录 +article: false +date: 2022-12-01 +permalink: /pages/sso/ +--- + +单点登录有效减少繁琐的登录操作,优化了用户体验 + +## 单点登录 + +单点登录主要功能在后端,这里只讲述使用 `ronna-admin` 前端代码如何实现 +下面以完整版为例,精简版想要开启单点登录只需将 [import "@/utils/sso"](https://github.com/ronnaces/ronna-admin/blob/main/src/router/index.ts#L1) 注释解开即可 + +### 前端实现步骤划分 + +- 先判断是否为单点登录,不为则直接返回不再进行任何逻辑处理,下面是单点登录的处理步骤 + +1. [清空本地旧信息](https://github.com/ronnaces/ronna-admin/blob/main/src/utils/sso.ts#L37) +2. [ 获取 `url` 中的重要参数信息,然后通过 `setToken` 保存在本地](https://github.com/ronnaces/ronna-admin/blob/main/src/utils/sso.ts#L40) +3. [删除不需要显示在 `url` 的参数,这样做更安全](https://github.com/ronnaces/ronna-admin/blob/main/src/utils/sso.ts#L43-L44) +4. [使用 `window.location.replace` 跳转正确页面,`window.location.replace` 可以替换浏览器历史记录项](https://github.com/ronnaces/ronna-admin/blob/main/src/utils/sso.ts#L55) + +### 完整代码 + +[点击查看完整代码](https://github.com/ronnaces/ronna-admin/blob/main/src/utils/sso.ts) + +### url 格式 + +``` +以平台的预览地址为例 + +完整地址 https://ronna.ronnaces.com/#/welcome?username=sso&roles=admin&accessToken=eyJhbGciOiJIUzUxMiJ9.admin + +https://ronna.ronnaces.com 域名 + +/#/welcome 要跳转的页面(这里是hash路由模式,根据实际情况修改即可) + +?username=sso&roles=admin&accessToken=eyJhbGciOiJIUzUxMiJ9.admin 需要携带的三个(username、roles、accessToken)必传参数 +``` \ No newline at end of file diff --git "a/docs/01.\346\214\207\345\215\227/02.\350\277\233\351\230\266/08.\350\207\252\345\256\232\344\271\211\345\205\215\347\231\273\345\275\225.md" "b/docs/01.\346\214\207\345\215\227/02.\350\277\233\351\230\266/08.\350\207\252\345\256\232\344\271\211\345\205\215\347\231\273\345\275\225.md" new file mode 100644 index 0000000..afba902 --- /dev/null +++ "b/docs/01.\346\214\207\345\215\227/02.\350\277\233\351\230\266/08.\350\207\252\345\256\232\344\271\211\345\205\215\347\231\273\345\275\225.md" @@ -0,0 +1,29 @@ +--- +title: 自定义免登录 +article: false +date: 2023-10-09 +permalink: /pages/nologin/ +--- + +自定义免登录时长具有一定的应用价值,优化了用户体验 + +## 优点 + +1. 增强用户体验: 通过提供自定义免登录时长的选项,用户可以根据自己的实际需求和喜好来设置登录频率,以提升使用体验 +2. 提升系统安全性:对于不同的环境和使用场景,用户可以根据自身的安全考虑来设定免登录时长。例如,在私人电脑或手机上,用户可能会选择较长的免登录时间以提升使用便利性。相反,在公共电脑上,用户可能会选择较短的免登录时间或者不使用免登录功能,以避免账号安全风险 +3. 紧密符合业务需求:对于管理员或后台管理人员,他们可能需要频繁地登录系统进行功能操作,允许他们自定义免登录时长可以提升工作效率 +4. 促进个性化服务:自定义免登录时长这样的个性化选项可以在一定程度上增加系统的用户友好性,让用户感觉更为贴心,有助于提高用户满意度和忠诚度 + +## 如何操作 + +来到登录页勾选 7 天内免登录即可,如下图 + +![nologin1](~@alias/img/login/no1.png) + +平台提供 1、7、30 三种天数供选择,默认 7 天。您也可查看下面的具体实现,修改少量代码即可自定义所需天数。点击天数即可切换 + +## 具体实现 + +用户登录后判断是否勾选免登录,来给`key`为`multiple-tabs`的数据存储到`cookie`中,如果勾选就设置对应的过期时间,反之不设置 [具体代码](https://github.com/ronnaces/ronna-admin/blob/main/src/utils/auth.ts#L55-L63) + +自定义所需天数在[此处配置](https://github.com/ronnaces/ronna-admin/blob/main/src/views/login/index.vue#L243-L245) diff --git "a/docs/01.\346\214\207\345\215\227/02.\350\277\233\351\230\266/09.\346\211\223\345\214\205\344\274\230\345\214\226.md" "b/docs/01.\346\214\207\345\215\227/02.\350\277\233\351\230\266/09.\346\211\223\345\214\205\344\274\230\345\214\226.md" new file mode 100644 index 0000000..83246bc --- /dev/null +++ "b/docs/01.\346\214\207\345\215\227/02.\350\277\233\351\230\266/09.\346\211\223\345\214\205\344\274\230\345\214\226.md" @@ -0,0 +1,126 @@ +--- +title: 打包优化 +article: false +date: 2022-11-07 +permalink: /pages/buildgood/ +--- + +打包优化关联着网站的稳定与加载速度,在开发中也是非常重要的一项 + +![buildgood](~@alias/img/watermarks/buildgood.jpg) + +## `vite` 自身的构建优化 + +点击查看 [build-optimizations](https://cn.vitejs.dev/guide/features.html#build-optimizations) + +## `css` 优化 + +分两步优化 + +### ​ 压缩 `css` + +使用 [cssnano](/pages/tailwindcss/#cssnano) 去压缩 `css` + +### ​ 自动添加浏览器前缀 + +使用 [Autoprefixer](/pages/tailwindcss/#autoprefixer) 自动添加浏览器前缀 + +## 组件、工具库 + +- 无论是组件(如 `element-plus`),还是工具库(如 `lodash`、`axios`)我们都应该尽可能的按需引入,使其有良好的  `tree-shaking` 效果,这样项目整体打包出来的无用代码就少之又少了 + +- 拿 `lodash` 举例,`lodash` 默认是 `cjs` 格式,不支持 `es6` 的 `import` 语法,那么我们就可以去 `github` 或者某些搜索引擎去寻找替代品,最终平台找到了 `lodash-unified`,它完全兼容 `lodash` 的全部语法并且既支持 `esm` 又支持 `cjs`,这使得它无论在浏览器还是 `node` 环境中表现都很良好。当然如果遇到那种只支持 `cjs` 格式,网上找遍了都找不到兼容 `esm` 格式的咋办呢,这时你可以参考 `lodash-unified`,看看别人是如何转换的 😊 + +- `vite` 目前最大的性能瓶颈是大量模块的首页加载,可看 [vite-issues](https://github.com/vitejs/vite/issues/1309#issue-777569758),值得期待的是这个 [pr](https://github.com/vitejs/vite/pull/10671) 可能会缓解这个麻烦 + +## 压缩 `gzip`、`brotli` 格式 + +使用 [vite-plugin-compression](https://github.com/vbenjs/vite-plugin-compression) 对平台进行 `gzip` 或者 `brotli` 压缩,`nginx` 对这两种压缩模式都支持,压缩后部署到 `nginx` 将极大提高网页加载速度 + +### 如何开启压缩 + +来到 `.env.production` 文件,设置 [VITE_COMPRESSION](https://github.com/ronnaces/ronna-admin/blob/main/.env.production#L13) 即可。设置总体分为下面两种 [具体实现代码](https://github.com/ronnaces/ronna-admin/blob/main/build/compress.ts) + +#### 两种总体设置 + +1. 压缩时不删除原始文件的配置 +2. 压缩时删除原始文件的配置 + +##### 压缩时不删除原始文件的配置 + +```.env.production +开启 gzip 压缩 +VITE_COMPRESSION = "gzip" + +开启 brotli 压缩 +VITE_COMPRESSION = "brotli" + +# 同时开启 gzip 与 brotli 压缩 +VITE_COMPRESSION = "both" + +# 不开启压缩,默认 +VITE_COMPRESSION = "none" +``` + +##### 压缩时删除原始文件的配置 + +```.env.production +开启 gzip 压缩 +VITE_COMPRESSION = "gzip-clear" + +开启 brotli 压缩 +VITE_COMPRESSION = "brotli-clear" + +# 同时开启 gzip 与 brotli 压缩 +VITE_COMPRESSION = "both-clear" + +# 不开启压缩,默认 +VITE_COMPRESSION = "none" +``` + +## 采用 `cdn` 模式替换本地依赖 + +### `vite` 插件 + +使用 [vite-plugin-cdn-import](https://github.com/MMF-FE/vite-plugin-cdn-import/blob/master/README.zh-CN.md) 插件,在打包时将指定的 `modules` 替换成 `cdn` 链接,从而减少构建时间,提高生产环境中页面加载速度。 + +### `cdn` 厂商(免费) + +平台 `cdn` 采用的是国内 [bootcdn](https://www.bootcdn.cn),主要是稳定并且快,当然您也可以选择 [unpkg](https://unpkg.com) 或者 [jsdelivr](https://www.jsdelivr.com),这两个 `cdn` 是国外的 + +### 如何启动 `cdn` 替换 + +来到 `.env.production` 文件,将 [VITE_CDN](https://github.com/ronnaces/ronna-admin/blob/main/.env.production#L8) 设置成 `true` 即可 + +### 默认启动 `cdn` 替换的模块有哪些 + +`vue`、`vue-router`、`vue-demi`、`pinia`、`element-plus`、`axios`、`dayjs`、`echarts` 具体代码 [build/cdn.ts](https://github.com/ronnaces/ronna-admin/blob/main/build/cdn.ts) + +## 生产环境删除 `console.log` + +使用平台开发的 [vite-plugin-remove-console](https://github.com/xiaoxian521/vite-plugin-remove-console) 插件,在打包构建时移除平台中所有的 `console.log` + +## 静态资源分类打包 + +`vite` 是基于 `esbuild` 和 `rollup` 构建的,在打包时如果不进行 `output` 的配置,打包出来的效果如下图(这也是 `vite` 默认打包出来的效果,可以看到所有文件都混在一起) + +![no-output](~@alias/img/build/no-output.jpg) + +下图是我们配置 [output](https://github.com/ronnaces/ronna-admin/blob/main/vite.config.ts#L63-67) 后的效果,可以看到文件都进行了分类存放,这也方便我们查找文件 + +![output](~@alias/img/build/output.jpg) + +:::tip 相关推荐 +[Vite 代码拆包插件。支持多种拆包策略,可避免手动操作 manualChunks 潜在的循环依赖问题](https://github.com/sanyuan0704/vite-plugin-chunk-split/blob/master/README-CN.md) +::: + +## `svg` 压缩 + +一般下载的 `svg` 或者复制的 `svg` 代码,里面存在一些无关紧要的元素,可以将其剔除,毫无影响地降低 `svg` 大小 +平台使用了 [svgo](https://www.npmjs.com/package/svgo) 工具对所有 `svg` 进行了压缩,您拉取平台代码时所有 `svg` 都已经最简了哦。当然您会问自己新加的 `svg` 如何精简呢,来到 [main/package.json](https://github.com/ronnaces/ronna-admin/blob/main/package.json#L14),可以看到平台默认使用 `svgo` 工具对 `src/assets/svg` 文件夹里的所有 `svg` 进行压缩,这是可以改动的,只需要将 `-f` 和 `-o` 后的路径改为您需要压缩的 `svg` 路径即可。温馨提示:只需要运行 `pnpm svgo` 命令对 `svg` 文件进行一次压缩即可 + +:::tip 推荐阅读 + +- [性能优化](https://cn.vuejs.org/guide/best-practices/performance.html) +- [Vite 中组件按组分块打包](https://router.vuejs.org/zh/guide/advanced/lazy-loading.html#%E4%BD%BF%E7%94%A8-vite) + ::: diff --git "a/docs/01.\346\214\207\345\215\227/02.\350\277\233\351\230\266/10.vite\351\242\204\346\236\204\345\273\272.md" "b/docs/01.\346\214\207\345\215\227/02.\350\277\233\351\230\266/10.vite\351\242\204\346\236\204\345\273\272.md" new file mode 100644 index 0000000..dc10f5d --- /dev/null +++ "b/docs/01.\346\214\207\345\215\227/02.\350\277\233\351\230\266/10.vite\351\242\204\346\236\204\345\273\272.md" @@ -0,0 +1,44 @@ +--- +title: vite预构建 +article: false +date: 2022-12-01 +permalink: /pages/optimize/ +--- + +主要介绍下如何在 `pure-admin` 平台进行正确有效的 `vite` 预构建配置 + +## `include` + +[optimizeDeps.include](https://github.com/ronnaces/ronna-admin/blob/main/build/optimize.ts#L7) 配置为需要预构建的模块。`vite` 启动时会将 `optimizeDeps.include` 里的模块,编译成 `esm` 格式并缓存到 `node_modules/.vite` 文件夹,页面加载到对应模块时如果浏览器有缓存就读取浏览器缓存,如果没有会读取本地缓存并按需加载 + +::: + +:::tip + +1. 尤其当您禁用浏览器缓存时(这种情况只应该发生在调试阶段)必须将对应模块加入到 `include` 里,否则会遇到开发环境切换页面卡顿的问题(`vite` 会认为它是一个新的依赖包会重新加载并强制刷新页面),因为它既无法使用浏览器缓存,又没有在本地 `node_modules/.vite` 里缓存 +2. 如果您使用的第三方库是全局引入,也就是引入到 `src/main.ts` 文件里,就不需要再添加到 `include` 里了,因为 `vite` 会自动将它们缓存到 `node_modules/.vite` + +::: + +## `exclude` + +[optimizeDeps.exclude](https://github.com/ronnaces/ronna-admin/blob/main/build/optimize.ts#L25) 配置为排除预构建的模块。需要注意的是平台里所有以 `@iconify-icons/` 开头引入的的本地图标模块,都应加入到下面的 `exclude` 里,因为平台推荐本地图标的使用方式是哪里需要哪里引入而且都是单个的引入,不需要预构建,直接让浏览器加载就好 + +下面是精简版 `optimizeDeps.exclude` 配置 +::: details + +```ts +const exclude = [ + "@iconify-icons/ep", + "@iconify-icons/ri", + "@pureadmin/theme/dist/browser-utils", +]; +``` + +::: + +:::tip 推荐阅读 + +- [依赖预构建](https://cn.vitejs.dev/guide/dep-pre-bundling.html) +- [深入理解 Vite 核心原理](https://juejin.cn/post/7064853960636989454) + ::: diff --git "a/docs/01.\346\214\207\345\215\227/03.\345\205\266\344\273\226/01.\345\270\270\350\247\201\351\227\256\351\242\230.md" "b/docs/01.\346\214\207\345\215\227/03.\345\205\266\344\273\226/01.\345\270\270\350\247\201\351\227\256\351\242\230.md" new file mode 100644 index 0000000..7f4a0c5 --- /dev/null +++ "b/docs/01.\346\214\207\345\215\227/03.\345\205\266\344\273\226/01.\345\270\270\350\247\201\351\227\256\351\242\230.md" @@ -0,0 +1,778 @@ +--- +title: 常见问题 +article: false +date: 2022-11-07 +permalink: /pages/FAQ/ +--- + +## 是否支持 `IE` ? + +答:`vue3` 官方说过不支持 `IE`,具体看 [rfcs](https://github.com/vuejs/rfcs/blob/master/active-rfcs/0038-vue3-ie11-support.md) 和 [cn.vuejs](https://cn.vuejs.org/about/faq.html#what-browsers-does-vue-support)。当然有人会说 [@vitejs/plugin-legacy](https://cn.vitejs.dev/plugins/#vitejsplugin-legacy) 会支持 `IE`,它的确会,但是它是一款 `vite` 插件,只对非 `vue3` 的框架进行支持,目前没有任何一款工具可以使 `vue3` 支持 `IE` 浏览器,如果您项目需要支持 `IE`,请慎重考虑使用本平台。如果您既要使用最新技术并且又想稳定又要兼容 `IE` 浏览器的话可以选择 `vue2.7` 的某个版本搭配 `vue-cli` 最新版本 + +## `husky` 是什么?可以删除 `husky` 提交前校验吗?如何彻底删除? + +- `husky` 是什么? + 答:[官方文档](https://typicode.github.io/husky/#/) + +- 可以删除 `husky` 提交前校验吗? + 答:如果您们提交代码不需要严格的提交前校验,这当然可以删除 + +- 如何彻底删除? + ① 删除根目录 `.husky` 文件夹以及里面所有文件 + ② 删除根目录 `commitlint.config.js` 文件 + ③ 来到 `package.json` 下的 `devDependencies` ,删除 `@commitlint/cli` 、 `@commitlint/config-conventional` 、 `@commitlint/types` 、 `husky` 、 `lint-staged` 这些依赖 + ④ 最后来到 `package.json` 下的 `scripts` ,删除 `"prepare": "husky"` 命令即可 + +## 为什么使用 `pnpm` ? `pnpm` 天生支持 `monorepo`,为什么平台不采用这种模式呢?可以不使用 `pnpm` 吗?如何从 `pnpm` 切换到 `yarn` ? + +- 为什么使用 `pnpm`? + ① 节约磁盘空间并提升安装速度 + 当使用 `npm` 或 `Yarn` 时,如果您有 `100` 个项目使用了某个依赖,就会有 `100` 份该依赖的副本保存在硬盘上。 对于 `pnpm` ,依赖项将存储在一个内容可寻址的仓库中,因此:如果您用到了某依赖项的不同版本,那么只会将有差异的文件添加到仓库。例如,如果它有 `100` 个文件,而新版本只改变了其中 `1` 个文件。那么 `pnpm update` 只会向存储中心添加 `1` 个新文件,不会仅因为单一的改变而克隆整个依赖。所有文件都会存储在硬盘上的同一位置。 当多个包(`package`)被安装时,所有文件都会从同一位置创建硬链接,不会占用额外的磁盘空间。 这允许您跨项目地共享同一版本的依赖。最终您节省了大量与项目和依赖成比例的硬盘空间,并且拥有更快的安装速度! + ② 创建非扁平化的 `node_modules` 文件夹 + 当使用 `npm` 安装依赖时,所有的依赖都会被提升到模块的根目录。 因此,项目可以访问到未被添加进 当前 项目的依赖。`pnpm` 使用软链的方式将项目的直接依赖添加进模块文件夹的根目录。 + +- `pnpm` 天生支持 `monorepo`,为什么平台不采用这种模式呢? + 答:我们先来简单介绍一下什么是 `monorepo` ,`monorepos` 指单一代码库,在版本控制系统的单个代码库里包含了许多项目的代码,与它对应的是 `multirepos` 多代码库,每个项目都储存在一个完全独立的、版本控制的代码库中。`monorepo` 可能并不适合大多数项目,毕竟大家习惯了多代码库开发,所以平台不采用这种模式。 + [推荐文章:Monorepo 可能没您想象中那么香](https://baijiahao.baidu.com/s?id=1663844045880515134&wfr=spider&for=pc) + +- 可以不使用 `pnpm` 吗? + 答:可以的 + +- 如何从 `pnpm` 替换到 `yarn`( `npm` 替换方法同下) + 替换方法:来到根目录 `package.json` 文件,删除 `"pnpm": ">= 6"` 和 `"preinstall": "npx only-allow pnpm"` ,然后将 `pnpm` 全部换成 `yarn` 即可 + +::: warning + +`ronna-admin` 在 `3.5.0` 版本移除了 `cross-env`,采用 `pnpm` 中 [shell-emulator](https://pnpm.io/zh/cli/run#shell-emulator)这个配置项替代。如果您替换成了 `yarn` 或者 `npm` ,则需要安装 `cross-env`,还原此处的代码即可 [commit](https://github.com/ronnacesronna-admin-thin/commit/820f724d5bec14951cbe81d7c6984451de66d93b#diff-7ae45ad102eab3b6d7e7896acd08c427a9b25b346470d7bc6507b6481575d519) + +::: + +## 平台出现报错 `Cannot find module '@zougt/some-loader-utils'` + +- 为什么会出现 `Cannot find module '@zougt/some-loader-utils'` + 答:平台路径请不要使用中文命名!!!会造成解析乱码!!!请使用全英文路径!!! + +## 平台出现报错 `Access is denied`(`windows` 常见) + +![error](~@alias/img/guide/error1.png) + +- 解决办法:请遵循平台要求,安装对应的 `node` 和 `pnpm` 版本 ( `node` 16 版本及以上、`pnpm` 6 版本及以上) + +## 安装依赖时出现报错 `Cannot find module 'sass'` + +答:删除平台的 `pnpm-lock.yaml` 和 `node_modules` ,重新执行命令 `pnpm install` 安装依赖即可。(重点:`文件存放路径不要带有中文`) + +## 动态路由刷新出现警告 ⚠️ + +- 为什么会出现警告?会不会影响使用? + 答:这个警告是 `vue-router` 作者故意留下的,咱也不知道为啥,详情看 [issues](https://github.com/vuejs/router/issues/521#issuecomment-706680593)。不会影响使用,功能一切表现正常,平台打包部署到生产环境就不会出现警告了。 + 已通过 [vite-plugin-router-warn](https://www.npmjs.com/package/vite-plugin-router-warn) 解决。 + +## 平台出现警告 `rank only the home page can be 0` ⚠️ + +![rank](~@alias/img/guide/rank.png) + +答:路由 `meta` 里的 `rank` 字段只有 `home` 路由才能是 `0` ,其他均不能为 `0` 。作为一种规范,`rank` 字段最好唯一。`rank` 字段代表菜单的排序,而且只能是顶级菜单进行排序,也就是最外层的菜单,为什么这么设计呢。详见[issues/154](https://github.com/ronnaces/ronna-admin/issues/154#issuecomment-996571156)。 + +## 为什么平台使用 `lodash-unified` ,而不是使用 `lodash-es` 呢? + +答:其实 `lodash-unified` 只是对 `lodash-es` 做了 `ESM` (ESModule)格式支持并兼容 `CJS` (CommonJS)格式,`vite` 又是使用原生 `ESM` 文件快速启动。这里需要注意的是 `lodash-unified` 和 `lodash-es` 需要同时安装。 +用法:`import { sum } from "lodash-unified"`。 + +## 为什么平台使用手动按需引入,而不是使用 `unplugin-vue-components` 插件自动按需引入呢? + +答:我尝试将 `unplugin-element-plus` 替换成 `unplugin-vue-components` ,但似乎 `unplugin-vue-components` 表现不是太好,整体来说有些问题,可以看看 [unplugin-vue-components/issues](https://github.com/antfu/unplugin-vue-components/issues) 了解一下,而且 `unplugin-vue-components` 不是为 `element-plus` 特供的产物,毕竟 `vite` 等工具还在高速发展,可能会出现一些莫名的问题影响项目,我之前碰到过开发环境没事,打包就凉了(这里是 vite 某个版本的问题),这很坑,所以我感觉手动按需引入更有安全感,毕竟迭代了这么多版本,`unplugin-element-plus` 没出过问题。所以整体来说平台都把很多坑都踩过了,毕竟提供很多人使用,平台应该有这个责任在使用最新技术前进行调研,并在综合考虑下保留相对稳定的东西,给平台带来稳定。当然您也可自行替换成 `unplugin-vue-components` 插件自动按需引入。 + +## 为什么平台采用全局引入 `element-plus` ,而不是按需引入呢? 全局引入带来打包冗余,如何处理? 如何改成按需引入? + +- 为什么平台采用全局引入 `element-plus` ,而不是按需引入呢? + 答:① 经过多次实践,按需引入一个组件库的话,`vite` 的预编译的时间有点长(尤其是性能低的电脑或者您开了很多程序导致 `cpu` 占用过高),所以我们采用了全局引入的方式,不再让它预编译,而是直接加载整个包。② 按需引入会出现 `new dependencies optimized` 的情况,这个情况一旦出现就会使得页面重新加载,如下图,开发体验不好。 + +![optimized](~@alias/img/guide/optimized.png) +上图的问题,估计是 `vite` 还需进行优化,下图是来自 `vite` 官方开发者的回复[issues](https://github.com/vitejs/vite/issues/7608#issuecomment-1087877492) +![vite](~@alias/img/guide/vite.png) + +- 全局引入带来打包冗余,如何处理? + 答:全局引入,打包不会在进行 `tree shanking` ,带来未引用的代码也打包进来,造成冗余问题。如何解决呢。目前来说只能在打包时,平台改用 `unplugin-element-plus` 插件按需引入模式,开发时,再换成全局引入。 + +- 如何改成按需引入? + ① 安装 `unplugin-element-plus` ,执行命令: + ```sh + pnpm add unplugin-element-plus -D + ``` + ![ep1](~@alias/img/ep/ep1.png) + ② 来到根目录 `build/plugins.ts` 文件,去掉 `import ElementPlus from "unplugin-element-plus/vite";` 和 `ElementPlus({}),` 的代码注释 + ![ep2](~@alias/img/ep/ep2.png) + ③ 来到根目录 `src/main.ts` 文件,注释 `import ElementPlus from "element-plus";` ,添加 `import { useElementPlus } from "/@/plugins/element-plus";` ,将 `use(ElementPlus)` 替换成 `use(useElementPlus)` + ![ep3](~@alias/img/ep/ep3.png) + ④ 千万别忘记,把用到的 `element-plus` 组件引入到根目录 `src/plugins/element-plus/index.ts` 文件中 + +## `vertical` 模式下左侧菜单卡顿,如何解决?菜单切换卡顿? + +- `vertical` 模式下左侧菜单卡顿,如何解决? + 答:这个问题大多数出现在 `windows` 上,特别是电脑性能低或者双屏的模式下。我的电脑从未出现过卡顿的情况。下图是我的电脑信息 + +![mac](~@alias/img/guide/mac.png) + +`element-plus` 的 `menu` 在上述的情况可能会出现卡顿。 + +两种解决办法: + +① 从软件上解决:来到 [public/platform-config.json](https://github.com/ronnaces/ronna-admin/blob/main/public/platform-config.json#L20) 设置 `MenuArrowIconNoTransition` 为 `true` 即可以解决,当然平台已经设置过了。菜单经过测试在谷歌浏览器 `92` 到 `94` 版本是不卡顿的,谷歌浏览器版本下载地址 [chromedownloads](https://www.chromedownloads.net/chrome64osx/),卡顿是这个 [transform: rotateZ(180deg)](https://github.com/element-plus/element-plus/blob/dev/packages/components/menu/src/sub-menu.ts#L320) 造成的,貌似是谷歌的 [bug](https://bugs.chromium.org/p/chromium/issues/detail?id=1384444) 吧 +② 从硬件上解决:运行 window + x 打开计算机管理界面,找到设备管理器(或者英文 Device Manager),打开显示适配器(或者英文 Display Adapters),如果列表内展示的有 Inter(R) HD Graphics,则说明此电脑具有集成显卡,禁用掉此项(集成显卡),将独立显卡开启满载状态。[Windows 怎么禁用集成显卡](https://jingyan.baidu.com/article/fd8044fae944b61131137ab1.html) + +- 菜单切换卡顿? + 答:有人问平台演示环境菜单切换卡顿,是什么问题? + ① 首先,平台的演示环境使用的是 [github](https://github.com/) ,一个免费的静态网站部署服务,切换菜单的时候,需要加载网络资源,走了请求,响应越慢,页面显示的越慢。 + ② 其次,本地运行平台的完整版,有的菜单切换卡顿,因为也要加载资源啊,比如地图什么的,当前页面加载资源越大,正常情况下响应就越慢,这是最基本的知识哦。 + +## 浏览器控制台打印一些重复信息,很影响开发体验,如何解决? + +![log](~@alias/img/guide/log.png) + +答:如下图所示,触发了 `vite` 的 `hmr update` 就会在控制台输出相对应的信息 [issues](https://github.com/vitejs/vite/issues/1785) ,有时候输出的信息对于我们来说并没有用,是否可以屏蔽掉这些信息呢?当然可以,在浏览器控制台过滤框中输入您不需要的信息并在最前面加上 `-` 即可。[浏览器控制台过滤无用的提示和报错](https://blog.csdn.net/qq_33674300/article/details/114764718) + +![hotlog](~@alias/img/guide/hotlog.png) + +## `vue3` 的 ` +``` + +目前`vue`官方已支持 [defineOptions](https://cn.vuejs.org/api/sfc-script-setup.html#defineoptions) + +## `vue3` 单文件支持多个根标签,但是平台为什么不能这么用呢?如何解决? + +- 平台为什么不能这么用呢? + 答:因为平台用了 `vue3` 中 `Transition` 组件包裹整个内容区,这样才能带来各种页面切换效果。但是 `Transition` 仅支持单个元素或组件作为其插槽内容。如果内容是一个组件,则该组件也必须只有一个根元素,所以这才要求内容区里的单文件要在最外层加上一个根元素,详情看 [TIP](https://cn.vuejs.org/guide/built-ins/transition.html#the-transition-component) + +- 如何解决? + 答:如果想内容区的单文件支持多个根元素,可以来到这里 [appMain.vue](https://github.com/ronnaces/ronna-admin/blob/main/src/layout/components/appMain.vue#L41) 将 `Transition` 以及相关地方删除,不在要页面内容过渡效果了。 + +## 不同项目的本地存储设置可能不同(页面效果不同),那么如何避免 `fork` 项目的本地存储 `key` 值一样呢? + +- 平台使用的 [响应式本地存储](https://github.com/xiaoxian521/responsive-storage),默认的 `key` 全部以 `responsive-` 开头,如下图所示 + +![namespace](~@alias/img/guide/namespace.jpg) + +- 如何避免? + 答:可以在 [此处](https://github.com/ronnaces/ronna-admin-doc/blob/main/public/platform-config.json#L25) 修改 `ResponsiveStorageNameSpace` 为您所需的命名空间即可 + +## 平台要求 `node` 版本应不小于 `18.18.0` 、`pnpm` 版本应不小于 `8.6.10` ,但是实际开发有的项目需要比这些低的版本怎么解决呢? + +答:推荐阅读 [三款非常实用的 Node.js 版本管理工具](https://blog.csdn.net/qq_36380426/article/details/126218495) + +## 打包时报 `Unexpected token`,如下图(来自群友提供) + +![unexpected](~@alias/img/guide/unexpected.jpg) + +首先请您 `不要` 用 `中文路径名`,然后我们来解答一下 + +答:这里报错来自于 [vite-plugin-remove-console](https://github.com/xiaoxian521/vite-plugin-remove-console),当 `console.log` 写法不规范或者这个文件是压缩格式时就会出现这种报错,请在 `external` 中排除这个 `console.log` 出现的文件,参考 [removeConsole](https://github.com/ronnaces/ronna-admin/blob/main/build/plugins.ts#L50) + +## 安装依赖慢,如何解决? + +可能您刚接触到 `ronna-admin` 会有个疑问,为什么平台使用了 `pnpm` 可是安装平台依赖的时候还是等了很长时间呢? + +答:首先我觉得您可以认真看下 [pnpm](/pages/FAQ/#为什么使用-pnpm-pnpm-天生支持-monorepo-为什么平台不采用这种模式呢-可以不使用-pnpm-吗-如何从-pnpm-切换到-yarn) 哦。其次,`pnpm` 只会在项目依赖包从本地找不到对应版本的情况下,才会去 [npm](https://www.npmjs.com/) 下载,既然是 `npm` 下载的话,它肯定是国外镜像,下载慢就很正常了。下面讲下解决办法: + +① 使用下面命令查看当前 `npm` 源 + +``` +npm config ls +``` + +执行完上面的命令后,在您没有设置过任何源的情况下,默认是 [npmjs](https://www.npmjs.com/) 官方源,如下图 + +![npm](~@alias/img/guide/npm1.jpg) + +② 不管是什么源,我们都可以不用管,直接执行下面命令即可 + +``` +npm config set registry https://registry.npmmirror.com +``` + +上面的命令是将本地的源换成国内源 [npmmirror](https://npmmirror.com/),经过几轮测试,发现它的下载速度快且同步率高,同步频率 `10` 分钟一次,如果您之前的源是这个 `http://registry.npm.taobao.org` ,那您必须换成 `npmmirror` 啦,因为原淘宝 `npm` 域名即将停止解析 [具体了解](https://zhuanlan.zhihu.com/p/465424728?spm=a2c6h.24755359.0.0.6d444dccAL1K1J) +执行完上面的命令后再使用 `①` 中的命令查看本地源,如下图 + +![npm](~@alias/img/guide/npm2.jpg) + +③ 当我们将本地源换成 `npmmirror` 后,再回到 `ronna-admin` 平台,将 `pnpm-lock.yaml` 和 `node_modules` 这两个文件删除,然后执行下面的命令重新安装依赖,您就会发现安装速度很快啦 + +``` +pnpm install +``` + +如果您不删除上面提到的两个文件就会遇到如下图的报错 + +![npm](~@alias/img/guide/npm3.jpg) + +:::tip +如果您本地有自己维护的 `npm` 包,请在发包前使用下面命令将本地源换成 `npm` 官方源,这样才能保证您发包成功,发完之后再换成 `npmmirror` 源即可。同理,如何您公司有私服的话,也是如此操作,只不过把下面命令 `registry` 后的地址换成私服的地址即可。如何部署私服可参考 [该文章](https://www.cnblogs.com/venblogs/p/14371381.html) + +``` +npm config set registry https://registry.npmjs.org +``` + +当然第二种办法也是最方便的办法就是将下面代码加入到您自己库的 `package.json` 里 [查看具体参考](https://github.com/ronnacesronna-admin-table/blob/main/package.json#L24-L26) + +```JSON +"publishConfig": { + "registry": "https://registry.npmjs.org/" +} +``` + +::: + +## 安装 `vue` 的某些版本,页面卡顿明显,如何解决? + +答:`vue v3.2.41` 及以上版本和 `Vue.js devtools v6.4.5` 两者一起使用,页面卡顿明显,尤其当页面元素多以及同一时刻操作较多元素是最为明显。解决办法:卸载 `Vue.js devtools` 这款浏览器插件,卸载后,页面比之前操作还流畅 🐶。这足以看出 `Vue.js devtools` 影响还是很大的,可以尝试不依赖 `Vue.js devtools`,我这些年用 `vue` 基本不用 `Vue.js devtools`,毕竟浏览器的断点调试足够了,当然这也可以锻炼您的思维能力 + +## 平台出现报错 `global is not defined` + +答:可能是您引入某个库的问题,比如 [aws-sdk-js](https://github.com/aws/aws-sdk-js),解决办法就是将 [src/utils/globalPolyfills.ts](https://github.com/ronnaces/ronna-admin-doc/blob/main/src/utils/globalPolyfills.ts) 引入 [src/main.ts](https://github.com/ronnaces/ronna-admin-doc/blob/main/src/main.ts) + +## 平台如何置灰并且不影响操作? + +::: details 展开查看实现代码 + +![grey](~@alias/img/guide/grey.jpg) + +``` +* { filter: grayscale(100%); } + +import { toggleClass } from "@pureadmin/utils"; + +beforeCreate() { + toggleClass(true, "html-grey", document.querySelector("html")); +}, +``` + +::: + +## 平台在使用 `element-plus` 的 `el-dialog`、`el-drawer`、`el-message-box`、`el-notification` 这四个组件时,右上角关闭图标的样式跟 `element-plus` 本身表现不一致? + +答:在平台 `3.9.2` 版本,我把样式覆盖了,使其表现更鲜明(细心的小伙伴会发现 `vscode` 好多操作鼠标覆盖上去也是这种样式风格 🤗️),具体代码修改位置 [第一处](https://github.com/ronnaces/ronna-admin/commit/c80818d792276666aaea4b18413a0f08777f2ed1#diff-65a69f4a70b50de99604a7cae0784ee0e63a22f5d3addc384d50f76bbba1a2c2)、[第二处](https://github.com/ronnaces/ronna-admin/commit/c80818d792276666aaea4b18413a0f08777f2ed1#diff-6e577e4119a687e405cdbfac69a8fa06cbcc3b80eeca1d3766d936961de4f3a5),如果想保持一致删除对应改动处即可 + +::: details 展开查看平台当前这四个组件右上角关闭图标的样式 + +![dialog](~@alias/img/ep/dialog.jpg) +![dialog-dark](~@alias/img/ep/dialog-dark.jpg) + +![drawer](~@alias/img/ep/drawer.jpg) +![drawer-dark](~@alias/img/ep/drawer-dark.jpg) + +![messagebox](~@alias/img/ep/messagebox.jpg) +![messagebox-dark](~@alias/img/ep/messagebox-dark.jpg) + +![notification](~@alias/img/ep/notification.jpg) +![notification-dark](~@alias/img/ep/notification-dark.jpg) + +::: + +## 平台在 `v3.9.4` 版本完全移除了 `vxe-table`,为什么移除?如何自行集成? + +- 为什么移除? + +答:[请点击这里查看原因](https://github.com/ronnaces/ronna-admin/issues) + +- 如何自行集成? + +::: details + +1. 安装 `vxe-table`、`xe-utils` + +``` +pnpm add vxe-table xe-utils +``` + +2. 将 `vxe-table` 和 `xe-utils` 加入 `build/optimize.ts` 文件的 `include` 里 + +3. 安装 `font-awesome` + +``` +pnpm add font-awesome -D +``` + +4. 在 `src/layout/index.vue` 文件的 `` 引入 `font-awesome`,如下 + +```Vue + +``` + +5. 将下面样式加入 `src/style/index.scss` 文件 + +```Css +/* 重置 vxe-table 样式 */ +.vxe-button.type--button.theme--primary:hover, +.vxe-pager .vxe-pager--num-btn:not(.is--disabled).is--active { + color: #fff !important; +} +``` + +6. 将下面样式加入 `src/style/dark.scss` 文件 + +```Css +/* vxe-table 暗黑模式适配 */ +.vxe-table--header-wrapper, +.vxe-table--body-wrapper { + color: var(--el-text-color-primary); + background: var(--el-bg-color) !important; +} + +.vxe-table--render-default.border--full .vxe-header--column, +.vxe-table--render-default.border--full .vxe-body--column, +.vxe-table--render-default.border--full .vxe-footer--column { + background-image: linear-gradient( + var(--el-border-color-lighter), + var(--el-border-color-lighter) + ), + linear-gradient( + var(--el-border-color-lighter), + var(--el-border-color-lighter) + ); +} + +/* 表头 */ +.vxe-table--header-wrapper { + background: #262727 !important; +} + +.vxe-table--render-wrapper, +.vxe-table--main-wrapper { + border: none; +} + +.vxe-pager.is--perfect, +.vxe-table--render-default .vxe-table--border-line { + border: 1px solid var(--el-border-color-lighter); +} + +.vxe-table--header-border-line { + border-bottom: 1px solid var(--el-border-color-lighter) !important; +} + +.vxe-body--row.row--hover, +.vxe-pager { + background-color: #262727; +} + +.vxe-input--inner, +.vxe-pager .vxe-pager--jump-prev, +.vxe-pager .vxe-pager--prev-btn, +.vxe-pager .vxe-pager--next-btn, +.vxe-pager .vxe-pager--jump-next, +.vxe-pager .vxe-pager--num-btn, +.vxe-pager .vxe-pager--jump .vxe-pager--goto { + background-color: transparent; + color: var(--el-text-color-primary); + // outline: none !important; +} + +.vxe-select-option--wrapper { + background: var(--el-bg-color) !important; +} + +.vxe-select-option:not(.is--disabled).is--hover { + background: var(--el-color-primary-light-6) !important; +} + +.vxe-modal--wrapper.type--modal .vxe-modal--box, +.vxe-modal--wrapper.type--alert .vxe-modal--box, +.vxe-modal--wrapper.type--confirm .vxe-modal--box, +.vxe-form { + background: var(--el-bg-color) !important; +} + +.vxe-modal--box, +.vxe-modal--header { + border: none; + background: var(--el-bg-color) !important; +} + +.vxe-modal--title, +.vxe-button--content, +.vxe-modal--header-title { + color: var(--el-text-color-primary); +} + +.vxe-button.type--button:hover { + background: var(--el-color-primary) !important; +} + +.vxe-button { + background-color: transparent; +} +``` + +7. 使用下面代码直接替换 `src/layout/theme/index.ts` 里的所有代码 + +```Ts +/** + * @description ⚠️:此文件仅供主题插件使用,请不要在此文件中导出别的工具函数(仅在页面加载前运行) + */ + +import { EpThemeColor } from "../../../public/platform-config.json"; + +type MultipleScopeVarsItem = { + scopeName: string; + varsContent: string; +}; + +/** 将vxe默认主题色和ep默认主题色保持一致 */ +const vxeColor = EpThemeColor; +/** 预设主题色 */ +const themeColors = { + default: { + vxeColor, + subMenuActiveText: "#fff", + menuBg: "#001529", + menuHover: "#4091f7", + subMenuBg: "#0f0303", + subMenuActiveBg: "#4091f7", + menuText: "rgb(254 254 254 / 65%)", + sidebarLogo: "#002140", + menuTitleHover: "#fff", + menuActiveBefore: "#4091f7" + }, + light: { + vxeColor, + subMenuActiveText: "#409eff", + menuBg: "#fff", + menuHover: "#e0ebf6", + subMenuBg: "#fff", + subMenuActiveBg: "#e0ebf6", + menuText: "#7a80b4", + sidebarLogo: "#fff", + menuTitleHover: "#000", + menuActiveBefore: "#4091f7" + }, + dusk: { + vxeColor: "#f5222d", + subMenuActiveText: "#fff", + menuBg: "#2a0608", + menuHover: "#e13c39", + subMenuBg: "#000", + subMenuActiveBg: "#e13c39", + menuText: "rgb(254 254 254 / 65.1%)", + sidebarLogo: "#42090c", + menuTitleHover: "#fff", + menuActiveBefore: "#e13c39" + }, + volcano: { + vxeColor: "#fa541c", + subMenuActiveText: "#fff", + menuBg: "#2b0e05", + menuHover: "#e85f33", + subMenuBg: "#0f0603", + subMenuActiveBg: "#e85f33", + menuText: "rgb(254 254 254 / 65%)", + sidebarLogo: "#441708", + menuTitleHover: "#fff", + menuActiveBefore: "#e85f33" + }, + yellow: { + vxeColor: "#fadb14", + subMenuActiveText: "#d25f00", + menuBg: "#2b2503", + menuHover: "#f6da4d", + subMenuBg: "#0f0603", + subMenuActiveBg: "#f6da4d", + menuText: "rgb(254 254 254 / 65%)", + sidebarLogo: "#443b05", + menuTitleHover: "#fff", + menuActiveBefore: "#f6da4d" + }, + mingQing: { + vxeColor: "#13c2c2", + subMenuActiveText: "#fff", + menuBg: "#032121", + menuHover: "#59bfc1", + subMenuBg: "#000", + subMenuActiveBg: "#59bfc1", + menuText: "#7a80b4", + sidebarLogo: "#053434", + menuTitleHover: "#fff", + menuActiveBefore: "#59bfc1" + }, + auroraGreen: { + vxeColor: "#52c41a", + subMenuActiveText: "#fff", + menuBg: "#0b1e15", + menuHover: "#60ac80", + subMenuBg: "#000", + subMenuActiveBg: "#60ac80", + menuText: "#7a80b4", + sidebarLogo: "#112f21", + menuTitleHover: "#fff", + menuActiveBefore: "#60ac80" + }, + pink: { + vxeColor: "#eb2f96", + subMenuActiveText: "#fff", + menuBg: "#28081a", + menuHover: "#d84493", + subMenuBg: "#000", + subMenuActiveBg: "#d84493", + menuText: "#7a80b4", + sidebarLogo: "#3f0d29", + menuTitleHover: "#fff", + menuActiveBefore: "#d84493" + }, + saucePurple: { + vxeColor: "#722ed1", + subMenuActiveText: "#fff", + menuBg: "#130824", + menuHover: "#693ac9", + subMenuBg: "#000", + subMenuActiveBg: "#693ac9", + menuText: "#7a80b4", + sidebarLogo: "#1f0c38", + menuTitleHover: "#fff", + menuActiveBefore: "#693ac9" + } +}; + +/** + * @description 将预设主题色处理成主题插件所需格式 + */ +export const genScssMultipleScopeVars = (): MultipleScopeVarsItem[] => { + const result = [] as MultipleScopeVarsItem[]; + Object.keys(themeColors).forEach(key => { + result.push({ + scopeName: `layout-theme-${key}`, + varsContent: ` + $vxe-primary-color: ${themeColors[key].vxeColor} !default; + $subMenuActiveText: ${themeColors[key].subMenuActiveText} !default; + $menuBg: ${themeColors[key].menuBg} !default; + $menuHover: ${themeColors[key].menuHover} !default; + $subMenuBg: ${themeColors[key].subMenuBg} !default; + $subMenuActiveBg: ${themeColors[key].subMenuActiveBg} !default; + $menuText: ${themeColors[key].menuText} !default; + $sidebarLogo: ${themeColors[key].sidebarLogo} !default; + $menuTitleHover: ${themeColors[key].menuTitleHover} !default; + $menuActiveBefore: ${themeColors[key].menuActiveBefore} !default; + ` + } as MultipleScopeVarsItem); + }); + return result; +}; +``` + +8. 新建文件夹,起名 `vxe-table` ,然后添加 `index.scss` 和 `index.ts` 这两个文件到 `vxe-table` 文件夹里,如下 + +- `vxe-table` 文件夹 +- `index.scss` 文件 + +```Css +@import "vxe-table/styles/variable.scss"; +@import "vxe-table/styles/modules.scss"; + +i { + border-color: initial; +} +``` + +- `index.ts` 文件 + +```Ts +import "xe-utils"; +import "./index.scss"; +import XEUtils from "xe-utils"; +import { App, unref } from "vue"; +import { i18n } from "@/plugins/i18n"; +import zh from "vxe-table/lib/locale/lang/zh-CN"; +import en from "vxe-table/lib/locale/lang/en-US"; + +import { + // 核心 + VXETable, + // 表格功能 + Icon, + Filter, + Edit, + Menu, + Export, + Keyboard, + Validator, + // 可选组件 + Column, + Colgroup, + Grid, + Tooltip, + Toolbar, + Pager, + Form, + FormItem, + FormGather, + Checkbox, + CheckboxGroup, + Radio, + RadioGroup, + RadioButton, + Switch, + Input, + Select, + Optgroup, + Option, + Textarea, + Button, + Modal, + List, + Pulldown, + // 表格 + Table +} from "vxe-table"; + +// 全局默认参数 +VXETable.setup({ + size: "medium", + version: 0, + zIndex: 1002, + table: { + // 自动监听父元素的变化去重新计算表格 + autoResize: true, + // 鼠标移到行是否要高亮显示 + highlightHoverRow: true + }, + input: { + clearable: true + }, + i18n: (key, args) => { + return unref(i18n.global.locale) === "zh" + ? XEUtils.toFormatString(XEUtils.get(zh, key), args) + : XEUtils.toFormatString(XEUtils.get(en, key), args); + }, + translate(key) { + const NAMESPACED = ["el.", "buttons."]; + if (key && NAMESPACED.findIndex(v => key.includes(v)) !== -1) { + return i18n.global.t.call(i18n.global.locale, key); + } + return key; + } +}); + +export function useTable(app: App) { + app + .use(Icon) + .use(Filter) + .use(Edit) + .use(Menu) + .use(Export) + .use(Keyboard) + .use(Validator) + // 可选组件 + .use(Column) + .use(Colgroup) + .use(Grid) + .use(Tooltip) + .use(Toolbar) + .use(Pager) + .use(Form) + .use(FormItem) + .use(FormGather) + .use(Checkbox) + .use(CheckboxGroup) + .use(Radio) + .use(RadioGroup) + .use(RadioButton) + .use(Switch) + .use(Input) + .use(Select) + .use(Optgroup) + .use(Option) + .use(Textarea) + .use(Button) + .use(Modal) + .use(List) + .use(Pulldown) + // 安装表格 + .use(Table); +} +``` + +9.最后一步,将下面代码添加到 `src/main.ts` 文件,然后您就可以按照 [vxetable](https://vxetable.cn/v4/#/table/start/quick) 文档去使用啦 + +```Ts +import { useTable } from "@/plugins/vxe-table"; + +// 记得要用 app.use 注册下哦 +app.use(useTable) +``` + +:::tip 具体修改记录 +[点击查看完整版具体修改记录](https://github.com/ronnaces/ronna-admin-doc/commit/3629a66535d3d47bec04be9f73becbd12d339fe0) +[点击查看非国际化精简版具体修改记录](https://github.com/ronnaces/ronna-admin-thin/commit/27056e75609637508fa8818439c553082600b00f) +[点击查看国际化精简版具体修改记录](https://github.com/ronnaces/ronna-admin-thin/commit/23d9cdaf81cb543b8659d7c2b5f969e8b53364b5) +::: + +## 平台在 `v3.9.5` 版本完全移除了 `lodash` 和其相关库,为什么移除?如何自行集成? + +- 为什么移除? + +答:[请点击这里查看原因](https://github.com/ronnaces/ronna-admin/issues/397#issue-1492326492) + +- 如何自行集成? + +::: details + +1. 安装 `lodash`、`lodash-es`、`lodash-unified` + +``` +pnpm add lodash lodash-es lodash-unified +``` + +2. 安装 `@types/lodash`、`@types/lodash-es` + +``` +pnpm add @types/lodash @types/lodash-es -D +``` + +3. 将 `lodash`、`lodash-es`、`lodash-unified` 这三个库加入到 [include](https://github.com/ronnaces/ronna-admin/blob/main/build/optimize.ts#L7) + +4. 如果需要在生产环境使用 `lodash cdn` ,将下面代码加入到 [modules](https://github.com/ronnaces/ronna-admin/blob/main/build/cdn.ts#L12) + +```Ts +{ + name: "lodash", + var: "lodash", + // 可写`完整路径`,会替换`prodUrl` + path: "https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.21/lodash.min.js" +} +``` + +5. 最后直接使用 `lodash-unified` 即可,如下代码 + +```Ts +import { cloneDeep } from "lodash-unified" +``` + +::: + +## `mac` 版本的向日葵无法远程操控?向日葵总是闪退、打不开? + +答:`mac` 版本的向日葵无法远程操控请参考下图解决 + +![xrk1](~@alias/img/guide/xrk1.jpg) + +答:向日葵总是闪退、打不开请参考下图解决 + +![xrk2](~@alias/img/guide/xrk2.jpg) + +## 初次拉取项目,使用 `vscode` 编辑器时代码出现 `eslint` 报错,如下图 + +![eslint](~@alias/img/guide/eslint.jpg) + +答:解决办法如下图,来自 [issues/953](https://github.com/ronnaces/ronna-admin/issues/953#issuecomment-1976024071) + +![eslint1](~@alias/img/guide/eslint1.jpg) diff --git "a/docs/01.\346\214\207\345\215\227/03.\345\205\266\344\273\226/02.\351\235\236\345\271\263\345\217\260\351\227\256\351\242\230\350\267\237\350\270\252\350\256\260\345\275\225.md" "b/docs/01.\346\214\207\345\215\227/03.\345\205\266\344\273\226/02.\351\235\236\345\271\263\345\217\260\351\227\256\351\242\230\350\267\237\350\270\252\350\256\260\345\275\225.md" new file mode 100644 index 0000000..eb6a2fa --- /dev/null +++ "b/docs/01.\346\214\207\345\215\227/03.\345\205\266\344\273\226/02.\351\235\236\345\271\263\345\217\260\351\227\256\351\242\230\350\267\237\350\270\252\350\256\260\345\275\225.md" @@ -0,0 +1,22 @@ +--- +title: 非平台问题跟踪记录 +article: false +date: 2022-11-11 +permalink: /pages/track/ +--- + +从 `2020年11月16` 开发平台到现在,已然忘记踩了多少坑,找了多少 `issues、pull requests` 以及重构了多少次,但是我并没有做记录,感觉很可惜,当然由于平台使用的技术比较新,也一直在跟随潮流,这也难免会出现一些很令人难以寻味的非平台 `bug`,从 `2022年11月11日` 起决定开始记录对平台影响较大的问题,供使用者参考(无任何抨击!感恩开源!) + +## `2022年11月11日`(`vue`、`Vue.js devtools`) + +### 发现 `vue` 的 `bug` + +- `vue v3.2.41` 及以上版本和 `Vue.js devtools v6.4.5` 两者一起使用,页面卡顿明显,尤其当页面元素多以及同一时刻操作较多元素是最为明显。解决办法:卸载 `Vue.js devtools`,毕竟我也不用 😄,断点调试足以(卸载 `Vue.js devtools` 后,页面比 `vue v3.2.41` 之前操作还流畅) + +### 排查方法 + +- 将 `vue` 升级到 `v3.2.41` 版本后,开发环境页面卡顿明显,当我打包后,线上预览很丝滑。然后我把平台的项目很多依赖都升级了个遍还不行,删除 `pnpm-lock.yaml` 和 `node_modules` 重新安装也不行,于是我怀疑是 `pnpm` 的问题,又把 `pnpm ` 从 `6` 升到 `7` 但还是不行,接着我把项目放到火狐浏览器运行,很流畅 😭,因为我平时不咋用火狐,没有安装任何插件,这样我就排查到问题出在谷歌浏览器的 `Vue.js devtools` 插件了,当前之前我在 `vue` 的 `issues` 中看到不少 `Vue.js devtools` 会导致页面崩溃和内存泄露的问题 + +## `2022年11月11日`(`vite`) + +`2022年11月11日` 我将平台的 `vite` 版本固定到了 `3.1.8` ,因为之后的版本问题还是有点多,尤其是这个 [issues](https://github.com/vitejs/vite/issues/10658),说的是 `vite v3.1.8` 以上版本首次启动在 `windows` 的表现比 `mac` 慢两倍。当然 `vite v4` 快来了,应该会解决很多问题,到时我们在升级。这里大家要注意下,依赖包还是跟着平台的版本去使用,不要随便升级,平台每次升级依赖都会去做测试(开发、生产) diff --git "a/docs/01.\346\214\207\345\215\227/03.\345\205\266\344\273\226/03.\351\227\256\351\242\230\345\217\215\351\246\210.md" "b/docs/01.\346\214\207\345\215\227/03.\345\205\266\344\273\226/03.\351\227\256\351\242\230\345\217\215\351\246\210.md" new file mode 100644 index 0000000..ffa366c --- /dev/null +++ "b/docs/01.\346\214\207\345\215\227/03.\345\205\266\344\273\226/03.\351\227\256\351\242\230\345\217\215\351\246\210.md" @@ -0,0 +1,14 @@ +--- +title: 问题反馈 +article: false +date: 2023-06-04 +permalink: /pages/support +--- + +### 网易邮箱 + +平台唯一账号 `kunlong_luo@163.com` + +### Github Issues + +[点我进行 bug 反馈](https://github.com/ronnaces/ronna-admin/issues/new/choose) diff --git "a/docs/01.\346\214\207\345\215\227/03.\345\205\266\344\273\226/04.git\345\270\270\347\224\250\345\221\275\344\273\244.md" "b/docs/01.\346\214\207\345\215\227/03.\345\205\266\344\273\226/04.git\345\270\270\347\224\250\345\221\275\344\273\244.md" new file mode 100644 index 0000000..dc102b0 --- /dev/null +++ "b/docs/01.\346\214\207\345\215\227/03.\345\205\266\344\273\226/04.git\345\270\270\347\224\250\345\221\275\344\273\244.md" @@ -0,0 +1,260 @@ +--- +title: git常用命令 +article: false +date: 2022-11-13 +permalink: /pages/git/ +--- + +## 程序员必备技能之 `Git` + +### 常用命令 + +#### 拉取代码 + +```sh +git clone xxx.git +``` + +#### 创建分支 + +```sh +git branch dev +# or +git checkout -b dev +# or +git switch -c dev +``` + +#### 切换本地分支 + +```sh +git checkout dev +# or +git switch dev +``` + +#### 切换分支并关联远程分支 + +```sh +git checkout -b dev origin/dev +# or +git checkout --track origin/dev +``` + +#### 查看本地所有分支 + +```sh +git branch +``` + +#### 查看远程所有分支 + +```sh +git branch -r +``` + +#### 删除本地分支 + +```sh +git branch -d dev +``` + +#### 删除远程分支 + +```sh +git push origin -d dev +``` + +#### 将代码从工作区添加暂存区 + +```sh +git add . +``` + +#### 查看尚未暂存的更新 + +```sh +git diff +``` + +#### 添加提交信息(`commit` 注释写错,执行 `git commit --amend` 此时会进入默认 `vim` 编辑器,修改注释后保存) + +```sh +git commit -m 'xxxx' +``` + +#### 推送代码到远程分支 + +```sh +git push origin dev + +# 强制推送(常在 git rebase 或 git reset 后使用) +git push -f origin dev +``` + +#### 拉取远程分支代码 + +```sh +git pull origin dev +``` + +#### 合并分支 + +```sh +git merge dev +``` + +#### 查看 `git` 状态 + +```sh +git status +``` + +#### 查看提交历史 + +```sh +git log +``` + +#### 查看可引用的历史版本记录 + +```sh +git reflog +``` + +#### 把本地未 `push` 的分叉提交历史整理成直线 + +```sh +git rebase origin/dev +``` + +#### 回到 `rebase` 执行之前的状态 + +```sh +git rebase --abort +``` + +#### 回退版本 + +```sh +# 回退指定 commit_id 版本 +git reset --hard commit_id + +# 回退上一个版本 +git reset --soft HEAD^ +# or +git reset --soft HEAD~1 +``` + +#### 撤销代码 + +```sh +git revert commit_id +``` + +#### 修改分支名 + +```sh +# 第一步 +git branch -m oldBranchName newBranchName + +# 第二步 +git push origin :oldBranchName + +# 第三步 +git push --set-upstream origin newBranchName +``` + +#### 查看 `git` 配置 + +```sh +# 查看全局配置 +git config --global --list + +# 查看用户名 +git config --global user.name +``` + +#### 添加用户名 + +```sh +git config --global --add user.name newName +``` + +#### 删除用户名 + +```sh +git config --global --unset user.name +``` + +#### 修改用户名 + +```sh +git config --global user.name newName +``` + +#### 配置 `Git` 用户名和邮箱 + +```sh +# 用户名 +git config --global user.name "Your Name" + +# 邮箱 +git config --global user.email "email@example.com" +``` + +#### 统计代码行数 + +```sh +git ls-files | xargs wc -l +``` + +#### 文件或文件夹重命名 + +`Git` 在 `Windows` 和 `macOS` 的默认文件系统中对文件大小写修改是不敏感的。可能你会先删除文件并提交,然后再新建文件再提交,这样做很麻烦,下面的 `git mv` 就简化了繁琐的操作 +比如文件 `filename.ts` 或文件夹 `jsutils`,它们的相对路径分别是 `src/filename.ts` 和 `src/jsutils` + +```sh +# 将 filename.ts 文件重命名为 fileName.ts,分下面两步 +# 第一步(注意下面的 name.ts 与 filename.ts 是不同的,如果你把 name.ts 改为 fileName.ts 是不行的,因为上面讲了仅大小写不同是不行的) +git mv src/filename.ts src/name.ts +# 第二步 +git mv src/name.ts src/fileName.ts + +# 将 jsutils 文件夹重命名为 jsUtils,分下面两步 +# 第一步 +git mv src/jsutils src/utils +# 第二步 +git mv src/utils src/jsUtils +``` + +## 提交规范 + +[相关参考](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-angular) + +`feat: 增加新功能` +`fix: 修复问题/BUG` +`style: 代码风格相关无影响运行结果的` +`perf: 优化/性能提升` +`refactor: 重构` +`revert: 撤销修改` +`test: 测试相关` +`docs: 文档/注释` +`chore: 依赖更新/脚手架配置修改等` +`workflow: 工作流改进` +`ci: 持续集成` +`types: 类型定义文件更改` +`wip: 开发中` + +## `CodeReview` 常用缩写 + +`PR`(Pull Request)拉取请求,给其他项目提交代码 +`LGTM`(Looks Good To Me)代码已经过 review,可以合并 +`SGTM`(Sounds Good To Me)和上面那句意思差不多,也是已经通过了 review 的意思 +`WIP`(Work In Progress)如果有个改动很大的 PR,可以在写了一部分的情况下先提交,但需在标题写上 WIP,以告诉项目维护者这个功能还未完成,方便维护者提前 review 部分提交的代码 +`PTAL`(Please Take A Look)提示别人来看一下 +`TBR`(To Be Reviewed)提示维护者进行 review +`TL;DR`(Too Long; Didn't Read)太长懒得看 +`TBD`(To Be Done(or Defined/Discussed/Decided/Determined)) 一般表示还没搞定 + +[简单易懂的 Git](https://www.bilibili.com/video/BV1KZ4y1o7gr/?p=1&vd_source=5a992808de6229d78e7810536c5f9ab3) diff --git "a/docs/01.\346\214\207\345\215\227/03.\345\205\266\344\273\226/05.\344\274\230\347\247\200\347\275\221\347\253\231\346\216\250\350\215\220.md" "b/docs/01.\346\214\207\345\215\227/03.\345\205\266\344\273\226/05.\344\274\230\347\247\200\347\275\221\347\253\231\346\216\250\350\215\220.md" new file mode 100644 index 0000000..16b07a0 --- /dev/null +++ "b/docs/01.\346\214\207\345\215\227/03.\345\205\266\344\273\226/05.\344\274\230\347\247\200\347\275\221\347\253\231\346\216\250\350\215\220.md" @@ -0,0 +1,24 @@ +--- +title: 技术网站推荐 +article: false +date: 2022-11-07 +permalink: /pages/recommendation/ +--- + +收集一些 `有用`、`常用`、`好用` 的网站 + +| [vue3 官方中文文档](https://cn.vuejs.org/) | [vite 官方中文文档](https://cn.vitejs.dev/) | [element-plus 官方中文文档](https://element-plus.org/zh-CN/) | +| :----------------------------------------------------------------- | :------------------------------------------------------------ | :----------------------------------------------------------------------------- | +| [pinia 官方中文文档](https://pinia.vuejs.org/zh/index.html) | [vue-router 官方中文文档](https://router.vuejs.org/zh/) | [Tailwind CSS 官方文档](https://tailwindcss.com/docs/installation) | +| [vitest 官方中文文档](https://cn.vitest.dev/) | [es6 中文文档](https://es6.ruanyifeng.com/#docs/proxy) | [axios 官方中文文档](https://axios-http.com/zh/) | +| [vxetable 官方中文文档](https://vxetable.cn/#/table/start/install) | [lodash 中文文档](https://www.lodashjs.com/) | [echarts 官方中文文档](https://echarts.apache.org/zh/index.html) | +| [animate.css 官方文档](https://animate.style/) | [设计师必备网站](https://www.meigong8.com/) | [JavaScript 中文文档](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript) | +| [JavaScript 风格指南一](https://github.com/airbnb/javascript) | [JavaScript 风格指南二](https://github.com/airbnb/javascript) | [rollup 官方中文文档](https://cn.rollupjs.org/) | +| [vueuse 文档](https://vueuse.org/) | [dayjs 官方中文文档](https://dayjs.github.io/zh-CN/) | [typescript 官方中文文档](https://www.tslang.cn/docs/home.html) | +| [swiper 官方文档](https://swiperjs.com/demos#default) | [vue-i18n 文档](https://vue-i18n.intlify.dev/) | [caniuse 浏览器兼容性查询](https://caniuse.com/) | +| [pnpm 官方中文文档](https://pnpm.io/zh/) | [tauri 中文官方文档](https://tauri.app/zh/) | [electron 官方中文文档](https://www.electronjs.org/zh/docs/latest) | +| [nuxt3 中文文档](https://nuxt.com.cn/) | [vue3 动画库 @vueuse/motion](https://motion.vueuse.org/) | [常用工具函数库 @pureadmin/utils](https://pure-admin-utils.netlify.app/) | +| [Rust 官方文档中文教程](https://rustwiki.org/) | [StackBlitz 在线开发工具](https://stackblitz.com/) | [React 官方中文文档](https://react.docschina.org/) | +| [nodejs 中文文档](https://nodejs.cn/) | [ESLint 官方中文文档](https://zh-hans.eslint.org/) | [Prettier 文档](https://prettier.io/docs/en/) | +| [Stylelint 中文文档](https://stylelint.nodejs.cn/) | [Babel 中文文档](https://babel.docschina.org/docs/) | [esbuild 中文文档](https://esbuild.bootcss.com/) | +| [tippy.js文档](https://atomiks.github.io/tippyjs/) | [vue-tippy文档](https://vue-tippy.netlify.app/installation) | | diff --git "a/docs/02.\344\274\230\350\264\250\346\234\215\345\212\241/01.\344\274\230\350\264\250\346\234\215\345\212\241.md" "b/docs/02.\344\274\230\350\264\250\346\234\215\345\212\241/01.\344\274\230\350\264\250\346\234\215\345\212\241.md" new file mode 100644 index 0000000..f44be66 --- /dev/null +++ "b/docs/02.\344\274\230\350\264\250\346\234\215\345\212\241/01.\344\274\230\350\264\250\346\234\215\345\212\241.md" @@ -0,0 +1,109 @@ +--- +title: 优质服务 +article: false +date: 2024-03-04 +permalink: /pages/service/ +--- + +非常感谢您选择了 `ronna-admin`。作者每天都在维护它,在保证其稳定的同时将 `95%` 的依赖包保持最新。所以您不用因为升级依赖包而头疼,因为我们会把坑都踩了。当某些依赖包(如`vue`、`vite`、`element-plus`等)发布版本不久后,我们会跟进升级,让您在快速迭代的前端中时刻享受着最新依赖包带来的便利! + +在代码、文档全部永久免费的基础上,我们还引入了更优质的可选服务,以满足您的各种需求! + + + +从 `2018` 年开始搞开源,一直到 `2024` 年一直维护 [ronna-admin](https://github.com/ronnaces/ronna-admin) 组织中所有项目,把热爱一直持续下去,将开源真正当作一项事业来做,为用户提供更好的解决方案和服务,求各位老板的支持呀 ❤️! + +## 项目重构、项目升级 + +价格:根据重构、升级难度进行合理定价 +服务内容:旧版 `ronna-admin` 升级最新版(通常需要一天包升级到位)、`vue2` 项目升级 `vue3`、自己项目某些依赖包想升级最新或升级时遇到瓶颈等 +如何获得服务:加最上方作者微信备注 `重构升级` 即可 + +## 技术指导、远程服务、面试指导、自定义服务 + +价格:根据问题难度进行合理定价,按次收费 +服务内容:各种前端问题解答、修复等。如果您还有别的需求尽管提,都会合理定价,包您满意 +如何获得服务:加最上方作者微信备注 `技术指导` 即可 + +## 页面定制开发(软件开发、项目外包) + +价格:根据页面数量、每页难度、开发周期进行合理定价 +服务内容:软件开发过程中保证 `页面高还原度`、`代码高质量`、`全方位多次测试` 。软件交付完毕后,不论您的软件工程量是大是小,我们都会提供 `一年免费技术支持`(免费小修、小改等),绝不辜负您选择了我们! +如何获得服务:加最上方作者微信备注 `软件开发` 即可 + +| **开发范围** | **范围种类** | +| ------------ | --------------------------------------------------------------------------------- | +| 网站 | 后台系统、可视化大屏、企业宣传页、活动推广页等各种只要能在浏览器查看的都能开发 | +| `h5`页面 | 移动端网站、广告推广、电子商务等 | +| 小程序 | 微信、支付宝、抖音、快手、京东小程序等 | +| 移动应用程序 | 可安装到安卓`Android`和苹果`iOS`系统的手机`App`软件 | +| 桌面应用程序 | 可安装到桌面操作系统(如`Windows`、`MacOS`、`Linux`)上的软件,可直接在电脑上运行 | + +## 企业赞助 + +成为赞助商即可获得以下服务 + +1. 将贵公司 `LOGO` 同时展示在 [ronna-admin 预览官网](https://ronna.ronnaces.com/) 、[ronna-admin 文档官网](https://ronnaces.github.io/ronna-admin-doc/) 以及 [GitHub 仓库 README](https://github.com/ronnaces/ronna-admin/blob/main/README.md) 页面的明显位置。 + +`ronna-admin` 文档官网 `日均约3万` 浏览量,更多详情请加最上方微信备注 `企业赞助` 进行详聊。 + +## 个人赞助 + +[ronnaces](https://github.com/ronnaces) 组织一直坚持代码、文档教程全部永久免费开源,如果 `ronna-admin` 帮助到了您,可以选择任意金额扫下方二维码进行赞助。赞助金额大于 `10` 元时,可在赞助时备注您的 `Github` 或 `github` 或某个博客地址,我们会将其加入下方赞助名单中。您的赞助也会推动我们开发更多优质免费代码、补充更多优质免费文档 + + +| 微信赞赏 | 微信 | 支付宝 | +|:--------------------------------------------------------------------:| :---: | :---: | +| 赞赏码 | Wechat QRcode| Alipay QRcode | + + +### 赞助名单 + +非常感谢您们的赞助! +如果链接备注错了的话 😳,请加我微信联系哈 +下面的昵称备注是我根据能获得的最大信息量推测的,称呼的不对,别见怪哈 😊 +最后就是兄弟们进群只需按照上面备注的价格哈,不用多转!!!备注的价格,已经足够把贴心服务做好了哈 ❤️ + +| **赞助人** | **金额** | **赞助人备注** | **作者的回复** | +| ------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --- | +| \*Alate | | 感谢你这样的开源人贡献~辛苦了!中国开源不容易。也希望你可以找到盈利模式可以健康持续的运营下去哈~嗯 加油!另外注意身体健康!适当运动。注意久坐就溜达下哈。尽量早睡哈~健康第一~不耽误你了~ | 短短几句, 我竟不知如何回答了,非常感谢你们,还有那些默默支持的,非常感谢! | | +| \*呼车 | `300` | 花点小钱,省点时间 | 感谢信任,谢谢我豪爽的大哥 ❤️ | | +| MUCv | `298` | 大佬你好,我是去年毕业的应届生,刚入行程序员不到一年,我是学 C++ 的,刚才公司摸鱼无意间在 B 站看到了大佬的视频,看了视频评论区,然后点开看了下 github 和 ronna-admin 文档,很受感动,虽然我不问项目和前端问题,但就想要买个大佬的服务支持下大佬,在国内这样的开源环境下,坚持在做对的事情 | 非常感谢哥们的支持,称呼我作者就行哈,嘿嘿。坚持在做热爱的事情,坚持在做对的事情,一起加油! ✊ ❤️ | | +| \*\*jcx | `200` | 全职开源不易,多的`200`是个人赞助,愿不忘初心,加油! | 不忘初心!!!非常感谢哥们 ❤️ | +| \*\*jb | `188` | 希望不忘初心,始终开源下去 👏 | 好的,大哥。多的不说了哈,一起看实际行动 ❤️ | +| \*\*豪c | `188` | 加油 | 一起加油,豪哥 ✊ ❤️ | +| \*贝a | `100` | +| Jung | `100` | 好东西要支持,能力范围之内,不要伤了作者一片至诚的心,哈哈哈哈哈 | 嘿嘿,非常感谢哥们支持哈 ❤️ | +| S\*hb | `100` | 开源不易,加油 | 非常感谢哥们,一起加油 ✊ | +| \*凡x | `99` | 加油加油 | 非常感谢哥们,一起加油 ✊ | +| \*刚q | `66.66` | 精简版终于更新到`5`版本了,来支持下 | 非常感谢哥们。`emm`,深夜还不睡觉,我怀疑你一直盯着我呢,哈哈 | +| \*不a\* | `66.60` | 多谢指导 | 客气啦 😉 | +| \*lang\* | `30` | | | | +| \*华c | `23` | | | +| \*蓝h | `20` | 欢庆精简版同步发布 | 嘿嘿,终于发布咯 | +| f\*dj | `15` | | | +| \*羽k | `12` | `ronna-admin` | 媒体查询+视窗单位 | +| \*\*明q | `10` | | | + +赞助金额高达 `100` 时,请加最上方微信,交个朋友 🤝 + + + + diff --git "a/docs/03.\350\265\204\346\272\220/01.\350\265\204\346\272\220.md" "b/docs/03.\350\265\204\346\272\220/01.\350\265\204\346\272\220.md" new file mode 100644 index 0000000..a70b072 --- /dev/null +++ "b/docs/03.\350\265\204\346\272\220/01.\350\265\204\346\272\220.md" @@ -0,0 +1,201 @@ +--- +title: 资源 +date: 2020-05-12 15:10:15 +permalink: /pages/db78e2 +article: false +--- + +## 插件推荐 + +* [vuepress-plugin-fulltext-search](https://github.com/leo-buneev/vuepress-plugin-fulltext-search) 全文搜索 + +* [vuepress-plugin-thirdparty-search](https://github.com/xugaoyi/vuepress-plugin-thirdparty-search) 可以添加第三方搜索链接的搜索框 + +* [vuepress-plugin-one-click-copy](https://www.npmjs.com/package/vuepress-plugin-one-click-copy) 代码块一键复制 + +* [vuepress-plugin-comment](https://github.com/dongyuanxin/vuepress-plugin-comment) 评论区 + +* [vuepress-plugin-vssue](https://vssue.js.org/) 评论区(单页) + +* [vuepress-plugin-vssue-global](https://github.com/u2sb/vuepress-plugin-vssue-global) 评论区(全局) + +* [vuepress-plugin-smplayer](https://github.com/u2sb/vuepress-plugin-smplayer) 播放器 + +* [vuepress-plugin-flowchart](https://www.npmjs.com/package/vuepress-plugin-flowchart) 流程图 + +* [vuepress-plugin-mathjax](https://www.npmjs.com/package/vuepress-plugin-mathjax) 数学公式 + +* [vuepress-plugin-tabs](https://www.npmjs.com/package/vuepress-plugin-tabs/) 选项卡 + +* [vuepress-plugin-element-ui](https://www.npmjs.com/package/vuepress-plugin-element-ui/) Element UI + +* [花里胡哨的插件](https://moefyit.github.io/moefy-vuepress/) 鼠标点击特效、背景彩带、音乐播放器等花里胡哨的插件 + +**更多插件...** + + - [Awesome VuePress](https://github.com/vuepressjs/awesome-vuepress) + + - [在npm中搜索"vuepress–plugin"](https://www.npmjs.com/search?q=vuepress%E2%80%93plugin) + + +## 社区优秀解决方案 + +### [1. 站点信息模块](https://notes.youngkbt.cn/about/website/info/) +在首页添加`站点信息模块`,效果: + +![](https://jsd.cdn.zzko.cn/gh/Kele-Bingtang/static/img/%E5%85%B3%E4%BA%8E/%E5%85%B3%E4%BA%8E%E6%9C%AC%E7%AB%99/20220102230720.png) + +在文章页添加`文章字数`、`阅读时间`、`浏览量`,效果: + +![](https://jsd.cdn.zzko.cn/gh/Kele-Bingtang/static/img/%E5%85%B3%E4%BA%8E/%E5%85%B3%E4%BA%8E%E6%9C%AC%E7%AB%99/20220103180059.png) + +### [2. 私密文章功能](https://notes.youngkbt.cn/about/website/private/) + +当大家想要「云端备份」文章到博客时,又不希望别人看到,该功能能满足你。 + +### [3. 首页大图模块](https://notes.youngkbt.cn/about/website/index-big-img/) + +喜欢首页大图模式的朋友可以参考此教程。 + +### [4. 优雅的全文搜索方案](https://wiki.eryajf.net/pages/dfc792/#%E5%89%8D%E8%A8%80) + + + +## 文章管理和发布 + +使用 [此插件 src-sy-post-publisher](https://github.com/terwer/src-sy-post-publisher) 发布[思源笔记](https://b3log.org/siyuan/)的文章到Vuepress等平台。 + +## 图标&配图 + +说明:以下图标**非主题内置**,你可以选择喜欢的图标右键保存或到图标库下载。更多图标:[阿里图标库](https://www.iconfont.cn/home/index) + +### 静态图标 + + + + + + + + + + + + + + + + + + + + + +
+ +

编程

+
+ +

服务器

+
+ +

机器学习

+
+ +

计算机网络

+
+ +

面向对象

+
+ +

软件开发

+
+ +

数据结构

+
+ +

数据库

+
+ +

思维导图

+
+ +

算法

+
+ +

网络技术

+
+ +

系统

+
+ +

系统分析

+
+ +

项目管理

+
+ + +### 萌系图标 + +- [猫咪系列](https://www.iconfont.cn/collections/detail?spm=a313x.7781069.1998910419.dc64b3430&cid=37776) +![](https://jsd.cdn.zzko.cn/gh/xugaoyi/image_store@master/maomi.51n7h2qwlv00.webp)
+- [数码宝贝](https://www.iconfont.cn/collections/detail?spm=a313x.7781069.1998910419.dc64b3430&cid=38124) +![](https://jsd.cdn.zzko.cn/gh/xugaoyi/image_store@master/smbb.3h83bez4dka0.webp) +- [水果系列](https://www.iconfont.cn/collections/detail?spm=a313x.7781069.1998910419.dc64b3430&cid=38124) +![](https://jsd.cdn.zzko.cn/gh/xugaoyi/image_store@master/QQ20220122-122349@2x.4oqggy71iso0.webp) + + +### 动态图标 + + + + + + + + + +
+ +

猫1

+
+ +

猫2

+
+ +

猫3

+
+ +

猫4

+
+ +### 插画 +[免费插画](https://undraw.co/illustrations)
+[2D/3D/手绘插画](https://storytale.io/)
+[阿里插画库](https://www.iconfont.cn/illustrations/index)
+ +### 配图 +[可画-文章配图](https://www.canva.cn/) + +### Logo +[logo生成1](https://www.designevo.com/logo-maker/)
+[logo生成2](https://instantlogodesign.com/) + +### Emoji表情 +[Emoji百科](https://emojipedia.org/) + +::: tip 小技巧 +在任意输入框快速打开emoji表情方法:
+Windows系统下按Win + .
+Mac系统下按Control + Command + 空格 +::: + diff --git "a/docs/04.\350\265\236\345\212\251/01.\350\265\236\345\212\251.md" "b/docs/04.\350\265\236\345\212\251/01.\350\265\236\345\212\251.md" new file mode 100644 index 0000000..f981925 --- /dev/null +++ "b/docs/04.\350\265\236\345\212\251/01.\350\265\236\345\212\251.md" @@ -0,0 +1,35 @@ +--- +title: '支持这个项目' +date: 2020-05-12 15:09:57 +permalink: /pages/1b12ed +sidebar: false +article: false +--- + +如果您正在使用这个项目并感觉良好,或者是想支持我继续开发,您可以通过如下`任意`方式支持我: + +1. Star并分享 [ronna-admin](https://github.com/ronnaces/ronna-admin) :rocket: +2. 通过以下二维码 一次性捐款,打赏作者一杯茶。:tea: + +谢谢! :heart: + +| 微信赞赏 | 微信 | 支付宝 | +|:--------------------------------------------------------------------:| :---: | :---: | +| 赞赏码 | Wechat QRcode| Alipay QRcode | + +## 赞助商 +> 如果您想支持本项目,奈何囊中羞涩,您可以花十几秒点击下方赞助商进入注册(只需微信扫码就可以),赞助商就会代您赞助一笔小钱。 + +## 成为赞助商 + +成为赞助商,即可将您的品牌LOGO及标语同时展示在: +- GitHub仓库主页顶部 +- 官网首页顶部 +- 官网所有文档页左侧边栏顶部 + +**主题官网平均每月约8w+浏览量 + GitHub仓库每月约1w+浏览量** + +`联系方式: kunlong_luo@163.com` + +## 致谢 +感谢给予支持的朋友,您的支持是我前进的动力 🎉 diff --git a/docs/@pages/archivesPage.md b/docs/@pages/archivesPage.md new file mode 100644 index 0000000..a10c651 --- /dev/null +++ b/docs/@pages/archivesPage.md @@ -0,0 +1,6 @@ +--- +archivesPage: true +title: 博客文章 +permalink: /blog/ +article: false +--- diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..b6ad856 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,58 @@ +--- +home: true +heroImage: /img/logo.png +heroText: ronna-admin-doc +tagline: 🚀一款简洁高效的 Vue3 开箱即用的企业级中后台管理系统 + +actionText: 开始使用 → +actionLink: /pages/introduction/ +bannerBg: none # auto => 网格纹背景(有bodyBgImg时无背景),默认 | none => 无 | '大图地址' | background: 自定义背景样式 提示:如发现文本颜色不适应你的背景时可以到palette.styl修改$bannerTextColor变量 + +features: # 可选的 + - title: 💡 保持稳定的同时采用最新技术栈 + details: 基于Vue3、Vite、Element-Plus、TypeScript、Pinia、Tailwindcss等最新技术栈开发 + - title: ⚡️ 轻快热重载完善的打包优化方案 + details: 无论应用程序大小如何,都始终极快的模块热重载(HMR),内置完善的打包优化方案 + - title: 🤙 简易上手内置丰富组件工具函数 + details: 使用单文件组件语法