From 6d3d204b5e090dff10289b5063a3cb89ce4e4c31 Mon Sep 17 00:00:00 2001 From: grtsinry43 Date: Tue, 30 Jul 2024 13:09:46 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=89=8D=E7=AB=AF=E8=A7=84=E8=8C=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vitepress/config.mjs | 8 +- package-lock.json | 2 +- public/logo.png | Bin 0 -> 11480 bytes styleguide/index.md | 7 +- styleguide/part2.md | 429 +++++++++++++++++++++++++++++++++++++++--- 5 files changed, 418 insertions(+), 28 deletions(-) create mode 100644 public/logo.png diff --git a/.vitepress/config.mjs b/.vitepress/config.mjs index 8714e57..25b2691 100644 --- a/.vitepress/config.mjs +++ b/.vitepress/config.mjs @@ -1,4 +1,4 @@ -import {defineConfig} from 'vitepress' +import {defineConfig} from 'vitepress'; // https://vitepress.dev/reference/site-config export default defineConfig({ @@ -7,9 +7,13 @@ export default defineConfig({ titleTemplate: ':title - 升华工作室文档站', description: "中南大学升华工作室的文档网站,包含代码规范,技术教学文档,项目文档等", lastUpdated: true, + publicDir: 'public', + sitemap: { + hostname: 'https://docs.54sher.com' + }, themeConfig: { // https://vitepress.dev/reference/default-theme-config - logo: 'logo.png', + logo: '/logo.png', nav: [ {text: '主页', link: '/', activeMatch: '^/$'}, {text: '代码规范', link: '/styleguide/', activeMatch: '^/styleguide/'}, diff --git a/package-lock.json b/package-lock.json index 59ee2a7..4638449 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "vitepress-test", + "name": "54sh-docs", "lockfileVersion": 3, "requires": true, "packages": { diff --git a/public/logo.png b/public/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f823d21e606f380119ec3204af04878fc01c04eb GIT binary patch literal 11480 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 literal 0 HcmV?d00001 diff --git a/styleguide/index.md b/styleguide/index.md index 1aea1c6..9a5ddb3 100644 --- a/styleguide/index.md +++ b/styleguide/index.md @@ -1,14 +1,19 @@ # 代码规范 ::: tip -这部分内容同步自 [Grtsinry43's Docs](https://docs.grtsinry43.com/) ,最后一次更新于2024-07-24。 +这部分内容同步自 [Grtsinry43's Docs](https://docs.grtsinry43.com/) ,最后一次更新于 2024-07-24。 ::: ::: info 这里是我个人的代码规范,参考了大型开源项目以及一些知名企业的开发规范,希望大家能够有所收获,也能不断完善这个规范。 ::: ## 为什么要有代码规范? + 首先当前的技术趋势都是前后端分离,我们要保证相互的协作开发,需要有详细的代码规范,这样才能保证代码的可读性,可维护性,可扩展性,可测试性等等。 其次,由于代码需要不断维护,不断调整迭代,必要时进行重构,所以我们需要有一套规范来保证代码的质量,减少代码的维护成本。 最后,学习代码规范也便于以后就业,学会了普遍的代码规范,对以后的工作 **(准确是和同事的交流和协作)** 也是有帮助的。 + ## 这里包含了什么? + +首先是前后端(前端采用 `Vue.js`,后端采用 `SpringBoot` 或 `FastAPI`)的代码以及规范, +然后是数据库的设计规范,运维和产品的相关内容,最后是一些常用的工具的使用规范。 diff --git a/styleguide/part2.md b/styleguide/part2.md index 496590c..74fd5ca 100644 --- a/styleguide/part2.md +++ b/styleguide/part2.md @@ -8,9 +8,11 @@ 在项目中引入 `axios` 后,我们需要对其进行封装,以便于更好地处理请求和响应,比如添加请求拦截器,响应拦截器,统一处理错误等等。 -首先,这是我在项目中经常使用的 `axios` 封装,大家可以参考一下(这里用了`vant`的弹窗组件,可以根据自己的项目需求进行修改,比如`El-Message`什么的都可以哇): +首先,这是我在项目中经常使用的 `axios` 封装,大家可以参考一下(这里用了 `vant` +的弹窗组件,可以根据自己的项目需求进行修改,比如 `El-Message` 什么的都可以哇): ::: details 点我查看代码 + ```js import axios from "axios"; import {showDialog, showNotify} from "vant"; @@ -26,7 +28,7 @@ const ins = axios.create({ }); ins.interceptors.response.use( function (resp) { - // 如果响应头中有token,则存储到localStorage中,以便下次请求时携带 + // 如果响应头中有 token,则存储到 localStorage 中,以便下次请求时携带 console.log(resp.headers) if (resp.headers.Authorization) { console.log("存储token") @@ -60,10 +62,10 @@ ins.interceptors.response.use( ins.interceptors.request.use( function (config) { - // 在localStorage中获取token + // 在 localStorage 中获取 token const token = getToken(); if (token) { - // 如果存在token,则在请求头中携带token + // 如果存在 token,则在请求头中携带 token config.headers.Authorization = `Bearer ${token}`; } return config; @@ -78,11 +80,13 @@ ins.interceptors.request.use( export default ins; ``` + ::: 我们开始逐步讲解: 1. 首先我们引入了 `axios`,然后创建了一个实例 `ins`,并设置了一些默认值,比如 `baseURL`,`timeout`,`headers` 等等。 + ```js {2} const ins = axios.create({ baseURL: "/api/v2", // 设置基础URL @@ -92,33 +96,37 @@ const ins = axios.create({ }, }); ``` + 其中,`baseURL` 一定要确定好,这样在请求时就不用每次都写全路径了,这里补充一下,如果你正在本地开发,一定会设置代理服务器: ```js {11-19} export default defineConfig({ - plugins: [ - vue(), - VueDevTools(), - ], - resolve: { - alias: { - '@': fileURLToPath(new URL('./src', import.meta.url)) - } - }, - server: { - proxy: { - '/api': { - target: 'http://localhost:8000', - changeOrigin: true, - } + plugins: [ + vue(), + VueDevTools(), + ], + resolve: { + alias: { + '@': fileURLToPath(new URL('./src', import.meta.url)) + } }, - host: '0.0.0.0', - } + server: { + proxy: { + '/api': { + target: 'http://localhost:8000', + changeOrigin: true, + } + }, + host: '0.0.0.0', + } }) ``` + 2.接下来就是拦截器的设置,这里我们设置了两个拦截器,一个是请求拦截器,一个是响应拦截器。 -响应拦截器主要用来处理响应数据,比如判断响应头中是否有 `token`,如果有则存储到 `localStorage` 中,以便下次请求时携带;判断响应数据中的 `code` 字段,如果不为 0 则弹出提示框,当没有报错就直接返回数据。 +响应拦截器主要用来处理响应数据,比如判断响应头中是否有 `token`,如果有则存储到 `localStorage` +中,以便下次请求时携带;判断响应数据中的 `code` 字段,如果不为 0 则弹出提示框,当没有报错就直接返回数据。 + ```js {23} ins.interceptors.response.use( function (resp) { @@ -155,10 +163,11 @@ ins.interceptors.response.use( ``` ::: tip -注意下这里的写法哦,我们获取`resp.data.data`,这样直接就是我们需要的数据了,不用每次都去解构,这样也方便我们后续的处理。 +注意下这里的写法哦,我们获取 `resp.data.data`,这样直接就是我们需要的数据了,不用每次都去解构,这样也方便我们后续的处理。 ::: 请求拦截器主要用来处理请求数据,比如在请求头中添加 `token`,这样后端就可以根据 `token` 来判断用户的身份,然后返回相应的数据。 + ```js {7} ins.interceptors.request.use( function (config) { @@ -185,6 +194,8 @@ ins.interceptors.request.use( 首先,我们明确一下项目的目录结构,这里我推荐一种目录结构,大家可以参考一下: +::: details 点我查看目录结构 + ``` ├── public │ ├── favicon.ico @@ -202,7 +213,7 @@ ins.interceptors.request.use( │ ├── directives // 自定义指令 │ │ ├── index.js │ │ └── ... -│ ├── mocks // 模拟数据,如果使用Vite mock服务额可能会在根目录下 +│ ├── mock // 模拟数据,如果使用Vite mock服务额可能会在根目录下 │ │ ├── index.js │ │ └── ... │ ├── router // 路由相关 @@ -229,3 +240,373 @@ ins.interceptors.request.use( └── ... ``` +::: + +### /api + +这部分主要是存放接口相关的文件,比如 `user.js`,`article.js` +等等,这里一般会根据模块来划分,比如用户相关的接口就放在 `user.js` 中,文章相关的接口就放在 `article.js` 中。 +在分别写某个接口之前,首先建议要用 `axios` 封装好,这样在写接口时就可以直接调用封装好的 `axios` 实例了。 + +(这里可以参考上面的 `axios` 封装) + +对于每个接口尽量要写好注释,说明这个接口的作用,参数,返回值等等,这样方便后续的维护和修改。 +比如像以下这样:要让人一眼看出来这个接口是干什么的,传入什么参数,返回什么值。 + +::: tip +如果你使用的 `WebStorm` 或者 `VSCode`,可以直接在函数上方 `/**`,然后回车,就会自动生成注释模板,然后你只需要填写参数,返回值等等就可以了。 +::: + +```js +/** + * 获取成员签到信息(用于队长或者指导老师) + * @param {String} id 成员 id + * @returns {Promise >} 成员签到信息 + */ +export function getMemberSignInfo(id) { + return ins.get("/sign/detail", { + params: { + memberid: id, + } + }); +} +``` + +### /assets + +这个文件夹主要是存放静态资源,比如图片,字体等等,这里一般会根据类型来划分,比如图片就放在 `images` +文件夹中,字体就放在 `fonts` 文件夹中。 +注意,由于使用`Webpack`打包,我们在引入静态资源时,一定要使用 `@` 来引入,这样可以避免路径错误。 + +```vue +logo +``` + +当然也可以在 script setup 中使用 `import` 来引入(推荐这个吧,这个管理起来比较舒服): + +```js +import logo from '@/assets/images/logo.png'; +``` + +```vue +logo +``` + +### /components + +这个目录主要是存放公共组件,公共的组件代码一定要封装好,充分解耦合 +比如侧边栏,头部导航栏,底部导航栏等等,这些组件一定要封装好,方便多次使用。 + +这里最好要考虑好组件的复用性,可维护性,可扩展性等等,这样可以减少代码的冗余,提高开发效率。 +比如说通过 `props` 来传递数据,通过 `emit` 来触发事件,通过 `slots` 来插槽等等。 + +### /directives + +这个目录主要是存放自定义指令,比如 `v-permission`,`v-ellipsis` +等等,这些指令一般会根据功能来划分,比如权限相关的指令就放在 `permission.js` 中,文本截断相关的指令就放在 `ellipsis.js` 中。 +可能大家用的不多吧...除了我举的这两个例子,还可以 `v-focus`,`v-loading` 等等,这些指令可以方便我们在模板中使用,减少代码的冗余,提高开发效率。 + +### /mock + +这个目录主要是存放模拟数据,这个目录一般会根据模块来划分,比如用户相关的模拟数据就放在 `user.js` +中,文章相关的模拟数据就放在 `article.js` 中。 + +方便前端攻城狮——独!立!开!发!不用再苦求后端小伙伴啦(逃 + +具体的使用方法可以参考 `mockjs` 的官方文档,这里给一下具体的链接:[Mock.js](http://mockjs.com/),当然 +代码的编写也是要有规范的,并且要和接口文档保持一致,这样才能更好地测试和开发。 +这里举个栗子: + +```js +import Mock from "mockjs"; +import qs from "querystring"; + +Mock.mock(/^\/api\/message\/?(\?.+)?$/, "get", function (options) { + const query = qs.parse(options.url); + + return Mock.mock({ + code: 0, + msg: "", + data: { + total: 52, + [`rows|${query.limit || 10}`]: [ + { + id: "@guid", + nickname: "@cname", + content: "@cparagraph(1, 10)", + createDate: Date.now(), + "avatar|1": [ + "https://balabala/avatar6.jpg", + "https://balabala/avatar4.jpg", + "https://balabala/avatar8.jpg", + "https://balabala/avatar2.jpg", + ], + }, + ], + }, + }); +}); +``` + +还有,最后建议创建一个 `index.js` 文件,然后在这个文件中引入所有的模拟数据,这样方便管理,方便维护。 +在 `main.js` 中引入这个文件,这样就可以在开发时直接使用模拟数据了。 +并且开发完成直接注释这行代码就可以了:) + +### /router + +这个目录主要是存放路由相关的文件,比如 `index.js`,`guard.js` 等等 +要善于使用路由懒加载,还有路由守卫,这样可以提高页面的加载速度,保护页面的安全性。 +另外,根据路由的`meta`字段,可以实现权限控制,比如某个页面登录之后才能访问,这样可以提高系统的安全性。 +具体这样写就可以啦: + +```js {21} +import {createRouter, createWebHistory} from 'vue-router' +import Login from "@/views/Login.vue"; + +const router = createRouter({ + history: createWebHistory(import.meta.env.BASE_URL), + routes: [ + { + path: '/', + redirect: '/login', + }, + { + path: '/login', + name: '登录', + component: Login, + meta: {title: '登录'} + }, + { + path: '/myHome', + name: '我的', + component: () => import('../views/MyHome.vue'), + meta: {title: '我的', auth: true} + }, + { + path: '/index', + name: '首页', + component: () => import('../views/HomeView.vue'), + meta: {title: '打卡', auth: true} + }, + //...更多的路由 + ] +}); + +export default router; +``` + +当然阴间的微信`js-sdk`也可以切换路由的时候进行初始化,这样可以避免一些问题。 + +### /store + +这个目录主要是存放状态管理相关的文件,一般Vue3都会使用`Pinia`,这里就不多说了,如果使用`Vuex`, +这里一般会根据模块来划分,比如用户相关的状态就放在 `user.js` 中,文章相关的状态就放在 `article.js` 中。 +没什么好说的,就是状态管理,方便数据的共享,方便数据的修改,方便数据的监听等等。 +写的方法按照官方的例子就好,额用一个之前项目的例子吧: + +```js +/** + * @name UserStore + * @description 用户信息 + * 这里打开网页时就会通过携带wx相关信息向后端请求,获取信息并存储 + */ +import {defineStore} from 'pinia' + +export const useUserStore = defineStore('user', { + state: () => { + return { + name: '', + phone: '', + title: '', + belong: '', + avatar: '', + } + }, + actions: { + /** + * @name setUser + * @param data 传入的data应该是一个对象,包含name, phone, title + */ + setUser(data) { + this.name = data.name; + this.phone = data.phone; + this.title = data.title; + }, + /** + * @name setAvatar + * @param avatar 传入的avatar应该是一个字符串,表示头像的url + */ + setAvatar(avatar) { + this.avatar = avatar; + } + }, +}); + +``` + +在其他的地方使用的时候最好是先setup中定义一个对象,然后在模板中使用。 + +```js +import {useUserStore} from "@/store/user"; + +const user = useUserStore(); +``` + +### /styles + +样式文件,最好用`less`或者`sass`,这样可以方便我们使用变量,函数等等。 + +建议包含这些文件: + +- `golbal.less`:全局初始化 + +```less +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +a { + text-decoration: none; + color: inherit; +} + +ul, ol { + list-style: none; +} + +``` + +- `variables.less`:变量 + +```less +:root { + --primary: #1890ff; // 全局主色 + --bg: #ffffff; // 全局背景 + --font: #333333; // 全局字体颜色 + --warning: #faad14; // 警告 + --success: #52c41a; // 成功 + --error: #f5222d; // 错误 + --info: #1890ff; // 信息 + --disabled: #bfbfbf; // 失效 + --link: #1890ff; // 链接 + --hover: #001764; // hover +} + +@primary: var(--primary); +@bg: var(--bg); +@font: var(--font); +@warning: var(--warning); +@success: var(--success); +@error: var(--error); +@info: var(--info); +@disabled: var(--disabled); +@link: var(--link); +@hover: var(--hover); + +@media (prefers-color-scheme: dark) { + :root { + --primary: #718dff; // 全局主色 + --bg: #1d1e21; // 全局背景 + --font: #ffffff; // 全局字体颜色 + --warning: #faad14; // 警告 + --success: #a8ff7d; // 成功 + --error: #f5222d; // 错误 + --info: #80c1ff; // 信息 + --disabled: #4e4e4e; // 失效 + --link: #a0b5ff; // 链接 + --hover: #d5e8ff; // hover + } +} +``` + +接下来的 `less` 文件就可以引入这个文件,然后使用这些变量了。 + +- `mixin.less`:混合(公共样式) + +```less +// 这里就随便举个例子吧,就是公共样式 +@self-conter: { + display: flex; + justify-content: center; + align-items: center; +} +``` + +其他的文件按模块来划分,比如 `login.less`,`home.less` 等等, +另外less相互引入的时候,最好是使用`@import`,这样可以避免路径错误。 + +```less +@import "@/styles/mixin.less"; + +.manage-team-container { + .main-container; + overflow-y: auto; +} +``` + +### /utils + +工具类,不多说了,就是一些工具函数,比如时间格式化,深拷贝,浏览器判断等等,这些函数一定要封装好,方便多次使用。 + +### /views + +页面文件,这里一般会根据模块来划分,不是很复杂的页面就直接放在这个目录下,如果复杂或者存在子页面,可以再细分,创建目录。 + +## 2.3 - JavaScript 规范 + +:::warning +这个真的是重中之重,一定要遵守,不然后面维护起来会很痛苦的。 +对于一个团队的代码规范,以及个人的代码风格,都是举足轻重的。 +::: + +:::tip +强烈建议大家书写代码时启用 `eslint`,`prettier` 等工具(尤其是 `ESLint`) +::: + +### 命名规范 + +在 JavaScript 中,变量名,函数名,类名等等都是有规范的 +务必要遵守驼峰命名法(小驼峰),比如 `userName`,`getUserInfo`等等 +这样可以提高代码的可读性,减少歧义,方便维护。 + +### 缩进 + +我们希望在纯 JavaScript 文件中使用四个空格缩进(更清晰),而对于 Vue 和 React ,我们希望使用两个空格缩进(更紧凑)。 + +### 分号 + +在 JavaScript 中,分号是可选的,但是我们建议在每行语句的末尾加上分号,这样可以避免一些错误。 + +### 注释 + +注释真的非常重要,尤其是协作开发和代码的流传与维护(? +在 JavaScript 中,我们建议使用单行注释 `//`,多行注释 `/* */`,文档注释 `/** */`等等 +在写注释时,一定要写清楚这段代码的作用,这样方便后续的维护和修改。 +强烈建议书写文档注释!!并且署名,这样方便他人查看,如果有不清楚的地方,可以直接找到你。 + +就像以下这样: + +```js +/** + * @name Permission + * @description 通过路由守卫实现登录验证 + * @author Grtsinry43 + * @date 2024-07-24 + * 本段代码灵感来源于vue-element-admin,当用户已登录时,会自动获取用户信息, + * 当用户访问需要登录的页面时,会自动跳转到登录页面,鉴权后再跳转回原页面 + */ +``` + +### 函数风格 + +这里以 Vue 为例,比如一些业务处理,命名为 ...Handle, +比如submitHandle,clickHandle等等,这样可以方便我们区分这个函数是用来处理什么的。 + +参数尽量让人一看就知道要传什么,比如 `durationSeconds`好于 `duration`,`isShow`好于 `show`等等。 +当然即使这样,也要写好注释,方便他人查看。 + +## 2.4 - 常用组件库的使用规范 + +[//]: # (TODO: 待补充)