@allkit/best-practice 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json ADDED
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "@allkit/best-practice",
3
+ "version": "0.0.1",
4
+ "description": "this is a best practice skills package",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "keywords": [],
9
+ "author": "SPig",
10
+ "license": "MIT"
11
+ }
@@ -0,0 +1,62 @@
1
+ ---
2
+ name: best-practice
3
+ description: 提供项目最佳实践指南,包括项目搭建、模块规范、代码规范、Vue 相关规范等,确保项目开发质量和一致性。
4
+ license: MIT
5
+ metadata:
6
+ author: allkit
7
+ version: 1.0
8
+ compatibility:
9
+ - Vue 3
10
+ - TypeScript 5.0+
11
+ - Vite 5.0+
12
+ - pnpm
13
+ - scss
14
+ ---
15
+
16
+ 本技能是 Vue 3 + TypeScript+ tsx+ scss+ pnpm 项目的开发规范和最佳实践指南。它提供了项目搭建、模块规范、代码规范、Vue 相关规范等方面的指导,确保项目开发质量和一致性。
17
+
18
+ ## 何时应用
19
+
20
+ 在 Vue 3 + TypeScript 项目开发过程中始终应用此技能。
21
+
22
+ - 在创建新项目或新模块时,参考`项目搭建`和`模块规范`
23
+ - 在编写代码时,遵循`代码规范`和`命名规范`
24
+ - 创建新组件时,遵循`组件规范`和 `Hooks 规范`
25
+ - 在使用 JSX jsx/tsx 语法时,遵循`JSX/tsx 规范`
26
+ - 在配置开发环境时,参考 ESLint、TypeScript、Vite 配置
27
+
28
+ ## 技能列表
29
+
30
+ ### 代码规范
31
+
32
+ | 规范 | 描述 | 调用时机 |
33
+ | ----------------------------------------- | --------------------------------------------- | -------------- |
34
+ | [变量命名](references/variable-naming.md) | 定义变量的命名规则,包括数组、对象、布尔值等 | 定义变量时遵循 |
35
+ | [函数命名](references/function-naming.md) | 定义函数的命名规则,包括 API、事件、Hook 函数 | 定义函数时遵循 |
36
+ | [枚举命名](references/enum-naming.md) | 定义枚举的命名规则,包括枚举名和属性命名 | 定义枚举时遵循 |
37
+ | [CSS 规范](references/css-spec.md) | 定义 CSS 开发规范,包括 BEM、SCSS、Tailwind | 编写样式时遵循 |
38
+ | [资源规范](references/assets-spec.md) | 定义静态资源的使用和命名规范 | 引入资源时遵循 |
39
+
40
+ ### 模块规范
41
+
42
+ | 规范 | 描述 | 调用时机 |
43
+ | --------------------------------------------- | --------------------------- | -------------------------------------------- |
44
+ | [模块目录结构](references/module-spec.md) | 定义功能模块,目录结构的标准 | 创建新模块,新的vue,,新的组件时新的文件时参考 |
45
+ | [文件夹命名规范](references/folder-naming.md) | 定义文件夹的命名规则 | 创建新文件夹时遵循 |
46
+ | [文件命名规范](references/file-naming.md) | 定义各类文件的命名规则 | 创建新文件时遵循 |
47
+
48
+ ## Vue 相关规范
49
+
50
+ | 规范 | 描述 | 调用时机 |
51
+ | ----------------------------------------- | ----------------------------------------------- | ------------------ |
52
+ | [组件规范](references/component-spec.md) | 定义 Vue 组件的开发规范,包括简单组件和复杂组件 | 开发组件时遵循 |
53
+ | [功能模块规范](references/module-spec.md) | 定义功能模块的开发规范,包括入口页面和职责划分 | 开发功能模块时遵循 |
54
+ | [Hooks 规范](references/hooks-spec.md) | 定义 Vue Hooks 的开发规范,包括命名和结构 | 开发 Hooks 时遵循 |
55
+ | [JSX/tsx 规范](references/jsx-spec.md) | 定义 JSX/tsx 语法规范,包括语法对比及注意事项 | 使用 JSX/tsx 时遵循 |
56
+
57
+ ### @allkit 库
58
+
59
+ | 库 | 描述 | 调用时机 |
60
+ | ------------------------------------------------ | ------------------------------------------ | ----------------------- |
61
+ | [@allkit/http-client](references/http-client.md) | HTTP 请求客户端,提供统一的请求封装 | 发起 API 请求时自动使用 |
62
+ | [@allkit/shared](references/shared-utils.md) | 通用工具函数库,提供类型判断、格式化等功能 | 需要工具函数时优先使用 |
@@ -0,0 +1,83 @@
1
+ ---
2
+ title: 资源规范
3
+ description: 新增修改(图片,视频等)资源文件的目录结构、命名规范及引用方式
4
+ category: 规范文档
5
+ ---
6
+
7
+ # 资源规范
8
+
9
+ ## 核心原则
10
+
11
+ 1. **模块化**:资源文件应尽可能存放在使用它的模块内部 `assets` 目录中。
12
+ 2. **引用方式**:必须使用 `import` 或 `new URL()` 引入资源,禁止使用相对路径字符串。
13
+ 3. **命名规范**:使用下划线 `_` 分隔,包含类型前缀。
14
+
15
+ ## 目录结构
16
+
17
+ 每个业务模块都应有独立的 `assets` 目录。
18
+
19
+ ```
20
+ vehicle-picker/
21
+ ├── assets/ # 模块私有资源
22
+ │ ├── img_vehicle_box.png
23
+ │ └── ic_close.svg
24
+ ├── index.vue
25
+ └── hooks/
26
+ ```
27
+
28
+ 全局资源存放在 `src/assets`。
29
+
30
+ ## 命名规范
31
+
32
+ - **字符限制**:仅限小写字母、数字、下划线 `_`。
33
+ - **格式**:`前缀_功能_描述_状态.扩展名`
34
+
35
+ ### 前缀对照表
36
+
37
+ | 前缀 | 类型 | 说明 | 示例 |
38
+ | ------------- | ---- | ----------- | ------------------------ |
39
+ | `ic` / `icon` | 图标 | 小图标、SVG | `ic_search.svg` |
40
+ | `bg` | 背景 | 大图背景 | `bg_login.png` |
41
+ | `img` | 图片 | 展示类图片 | `img_avatar_default.png` |
42
+ | `btn` | 按钮 | 按钮背景图 | `btn_submit_hover.png` |
43
+
44
+ ### 示例
45
+
46
+ - ❌ `box-truck.png` (使用了中划线)
47
+ - ✅ `img_vehicle_box.png` (符合规范)
48
+ - ✅ `bg_home_banner.jpg`
49
+ - ✅ `ic_nav_home_active.svg`
50
+
51
+ ## 引用规范
52
+
53
+ ### Vue 组件 / TS 文件
54
+
55
+ 必须使用 `import` 导入资源,以确保构建工具能正确处理路径和 hash。
56
+
57
+ ```ts
58
+ // 推荐
59
+ import imgBox from './assets/img_vehicle_box.png'
60
+
61
+ const list = [{ image: imgBox }]
62
+ ```
63
+
64
+ 或者使用 `new URL` (Vite 专用):
65
+
66
+ ```ts
67
+ const imgUrl = new URL('./assets/img_vehicle_box.png', import.meta.url).href
68
+ ```
69
+
70
+ ### CSS / SCSS
71
+
72
+ 使用相对路径引用。
73
+
74
+ ```scss
75
+ .banner {
76
+ background-image: url('./assets/bg_home_banner.png');
77
+ }
78
+ ```
79
+
80
+ ## 注意事项
81
+
82
+ - **小文件内联**:Vite 默认会将 < 4kb 的资源内联为 base64。
83
+ - **大文件处理**:对于较大的媒体文件,考虑使用 CDN 链接。
@@ -0,0 +1,88 @@
1
+ ---
2
+ title: 组件规范
3
+ description: Vue3 组件的开发规范、目录结构及 Props/Emits 定义,使用defineComponent定义组件,lang="tsx"语法
4
+ category: 规范文档
5
+ ---
6
+
7
+ # 组件规范
8
+
9
+ ## 使用场景
10
+ 定义 Vue 组件的开发规范,确保组件结构一致、可维护。
11
+
12
+ ## 基础使用
13
+
14
+ ### 组件组织
15
+ | 类型 | 目录 | 说明 |
16
+ |------|------|------|
17
+ | 全局组件 | `src/components/` | 可在任意位置使用 |
18
+ | 页面组件 | `src/views/<page>/components/` | 仅在当前页面使用 |
19
+
20
+ > **注意**: 除非明确需要,否则不要创建全局组件。如果需要创建全局组件,请先询问用户确认。
21
+
22
+
23
+
24
+ ### 组件
25
+ 需要导出类型、逻辑复杂的组件,使用文件夹形式。
26
+
27
+ ```
28
+ components/
29
+ ├── Demo
30
+ │ ├── index.ts # 导出组件和类型
31
+ │ ├── types.ts # 类型定义
32
+ │ ├── Demo.vue # 组件实现
33
+ │ └── hooks/ # 组件 Hooks (可选,询问用户是否需要创建)
34
+ │ └── useXXX.tsx
35
+ ```
36
+
37
+ ## 组件结构
38
+
39
+ ### 单文件组件
40
+ ```vue
41
+ <script lang="tsx">
42
+
43
+ export default defineComponent({
44
+ name: 'MyComponent',
45
+ props: Props,
46
+ setup(props, { emit }) {
47
+ const onClick = (event: MouseEvent) => {
48
+ emit('click', event)
49
+ }
50
+ return {
51
+ render() {
52
+ return (
53
+ <div class='my-component'>
54
+ <button onClick={onClick} disabled={props.disabled}>
55
+ {props.title}
56
+ </button>
57
+ </div>
58
+ )
59
+ },
60
+ }
61
+ },
62
+ })
63
+ </script>
64
+
65
+ <style scoped lang="scss">
66
+ .my-component {
67
+ padding: 16px;
68
+ }
69
+ </style>
70
+ ```
71
+
72
+
73
+
74
+
75
+ ## Props.ts 定义
76
+
77
+ ```ts
78
+ export let Props = {
79
+ title: String,
80
+ disabled: {
81
+ type: Boolean,
82
+ default: false,
83
+ },
84
+ }
85
+ ```
86
+
87
+
88
+
@@ -0,0 +1,83 @@
1
+ ---
2
+ title: CSS 规范
3
+ description: BEM + SCSS + Tailwind CSS 组合方案及命名规范
4
+ category: 规范文档
5
+ ---
6
+
7
+ # CSS 规范
8
+
9
+ ## 核心原则
10
+
11
+ 1. **组合使用**:项目采用 `BEM` + `SCSS` + `Tailwind CSS` 的组合方案,不使用元素选择器。
12
+ 2. **命名空间**:CSS 类名使用中划线(kebab-case)命名。
13
+ 3. **样式隔离**:组件样式**必须**使用 `scoped` 以防止污染。
14
+
15
+ ## 命名规范
16
+
17
+ - CSS 类名统一使用中划线分隔,如 `.my-component`。
18
+ - 特殊修饰符可使用双中划线 `--`,如 `.btn--primary`。
19
+
20
+ ## BEM 标准
21
+
22
+ BEM (Block, Element, Modifier) 是项目主要采用的 CSS 模块化命名规范。
23
+
24
+ ### 结构
25
+
26
+ | 概念 | 描述 | 示例 |
27
+ | --------------------- | ---------------- | ---------------------------------------------- |
28
+ | **Block** (块) | 独立的组件或模块 | `.warehouse`, `.vehicle-picker` |
29
+ | **Element** (元素) | 块的组成部分 | `.warehouse__header`, `.vehicle-picker__title` |
30
+ | **Modifier** (修饰符) | 状态或外观变体 | `.warehouse--active`, `.vehicle-picker--small` |
31
+
32
+ ### 最佳实践
33
+
34
+ 1. **Block**:通常对应组件名。
35
+ ```scss
36
+ .vehicle-picker { ... }
37
+ ```
38
+ 2. **Element**:使用双下划线 `__` 连接。
39
+ ```scss
40
+ .vehicle-picker__header { ... }
41
+ ```
42
+ 3. **Modifier**:使用双中划线 `--` 连接。
43
+ ```scss
44
+ .vehicle-picker__card--selected { ... }
45
+ ```
46
+
47
+
48
+
49
+ ## Tailwind CSS (Atomic CSS)
50
+
51
+ Tailwind CSS 用于快速实现原子样式,特别适合处理简单的布局、间距和工具类样式,不超过4个属性。
52
+
53
+ ### 使用场景
54
+
55
+ - **布局与间距**:`flex`, `grid`, `m-4`, `p-2` 等。
56
+ - **简单的工具样式**:`text-center`, `cursor-pointer`, `w-full`。
57
+ - **避免过度使用**:对于复杂的组件业务样式,建议优先使用 BEM + SCSS,保持 HTML 的整洁性。
58
+
59
+ ### 常用语法
60
+
61
+ - **宽度/高度**:`w-[100px]`, `h-full`, `w-1/2`
62
+ - **边距**:`m-0` (margin: 0), `px-4` (padding-left/right: 1rem)
63
+ - **Flex 布局**:`flex`, `flex-col`, `items-center`, `justify-between`
64
+ - **颜色**:`bg-white`, `text-red-500`, `border-gray-200`
65
+
66
+ ### 示例
67
+
68
+ ```html
69
+ <!-- 混合使用 BEM 和 Tailwind -->
70
+ <div class="vehicle-picker flex flex-col h-full">
71
+ <!-- 复杂的使用 BEM -->
72
+ <div class="vehicle-picker__header flex justify-between items-center p-4">
73
+ <!-- 简单的使用 Tailwind -->
74
+ <h2 class="text-xl font-bold">标题</h2>
75
+ </div>
76
+ </div>
77
+ ```
78
+
79
+ ## 优先级
80
+
81
+ 1. **组件结构样式**:优先使用 BEM + SCSS,不使用元素选择器。
82
+ 2. **简单的样式**:4个css属性以内,直接使用 Tailwind CSS。
83
+ 3. **动态样式**:优先使用css的var变量,然后使用 Vue 的 `:style` 或 `:class` 绑定。
@@ -0,0 +1,99 @@
1
+ ---
2
+ title: 枚举命名
3
+ description: 创建枚举,修改枚举名,定义项目中枚举的命名规则。
4
+ category: 命名规范
5
+ ---
6
+
7
+ # 枚举命名
8
+
9
+ ## 使用场景
10
+ 定义项目中枚举的命名规则,确保枚举命名清晰、一致。
11
+
12
+ ## 基础使用
13
+
14
+ ### 命名规则
15
+ - 枚举名使用 `Enum` 前缀(推荐)或后缀
16
+ - 枚举名使用 `大驼峰` 命名法
17
+ - 枚举属性使用 `大写 + 下划线`
18
+
19
+ ## 使用示例
20
+
21
+ ### enum 关键字
22
+ ```ts
23
+ enum EnumYesOrNo {
24
+ YES = 1,
25
+ NO = 0,
26
+ }
27
+ ```
28
+
29
+ ### as const 对象
30
+ ```ts
31
+ const EnumStatus = {
32
+ SUCCESS: 1,
33
+ ERROR: 2,
34
+ } as const
35
+
36
+ ```
37
+
38
+
39
+ ```ts
40
+ // 状态标签映射
41
+ export const USER_STATUS_LABELS = {
42
+ [EnumUserStatus.ACTIVE]: '启用',
43
+ [EnumUserStatus.INACTIVE]: '禁用',
44
+ } as const
45
+ ```
46
+
47
+ ### 使用枚举
48
+ ```ts
49
+ import { EnumUserStatus, USER_STATUS_LABELS } from './constants'
50
+
51
+ // 判断状态
52
+ if (user.status === EnumUserStatus.ACTIVE) {
53
+ // 用户已启用
54
+ }
55
+
56
+ // 获取标签
57
+ const label = USER_STATUS_LABELS[user.status]
58
+ ```
59
+
60
+ ## 命名对照表
61
+
62
+ | 类型 | 命名规范 | 示例 |
63
+ |------|----------|------|
64
+ | 枚举名 | `Enum` + 大驼峰 | `EnumUserStatus` |
65
+ | 枚举属性 | 大写 + 下划线 | `ACTIVE`, `IN_PROGRESS` |
66
+ | 标签映射 | 枚举名 + `Map` | `StatusMap`, `UserStatusMap` |
67
+ | 枚举策略 | 枚举名 + `Strategy` | `StatusStrategy`, `UserStatusStrategy` |
68
+
69
+
70
+ ## 最佳实践
71
+
72
+ ```ts
73
+ // 推荐:使用 as const 保持类型安全
74
+ export const EnumStatus = {
75
+ SUCCESS: 1,
76
+ ERROR: 0,
77
+ } as const
78
+
79
+ // 推荐:提供标签映射
80
+ export const StatusLabels = {
81
+ [EnumStatus.SUCCESS]: '成功',
82
+ [EnumStatus.ERROR]: '失败',
83
+ }
84
+
85
+ // 推荐:提供枚举策略
86
+ export const StatusStrategy = {
87
+ [EnumStatus.SUCCESS]: {
88
+ label: StatusLabels[EnumStatus.SUCCESS],
89
+ render: (status: StatusType) => StatusLabels[status],
90
+ },
91
+ [EnumStatus.ERROR]: {
92
+ label: StatusLabels[EnumStatus.ERROR],
93
+ render: (status: StatusType) => StatusLabels[status],
94
+ },
95
+ }
96
+
97
+ // 推荐:提供类型导出
98
+ export type StatusType = typeof EnumStatus[keyof typeof EnumStatus]
99
+ ```
@@ -0,0 +1,44 @@
1
+ ---
2
+ title: 文件命名规范
3
+ description: 创建文件,修改文件名,定义项目中各类文件的命名规则。
4
+ category: 命名规范
5
+ ---
6
+
7
+ # 文件命名规范
8
+
9
+ ## 使用场景
10
+
11
+ 创建文件,修改文件名,定义项目中各类文件的命名规则,确保文件命名一致、可识别。
12
+
13
+ ## 基础使用
14
+
15
+ ### 文件命名规则
16
+
17
+ | 文件类型 | 命名规范 | 示例 |
18
+ | --------- | ----------------- | ------------------ |
19
+ | 入口页面 | `index.vue` | - |
20
+ | API 文件 | `api.ts` | api.ts |
21
+ | 路由文件 | `router.ts` | - |
22
+ | 类型文件 | `types.ts` | - |
23
+ | 常量文件 | `constants.ts` | - |
24
+ | 字典文件 | `dict.ts` | - |
25
+ | 工具文件 | `util.ts` | - |
26
+ | Hook 文件 | `use*.tsx` | `useXX.tsx` |
27
+ | 组件文件 | `PascalCase.vue` | `DemoTest.vue` |
28
+ | 样式文件 | `kebab-case.scss` | `bem-xxx.scss` |
29
+
30
+ ### 组件文件命名
31
+
32
+ | 类型 | 命名规范 | 示例 |
33
+ | ---- | ----------------------------------- | ------------------------------ |
34
+ | 组件 | 文件夹 `PascalCase.vue`+ `index.ts` | `Button.vue`+`button/index.ts` |
35
+
36
+ ## 示例
37
+
38
+ ## 组件
39
+ 参考[组件规范](component-spec.md)
40
+
41
+
42
+ ### Hook 文件
43
+
44
+ 参考[Hook规范](hook-spec.md)
@@ -0,0 +1,42 @@
1
+ ---
2
+ title: 文件夹命名规范
3
+ description: (新增/创建)文件夹时,或者修改文件夹名时,需要遵守的命名规范
4
+ category: 命名规范
5
+ ---
6
+
7
+ # 文件夹命名规范
8
+
9
+ ## 使用场景
10
+ 定义项目中文件夹,目录的命名规则,确保目录结构清晰、一致。
11
+
12
+ ## 基础使用
13
+
14
+ ### 命名规则
15
+ - 使用 `小写字母`
16
+ - 多个单词以 `中划线` 分隔,不能用驼峰,文件夹一定不要驼峰
17
+ - 不超过 `三个单词`
18
+ - 不超过 `20个字符`
19
+ - 避免使用 `拼音、数字、特殊字符`
20
+
21
+ ### 示例对比
22
+
23
+ | 推荐 | 不推荐 | 说明 |
24
+ |------|--------|------|
25
+ | `user-mgr` ,`sys-mgr`| `userMgr`,`sysMgr(不使用驼峰)` | 使用中划线分隔 |
26
+ | `order-list` | `order_list` | 不使用下划线 |
27
+ | `product-detail` | `productDetail2020` | 不使用数字 |
28
+ | `sys-config` | `xitongpeizhi` | 不使用拼音 |
29
+
30
+ ## 特殊目录命名
31
+
32
+ | 目录名 | 说明 |
33
+ |--------|------|
34
+ | `hooks` | Hook 函数目录 |
35
+ | `components` | 组件目录 |
36
+ | `assets` | 静态资源目录 |
37
+ | `utils` | 工具函数目录 |
38
+ | `types` | 类型定义目录 |
39
+ | `api` | API 接口目录 |
40
+ | `styles` | 样式文件目录 |
41
+ | `constants` | 常量定义目录 |
42
+
@@ -0,0 +1,101 @@
1
+ ---
2
+ title: function函数命名
3
+ description: 新增/创建函数时,或者修改函数名时,需要遵守的命名规范
4
+ category: 命名规范
5
+ ---
6
+
7
+ # 函数命名
8
+
9
+ ## 使用场景
10
+
11
+ 定义项目中函数的命名规则,确保函数命名清晰、可理解。
12
+
13
+ ## 基础使用
14
+
15
+ ### 命名规则
16
+
17
+ - 使用 `小驼峰` 命名法
18
+ - 采用 `动作 + 特性` 结构
19
+ - 动词在前,名词在后
20
+
21
+ ### 基本示例
22
+
23
+ ```ts
24
+ // 设值、取值
25
+ const setToken = (token: string) => {}
26
+ const getToken = () => {}
27
+
28
+ ```
29
+
30
+ ## 函数类型命名
31
+
32
+ ### API 函数
33
+
34
+ 使用 `api` 前缀
35
+
36
+ ```ts
37
+ const apiGetUserInfo = (id: string) => {
38
+ return Http.get({ url: `/user/${id}` })
39
+ }
40
+
41
+ const apiCreateUser = (data: UserFormData) => {
42
+ return Http.post({ url: '/user', data })
43
+ }
44
+ ```
45
+
46
+ ### 事件函数
47
+
48
+ 使用 `on` 或 `handle` 前缀
49
+
50
+
51
+ ```ts
52
+ // 点击事件
53
+ const onClickEditBtn = (id: string) => {}
54
+ // 键盘事件
55
+ const onKeyUpEnter = () => {}
56
+ // 通用处理
57
+ const handleSearch = () => {}
58
+ ```
59
+
60
+ ### Hook 函数
61
+
62
+ 使用 `use` 前缀
63
+
64
+ ```tsx
65
+ // 解构使用
66
+ const { render } = useLoading()
67
+ ```
68
+
69
+ ### 渲染函数
70
+
71
+ 使用 `render` 前缀
72
+
73
+ ```tsx
74
+ const renderLoadingIcon = () => {
75
+ return <Loading size={16} />
76
+ }
77
+
78
+ const renderEmpty = () => {
79
+ return <Empty description='暂无数据' />
80
+ }
81
+ ```
82
+
83
+ ## 动词对照表
84
+
85
+ | 动词 | 含义 | 示例 |
86
+ | ------------------- | ------ | ------------------------------- |
87
+ | `get` | 获取 | `getToken`, `getUserInfo` |
88
+ | `set` | 设置 | `setToken`, `setConfig` |
89
+ | `add` | 新增 | `addUser`, `addItem` |
90
+ | `delete` / `remove` | 删除 | `deleteUser`, `removeItem` |
91
+ | `update` | 更新 | `updateUser`, `updateConfig` |
92
+ | `load` | 加载 | `loadData`, `loadList` |
93
+ | `save` | 保存 | `saveData`, `saveForm` |
94
+ | `submit` | 提交 | `submitForm`, `submitOrder` |
95
+ | `show` | 显示 | `showDialog`, `showLoading` |
96
+ | `hide` | 隐藏 | `hideDialog`, `hideLoading` |
97
+ | `toggle` | 切换 | `toggleMenu`, `toggleExpand` |
98
+ | `validate` | 校验 | `validateForm`, `validateInput` |
99
+ | `reset` | 重置 | `resetForm`, `resetState` |
100
+ | `init` | 初始化 | `initData`, `initConfig` |
101
+ | `fetch` | 请求 | `fetchList`, `fetchDetail` |
@@ -0,0 +1,131 @@
1
+ ---
2
+ title:Vue3 定义 Hook
3
+ description: 新增/创建Hook时,或者修改Hook名时,需要遵守的命名规范,
4
+ category: 规范文档
5
+ ---
6
+
7
+ 这里的hook,不是Composition API,是vue组件的替代版,免去`emit`,`props`,`attrs`传值问题
8
+
9
+ ## 禁止
10
+ - 不要创建`ts`结尾的,Composition API文件,只能创建`tsx`结尾的文件,返回对象包含`render`函数
11
+ - 不要创建`ts`结尾的,Composition API文件,也不要复用其他模块的Hook
12
+
13
+
14
+ ## hook规范要求
15
+ | 类型 | 文件后缀 | 核心用途 | 返回值特征 | 适用场景 |
16
+ | :------------------ | :------- | :--------------- | :-------------------------- | :---------------------------------- |
17
+ | **Hook** | `.tsx` | **业务组件拆分** | 包含 `render` 函数 | 模块内的业务逻辑 + 视图渲染 |
18
+
19
+ ---
20
+
21
+ ## 一、Hook (.tsx)
22
+
23
+ ### 1. 定义与用途
24
+
25
+ Hook 是功能模块内的业务单元。它不仅仅是逻辑的抽离,更是**视图组件的拆分**。
26
+
27
+ - **内聚性**:将相关的业务逻辑和 `JSX` 视图封装在同一个文件中。
28
+ - **模块化**:用于拆分复杂的 `index.vue` 入口文件,保持代码清晰。
29
+
30
+ ### 2. 规范要求
31
+
32
+ - **文件后缀**:必须为 `.tsx`。
33
+ - **返回值**:必须返回一个对象,且**必须包含 `render` 函数**,函数逻辑在 hook 内部实现,外部只调用 `render` 函数。
34
+ - **状态管理**:使用 `useCtxState` 获取模块级共享状态。
35
+ - **存放位置**:位于模块的 `hooks/` 目录下,vue中统一调用`hooks/index.ts`。
36
+
37
+ ### 3. 代码示例
38
+
39
+ #### Hook 实现 (`hooks/useList.tsx`)
40
+
41
+ ```tsx
42
+ import { ref } from 'vue'
43
+ import { useCtxState } from '@allkit/use'
44
+ import type { User, UserListState } from '../../types'
45
+
46
+ export const useList = (openDialog: Function) => {
47
+ // 1. 获取共享状态
48
+ const [state,setState] = useCtxState<UserListState>()
49
+
50
+ // 定义仅当前hook内部使用的状态
51
+ let currState =reactive({
52
+ list:[]
53
+ })
54
+
55
+ // 2. 定义局部逻辑
56
+ const cols = [
57
+ { prop: 'id', label: '序号', width: 55 },
58
+ { prop: 'account', label: '账号' },
59
+ ]
60
+
61
+ const onClickAdd = () => openDialog(true)
62
+ const onClickEdit = (row: User) => openDialog(false, row)
63
+
64
+ // 3. 返回包含 render 的对象
65
+ return {
66
+ render: () => (
67
+ <>
68
+ <div class='toolbar'>
69
+ <ElButton type='primary' onClick={onClickAdd}>
70
+ 新增
71
+ </ElButton>
72
+ </div>
73
+ <ElTable data={state.userList}>
74
+ {cols.value.map((col) => (
75
+ <ElTableColumn key={col.prop} {...col} />
76
+ ))}
77
+ </ElTable>
78
+ </>
79
+ ),
80
+ }
81
+ }
82
+ ```
83
+
84
+ #### 入口调用 (`index.vue`)
85
+
86
+ ```tsx
87
+ import { defineComponent } from 'vue'
88
+ import { defineCtxState } from '@allkit/use'
89
+ /* 引入所有hooks */
90
+ import { useList, useSearchForm } from './hooks'
91
+
92
+ export default defineComponent({
93
+ setup() {
94
+ // 1. 初始化状态
95
+ let [state]= defineCtxState<UserListState>({
96
+ /* ... */
97
+ })
98
+
99
+ // 2. 组合 Hooks
100
+ const { render: renderSearch } = useSearchForm()
101
+ const { render: renderList } = useList()
102
+
103
+ // 3. 布局渲染
104
+ return () => (
105
+ <div class='user-list'>
106
+ {renderSearch()}
107
+ {renderList()}
108
+ </div>
109
+ )
110
+ },
111
+ })
112
+ ```
113
+
114
+ ---
115
+
116
+ ## 二、Composition API (.ts)
117
+
118
+ ### 1. 定义与用途
119
+
120
+ Composition API 是纯粹的逻辑复用单元。它不包含任何 JSX 或视图代码。
121
+
122
+
123
+ 比如:
124
+ - `useWindowSize`
125
+ - `useScroll`
126
+ - `useCssVar`
127
+
128
+ 公共库会定义好,我们只需要在业务模块中引入即可
129
+ **注意**不需要去新创建ts结尾的hook。
130
+ **注意**不需要去新创建ts结尾的hook。
131
+
@@ -0,0 +1,158 @@
1
+ ---
2
+ title: JSX/tsx 规范
3
+ description: Vue3 项目中 JSX/tsx 语法 的使用规范、语法对比及最佳实践
4
+ category: 规范文档
5
+ ---
6
+
7
+ # JSX/tsx 规范
8
+
9
+ ## 使用场景
10
+ 在 Vue3 项目中使用 JSX 语法,配合 Composition API 和 Hooks 实现更灵活的组件开发。
11
+
12
+ ## 参考
13
+ - [Vue3 jsx 官方文档](https://cn.vuejs.org/guide/extras/render-function.html#jsx-tsx)
14
+
15
+ ## 基础语法对比
16
+
17
+ ### 1. 普通内容
18
+ ```jsx
19
+ // JSX 写法
20
+ setup() {
21
+ return () => <p type="email">hello</p>
22
+ }
23
+
24
+ // Template 写法
25
+ <template>
26
+ <p type="email">hello</p>
27
+ </template>
28
+ ```
29
+
30
+ ### 2. 动态变量
31
+ ```jsx
32
+ // JSX 写法
33
+ setup() {
34
+ let age = 1
35
+ return () => <div age={age}>{age}</div>
36
+ }
37
+
38
+ ```
39
+
40
+ ### 3. 函数事件
41
+ ```jsx
42
+ // JSX 写法
43
+ setup() {
44
+ const age = ref(0)
45
+ const inc = () => age.value++
46
+ return () => <div onClick={inc}>{age.value}</div>
47
+ }
48
+
49
+ ```
50
+
51
+ ### 4. Ref 绑定
52
+ ```jsx
53
+ // JSX 写法
54
+ setup() {
55
+ const divRef = ref(null)
56
+ return () => (
57
+ <div ref={divRef}>
58
+ <span>xxx</span>
59
+ </div>
60
+ )
61
+ }
62
+ ```
63
+
64
+ ### 5. v-model 语法
65
+ ```jsx
66
+ // JSX 写法
67
+ setup() {
68
+ const age = ref(0)
69
+ const gender = ref('')
70
+ return () => (
71
+ <>
72
+ <tz-input v-model={age} />
73
+ <tz-input v-model:foo={age} />
74
+ <tz-input v-model:bar={gender} />
75
+ </>
76
+ )
77
+ }
78
+
79
+ ```
80
+
81
+ ### 6. v-slots 语法
82
+ 对比`jsx`与 `template` 语法
83
+ ```jsx
84
+ // JSX 写法
85
+ const App = {
86
+ setup() {
87
+ return () => (
88
+ <A>
89
+ {{
90
+ default: () => <div>A</div>,
91
+ bar: () => <span>B</span>
92
+ }}
93
+ </A>
94
+ )
95
+ }
96
+ }
97
+
98
+ // Template 写法
99
+ <template>
100
+ <A>
101
+ <template v-slot:bar>
102
+ <span>B</span>
103
+ </template>
104
+ </A>
105
+ </template>
106
+ ```
107
+
108
+ ### 7. v-for 语法
109
+ map循环需要添加`key`属性,否则会报错。
110
+ ```jsx
111
+ // JSX 写法
112
+ setup() {
113
+ const arr = ref([{ label: '1' }, { label: '2' }, { label: '3' }])
114
+ return () => (
115
+ <>
116
+ {arr.value.map(item => <span key={item.label}>{item.label}</span>)}
117
+ </>
118
+ )
119
+ }
120
+
121
+
122
+ ```
123
+
124
+ ### 8. v-if 语法
125
+ ```jsx
126
+ // JSX 写法
127
+ setup() {
128
+ const show = ref(false)
129
+ return () => (
130
+ <>
131
+ {show && <span>test vif</span>}
132
+ {!show && <span>test velse</span>}
133
+ </>
134
+ )
135
+ }
136
+
137
+ ```
138
+
139
+ ### 9. v-show 语法
140
+ ```jsx
141
+ // JSX 写法
142
+ setup() {
143
+ const show = ref(false)
144
+ return () => (
145
+ <>
146
+ <span v-show={show.value}>test vshow</span>
147
+ </>
148
+ )
149
+ }
150
+
151
+ ```
152
+
153
+ ## 注意事项
154
+
155
+ 1. **ref 变量处理**:JSX 不会自动处理 `.value`,需要手动添加,所有少用ref定义变量
156
+ 2. **事件修饰符**:使用 `withModifiers` 实现 `.self`、`.stop` 等修饰符
157
+ 3. **插槽使用**:推荐使用对象形式传递插槽内容
158
+ 4. **多 v-model**:使用 `v-model:xx` 语法代替二维数组形式
@@ -0,0 +1,173 @@
1
+ ---
2
+ title: 功能模块规范
3
+ description: 项目中新增功能模块的目录结构、开发原则及最佳实践
4
+ category: 规范文档
5
+ ---
6
+
7
+ # 功能模块规范
8
+
9
+ ## 【核心开发原则 - 必读】
10
+
11
+ 在开发新模块时,**必须**严格遵守以下原则:
12
+
13
+ 1. **文件结构**:
14
+ - 入口文件必须是 `index.vue`,且**必须**使用 `lang="tsx"`,**禁止**使用 `<template>`。
15
+ - 所有业务逻辑和子组件必须拆分为 `hooks/*.tsx`,**禁止**创建 `.vue` 后缀的子组件。
16
+ - 样式统一放在 `index.scss`,使用 BEM 规范。**禁止**使用 CSS Modules (`.module.scss`)。
17
+
18
+ 2. **Hook 模式**:
19
+ - Hook 文件后缀必须是 `.tsx`。
20
+ - Hook 必须返回 `{ render: () => JSX }` 对象。
21
+ - 复杂模块需拆分为多个细粒度 Hook(如 `useFilter`, `useList`, `useFooter`),并在 `index.vue` 中组合。
22
+
23
+ 3. **状态管理**:
24
+ - **必须**在 `index.vue` 中使用 `let [state, setState] = defineCtxState({})` 初始化模块级共享状态。
25
+ - **必须**在子 Hooks 中使用 `useCtxState` 获取`defineCtxState`共享的状态。
26
+ - 禁止在 Hooks 中使用散乱的 `ref` / `reactive` 管理全局状态。
27
+
28
+ 4. **资源与命名**:
29
+ - 图片存放在模块 `assets` 目录,命名格式 `img_func_desc.png`,必须 `import` 引入。
30
+ - 事件处理函数命名使用 `onClickXxx` (点击) 或 `handleXxx` (通用)。
31
+
32
+ ---
33
+
34
+ ## 目录结构示例
35
+
36
+ ```
37
+ demo/
38
+ ├── api.ts # API 接口
39
+ ├── types.ts # 类型定义(和入口文件在同一级目录)
40
+ ├── constants.ts # 常量定义(可选)
41
+ ├── util.ts # 工具函数(可选)
42
+ ├── index.vue # 入口页面 (TSX)
43
+ ├── index.scss # 样式文件 (BEM 规范)
44
+ └── hooks/ # Hooks 目录 (业务逻辑拆分)
45
+ ├── index.ts # 统一导出
46
+ ├── useList.tsx # 列表渲染 Hook
47
+ └── useSearchForm.tsx # 搜索表单 Hook
48
+ ```
49
+
50
+ ## 代码示例
51
+
52
+ ### 1. 模块入口 (index.vue)
53
+
54
+ - 使用 `defineComponent` + `lang="tsx"`。
55
+ - 使用 `let [state, setState] = defineCtxState({})` 初始化状态。
56
+ - 组合 Hooks 的 `render` 函数,并在 `vue` 中的tsx调用。
57
+
58
+ ```vue
59
+ <script lang="tsx">
60
+ import { defineComponent } from 'vue'
61
+ import { apiGetUserList } from '../api'
62
+ import { useList, useSearchForm } from './hooks'
63
+ import type { UserListState } from '../types'
64
+ import { defineCtxState } from '@allkit/use'
65
+
66
+ export default defineComponent({
67
+ name: 'Demo',
68
+ setup() {
69
+ // 1. 初始化共享状态
70
+ let [state, setState] = defineCtxState<UserListState>({
71
+ userList: [],
72
+ listLoading: false,
73
+ searchForm: {},
74
+ pagination: { current: 1, size: 10, total: 0 },
75
+ })
76
+
77
+ const getSearchList = () => {
78
+ setState(state=>(state.name =1))
79
+ // ... 业务逻辑
80
+ }
81
+
82
+ // 2. 组合 Hooks
83
+ const { render: renderSearch } = useSearchForm(getSearchList)
84
+ const { render: renderList } = useList()
85
+
86
+ // 3. 返回渲染函数
87
+ return () => (
88
+ <div class='user-list'>
89
+ {renderSearch()}
90
+ {renderList()}
91
+ </div>
92
+ )
93
+ },
94
+ })
95
+ </script>
96
+
97
+ <style lang="scss">
98
+ @import './index.scss';
99
+ </style>
100
+ ```
101
+
102
+ ### 2. 业务 Hook (hooks/useSearchForm.tsx)
103
+
104
+ - `.tsx` 后缀。
105
+ - 使用 `useCtxState` 获取`defineCtxState`共享的状态,内部的状态统一用`let currState =reactive({})`对象包裹 。
106
+ - 返回包含 `render` 的对象。
107
+
108
+ ```tsx
109
+ import { useCtxState } from '@allkit/use'
110
+ import type { UserListState } from '../../types'
111
+
112
+ export const useSearchForm = () => {
113
+ const [state, setState] = useCtxState<UserListState>()
114
+ //内部状态
115
+ let currState = reactive({
116
+ name: '',
117
+ })
118
+
119
+ const onClickSearchBtn = () => {
120
+ setState(state=>state.name=1)
121
+ }
122
+
123
+ const render = () => (
124
+ <div class='search-form'>
125
+ {/* 使用 state.searchForm */}
126
+ <input
127
+ type='text'
128
+ placeholder='请输入姓名'
129
+ value={currState.name}
130
+ onChange={(e) => (currState.name = e.target.value)}
131
+ />
132
+ <button onClick={onClickSearchBtn}>搜索</button>
133
+ </div>
134
+ )
135
+
136
+ return {
137
+ render
138
+ }
139
+ }
140
+ ```
141
+
142
+ ### 3. 类型定义 (types.ts)
143
+
144
+ ```ts
145
+ export interface User {
146
+ id: string
147
+ name: string
148
+ }
149
+
150
+ export interface UserListState {
151
+ listLoading: boolean
152
+ userList: User[]
153
+ searchForm: Partial<User>
154
+ pagination: {
155
+ current: number
156
+ size: number
157
+ total: number
158
+ }
159
+ }
160
+ ```
161
+
162
+ ## 模块职责划分
163
+
164
+ | 文件/目录 | 职责 | 备注 |
165
+ | ---------------- | --------------------------------------- | ---- |
166
+ | `index.vue` | 页面入口、状态初始化、Hook 组合与布局 | 必选 |
167
+ | `hooks/*.tsx` | 具体的业务逻辑与 UI 片段 (Logic + View) | 可选 |
168
+ | `hooks/index.ts` | 统一导出所有 Hooks | 可选 |
169
+ | `api.ts` | API 接口定义 | 可选 |
170
+ | `types.ts` | 类型定义 (State, Entity) | 必选 |
171
+ | `index.scss` | 样式文件 (BEM) | 可选 |
172
+ | `dict.ts` | 枚举定义,map映射 (可选) | 可选 |
173
+ | `constants.ts` | 常量定义 (可选) | 可选 |
@@ -0,0 +1,77 @@
1
+ ---
2
+ title: 变量命名
3
+ description: 项目中变量的ts,js代码命名规则及最佳实践
4
+ category: 命名规范
5
+ ---
6
+
7
+ # 变量命名
8
+
9
+ ## 使用场景
10
+ 定义项目中变量的命名规则,确保代码可读性和一致性。
11
+
12
+ ## 基础使用
13
+
14
+ ### 命名规则
15
+ - 使用 `小驼峰` 命名法
16
+ - 使用 `单词全称`,避免缩写
17
+ - 不超过 `20个字符`
18
+ - 使用规范的前后缀
19
+
20
+ ### 基本示例
21
+ ```ts
22
+ const fileName = ''
23
+ const vueRouter = {}
24
+ const orderList = []
25
+ const useHook = () => {}
26
+ ```
27
+
28
+ ## 类型命名规范
29
+
30
+ ### 数组命名
31
+ 使用 `List`、`Array` 后缀或单词复数
32
+
33
+ | 推荐 | 不推荐 |
34
+ |------|--------|
35
+ | `orderList` | `orders` |
36
+ | `userArray` | `userArr` |
37
+ | `items` | `itemList` |
38
+
39
+ ### 对象命名
40
+ 使用 `Object`、`Obj`、`Data`、`Info` 后缀
41
+
42
+ | 推荐 | 不推荐 |
43
+ |------|--------|
44
+ | `userInfo` | `user` |
45
+ | `formData` | `form` |
46
+ | `orderObj` | `order` |
47
+
48
+ ### 布尔值命名
49
+ 使用 `is`、`has`、`can` 前缀
50
+
51
+ | 前缀 | 含义 | 示例 |
52
+ |------|------|------|
53
+ | `is` | 是不是 | `isEmpty`, `isLoading` |
54
+ | `has` | 有没有 | `hasPermission`, `hasError` |
55
+ | `can` | 能不能 | `canEdit`, `canDelete` |
56
+ | `show` | 显示状态 | `showDialog`, `showLoading` |
57
+
58
+ ### 数字命名
59
+ 使用 `Count`、`Total`、`Num` 后缀
60
+
61
+ ```ts
62
+ const fileCount = 10
63
+ const rowTotal = 100
64
+ const pageNum = 1
65
+ const limit = 20
66
+ ```
67
+
68
+
69
+ ## 命名对照表
70
+
71
+ | 类型 | 前缀/后缀 | 示例 |
72
+ |------|-----------|------|
73
+ | 数组 | `List`, `Array` | `orderList`, `userArray` |
74
+ | 对象 | `Info`, `Data`, `Obj` | `userInfo`, `formData` |
75
+ | 布尔 | `is`, `has`, `can` | `isEmpty`, `hasError` |
76
+ | 数字 | `Count`, `Total`, `Num` | `totalCount`, `pageTotal` |
77
+ | 响应式 | `State`, `Ref` | `currState`, `inputRef` |