# 长银数智办公平台 采用Vue3.0 + TypeScript + Element Plus + Pinia + JSX + Tailwindcss ## 安装依赖 ~~~js npm install -g pnpm pnpm install pnpm serve ~~~ ## 启动平台 ~~~js pnpm dev ~~~ ## 项目打包 ~~~js pnpm build ~~~ ## 打包分析 ~~~js pnpm report ~~~ ## Docker支持 1. 自定义镜像名为 `vue-pure-admin` 的镜像(请注意下面命令末尾有一个点 `.` 表示使用当前路径下的 `Dockerfile` 文件,可根据实际情况指定路径) ~~~js docker build -t vue-pure-admin . ~~~ 2. 端口映射并启动 `docker` 容器(`8080:80`:表示在容器中使用 `80` 端口,并将该端口转发到主机的 `8080` 端口;`pure-admin`:表示自定义容器名;`vue-pure-admin`:表示自定义镜像名) ~~~js docker run -dp 8080:80 --name pure-admin vue-pure-admin ~~~ 操作完上面两个命令后,在浏览器打开 `http://localhost:8080` 即可预览 ## Git 提交规范 - `feat` 增加新功能 - `fix` 修复问题/BUG - `style` 代码风格相关无影响运行结果的 - `perf` 优化/性能提升 - `refactor` 重构 - `revert` 撤销修改 - `test` 测试相关 - `docs` 文档/注释 - `chore` 依赖更新/脚手架配置修改等 - `workflow` 工作流改进 - `ci` 持续集成 - `types` 类型定义文件更改 - `wip` 开发中 ## 项目保存自动格式化代码 **安装Eslint** ~~~js npm i -D eslint eslint-plugin-vue @typescript-eslint/parser @typescript-eslint/eslint-plugin ~~~ **安装Prettier** ~~~js npm i -D prettier eslint-config-prettier eslint-plugin-prettier ~~~ **创建.eslintrc.js** ~~~js module.exports = { root: true, env: { node: true }, extends: [ 'plugin:vue/vue3-essential', 'eslint:recommended', '@vue/typescript/recommended', '@vue/prettier', '@vue/prettier/@typescript-eslint', 'plugin:prettier/recommended' ], parserOptions: { parsar: '@typescript-eslint/parsar', ecmaVersion: 2020, sourceType: 'module' }, rules: { 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off' } } ~~~ **创建.prettierrc.js ** ~~~js module.exports = { printWidth: 120, // 换行字符串阈值 tabWidth: 2, // 设置工具每一个水平缩进的空格数 useTabs: false, semi: false, // 句末是否加分号 vueIndentScriptAndStyle: true, singleQuote: true, // 用单引号 trailingComma: 'none', // 最后一个对象元素符加逗号 bracketSpacing: true, jsxBracketSameLine: true, // jsx > 是否另取一行 arrowParens: 'always', // 不需要写文件开头的 @prettier insertPragma: false, // 不需要自动在文件开头加入 @prettier endOfLine: 'lf' // 换行符使用 lf } ~~~ **vscode .settings.json文件** ~~~js { "editor.fontSize": 20, // 编辑器字体大小 "terminal.integrated.fontSize": 18, // terminal 框的字体大小 "editor.tabSize": 2, // Tab 的大小 2个空格 "editor.formatOnSave": true, // 保存是格式化 "prettier.singleQuote": true, // 单引号 "editor.defaultFormatter": "esbenp.prettier-vscode", "[vue]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "editor.codeActionsOnSave": { "source.fixAll.eslint": true }, "eslint.format.enable": true, "eslint.validate": [ "javascript", "javascriptreact", "html", "vue", "typescript", "typescriptreact" ], } ~~~ ## 项目目录结构 ~~~json ├── .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 # 构建工具常用方法抽离 ├── 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 # 自定义通用组件 │ │ ├── ReAuth # 按钮级别权限组件 │ │ ├── ReCol # 封装 element-plus 的 el-col 组件 │ │ ├── ReDialog # 基于 element-plus 中 el-dialog 组件开发的函数式弹框 │ │ ├── ReIcon # 图标组件 │ │ ├── ReImageVerify # 图形验证码组件 │ │ ├── RePureTableBar # 配合 `@pureadmin/table` 实现快速便捷的表格操作 https://github.com/pure-admin/pure-admin-table */ │ ├── 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 文件 │ │ ├── progress # 封装 nprogress │ │ └── auth.ts # 处理用户信息和 token 相关 │ │ └── 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 配置 ~~~ ## CSS的原子化(Tailwind Css) 官方地址文档 [Tailwindcss](https://tailwind.nodejs.cn/) 在`vscode` 插件商店搜索`bradlc.vscode-tailwindcss` 安装后, 鼠标覆盖对应的类名,既可以带来智能的提示 1. 拿最常用的 `width` 属性来举例,`tailwindcss` 内置了这些 [width#class-reference (opens new window)](https://tailwindcss.com/docs/width#class-reference)类名,有时候用户想写任意宽度值怎么做呢,比如给 `div` 一个 `666px` 的宽度 ,只需要按照下面的写法。当然不仅仅是宽度可以自定义,所有属性都支持这种模式,你只需要在自定义的时候用 `[ ]`包起来即可。 ~~~html
~~~ 2. 单个实用程序类加`!important` ```html

``` ~~~html
~~~ 3. 全局配置`!important` - 在`tailwind.config.js` 中进行配置即可 ~~~js module.exports = { important: true, }; ~~~ 4. 重用样式 ​ 当项目越来越大时,如果不规范使用`tailwindcss` ,很容易造成项目难以维护。 - 将重复的模块,抽离成组件 - 使用`@apply` 提取类, [参考](https://gitee.com/yiming_chang/vue-pure-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
~~~ 5. 定制化` Tailwind Css` - 具体详情看这里 [configuration](https://tailwindcss.com/docs/configuration) ## 类型声明(TypeScript) [TypeScript](https://www.tslang.cn/docs/home.html)作为 JavaScript 的超集,拥有强大的类型提示给我们的开发带来了极大的便利,尤其体现在团队合作开发中 ### 全局类型声明 在 `global.d.ts`和 `index.d.ts`文件中编写的类型可直接在 `.ts`、`.tsx`、`.vue` 中使用 ### `types/shims-tsx.d.ts` 该文件是为了给 `.tsx` 文件提供类型支持,在编写时能正确识别语法 ### `types/shims-vue.d.ts` `.vue`、`.scss` 文件不是常规的文件类型,`typescript` 无法识别,所以我们需要通过下图的代码告诉 `typescript` 这些文件的类型,防止类型报错 项目开发,我们可能需要安装一些库或者插件什么的,当它们对 `typescript` 支持不是很友好的时候,解决办法就是将这些通过 `declare module "包名"` 的形式添加到 types/shims-vue.d.ts中去 ### 自定义的全局组件 拿`Auth` 组件举例 1. 我们将 `Auth` 组件在 `main.ts` 中进行了全局注册 2. 然后将 `Auth` 组件在 `global-components.d`中引入,所有的全局组件都应该在 `GlobalComponents` 下引入才可获得类型支持 3. 最后我们直接写`xxx` 就可以得到类型提示啦