From 7ed8271e2d8898e3c100a839390c5402c53b80b8 Mon Sep 17 00:00:00 2001 From: Kagol Date: Mon, 21 Mar 2022 17:05:50 +0800 Subject: [PATCH 1/2] =?UTF-8?q?refactor:=20=E8=B0=83=E6=95=B4=E8=B4=A1?= =?UTF-8?q?=E7=8C=AE=E8=80=85=E6=8C=87=E5=8D=97=E7=9A=84=E7=9B=AE=E5=BD=95?= =?UTF-8?q?=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CONTRIBUTING.md | 2 +- .../devui-vue/docs/{CONTRIBUTING.md => contributing/index.md} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename packages/devui-vue/docs/{CONTRIBUTING.md => contributing/index.md} (100%) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6a6d479819..6f813520c7 120000 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1 +1 @@ -packages/devui-vue/docs/CONTRIBUTING.md \ No newline at end of file +packages/devui-vue/docs/contributing/index.md \ No newline at end of file diff --git a/packages/devui-vue/docs/CONTRIBUTING.md b/packages/devui-vue/docs/contributing/index.md similarity index 100% rename from packages/devui-vue/docs/CONTRIBUTING.md rename to packages/devui-vue/docs/contributing/index.md From ab69045496a1602daed18139a7dfa2a408e631f7 Mon Sep 17 00:00:00 2001 From: Kagol Date: Mon, 21 Mar 2022 18:40:46 +0800 Subject: [PATCH 2/2] =?UTF-8?q?docs:=20=E5=AE=8C=E5=96=84=E5=BC=80?= =?UTF-8?q?=E5=8F=91=E8=A7=84=E8=8C=83=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devui-vue/docs/.vitepress/config/nav.ts | 2 +- .../api-demo-design/index.md | 6 + .../coding-specification/index.md | 22 +++ .../component-document/index.md | 39 +++++ .../directory-organization/index.md | 153 ++++++++++++++++++ .../development-specification/index.md | 10 ++ packages/devui-vue/docs/contributing/index.md | 6 +- 7 files changed, 234 insertions(+), 4 deletions(-) create mode 100644 packages/devui-vue/docs/contributing/development-specification/api-demo-design/index.md create mode 100644 packages/devui-vue/docs/contributing/development-specification/coding-specification/index.md create mode 100644 packages/devui-vue/docs/contributing/development-specification/component-document/index.md create mode 100644 packages/devui-vue/docs/contributing/development-specification/directory-organization/index.md create mode 100644 packages/devui-vue/docs/contributing/development-specification/index.md diff --git a/packages/devui-vue/docs/.vitepress/config/nav.ts b/packages/devui-vue/docs/.vitepress/config/nav.ts index ae5c12a10c..d6b0a4b69f 100644 --- a/packages/devui-vue/docs/.vitepress/config/nav.ts +++ b/packages/devui-vue/docs/.vitepress/config/nav.ts @@ -1,6 +1,6 @@ const nav = [ { text: '组件', link: '/' }, - { text: '贡献指南', link: '/CONTRIBUTING' }, + { text: '贡献指南', link: '/contributing/' }, { text: 'Playground', link: 'https://brenner8023.github.io/devui-playground' }, { text: '更新日志', link: 'https://github.com/DevCloudFE/vue-devui/releases' }, { text: '设计规范', link: 'https://devui.design/design-cn/start' } diff --git a/packages/devui-vue/docs/contributing/development-specification/api-demo-design/index.md b/packages/devui-vue/docs/contributing/development-specification/api-demo-design/index.md new file mode 100644 index 0000000000..b9aa114027 --- /dev/null +++ b/packages/devui-vue/docs/contributing/development-specification/api-demo-design/index.md @@ -0,0 +1,6 @@ +# 组件 API 和 Demo 设计规范 + +1. 命名方式用中划线风格:组件的参数名和事件名统一使用中划线格式。 +2. 组件名称前缀:组件的命名统一使用D前缀。 +3. 针对需要双向绑定的参数,需要直接用v-model,避免增加额外参数,例如v-model:xxx。 +4. 原生支持的属性尽量不再用API去单独声明,直接通过attrs透传即可,比如placeholder。 diff --git a/packages/devui-vue/docs/contributing/development-specification/coding-specification/index.md b/packages/devui-vue/docs/contributing/development-specification/coding-specification/index.md new file mode 100644 index 0000000000..79aa7fb213 --- /dev/null +++ b/packages/devui-vue/docs/contributing/development-specification/coding-specification/index.md @@ -0,0 +1,22 @@ +# 组件编码规范 + +1. 安装VSCode插件CodeMetrics,原则上函数圈复杂度不超过20。 +2. 正确定义和使用TS类型,代码无TS类型报错。 +3. 变量采用语义化命名,原则上不需要通过注释说明变量或函数功能。 +4. 需注意逻辑和结构的拆分,原则上函数不应该超过50行。 +5. 目录下的子目录和文件数之和不超过10个。 +6. 原则上单个文件的代码行数不超过200行。 +7. 代码单行长度不超过140个字符。 +8. 代码块嵌套深度不超过4层。 +9. 组件props需在xx-types.ts文件中定义,并且导出相关参数和props的类型。 +10. 代码中不应该出现未使用的变量和依赖。 +11. 代码中不应该出现console等调试信息。 +12. 在setup函数返回的render函数中定义组件的DOM结构,而不是用单独的render函数来定义。 +13. 需要在组件的index.ts文件导出组件参数的类型,方便业务在使用组件时,利用组件导出的参数类型。 +14. 组件的import列表大致遵循以下几个原则: + - 最上面应该是依赖的三方库,例如vue;中间部分是依赖的组件库的类型文件、子组件、工具函数等;最后一部分是依赖的样式。 + - 对于同一个库中的依赖,按照字典序排列,比如vue依赖中的defineComponent需要排在ref前面。 + - 中间部分的引入顺序为类型文件、子组件、工具函数。 +15. 需要区分从vue中引入的api和类型,对于类型的引入,需要通过import type引入,例如import type { Ref } from 'vue',类型引入应该紧跟在api引入的后面。 +16. defineComponent参数顺序为name、props、emits、inheritAttrs、setup。components和directives不需要在组件内显示声明。 +17. 变量和函数的声明顺序需要按照字典序排列。 diff --git a/packages/devui-vue/docs/contributing/development-specification/component-document/index.md b/packages/devui-vue/docs/contributing/development-specification/component-document/index.md new file mode 100644 index 0000000000..d466384078 --- /dev/null +++ b/packages/devui-vue/docs/contributing/development-specification/component-document/index.md @@ -0,0 +1,39 @@ +# 组件 API 和 Demo 文档规范 + +### Demo 文档 + +1. 演示demo需要对所使用的API及组件默认行为和样式等进行尽可能详细的说明。避免让用户自己去推测,降低用户学习和使用成本。 +2. 每个组件的第一个demo,应该是组件最基本的用法,即展示组件在不传参数或者传入最基本参数情况下的效果。后面的demo应该尽可能按照参数的使用频率来排序。 +3. 每个demo所展示的API应该尽量精简,尽量不要一个demo中展示多个API的用法。 +4. 当API是枚举值时,demo中应尽量展示每个枚举值的效果。 +5. 演示demo代码,组件的参数大于三个或单行过长时需要每个参数占用一行来展示,避免出现横向滚动条,。 +6. 演示demo自定义class样式,命名格式为xxx-demo-yyy(xxx为组件名,yyy为自定义样式名),不然会成为全局样式,有可能影响其他组件或者demo效果。 +7. 文案描述需清晰,尽量参考ng devui的文案描述,尽量避免口语化;标点符号使用需正确;文案中若涉及到英文单词,需在单次左右两侧加一个空格。 +8. 一个标题尽量展示一个demo,避免一个标题中展示多个demo。 +9. boolean类型的参数,在demo中展示,设置为true的时候,不需要显式的设置为true,直接写参数名字即可。 +10. demo的描述说明文案中,用到代码块的地方需要用反引号包裹。 +11. demo的描述说明文案应该跟在:::demo后面,不应该放在h4或其他标签中,也不应该放在代码块外面。 +12. 【何时使用】标题等级应该为四级,避免出现在快速前往导航中。 + +### API 文档 + +1. API部分应该遵循参数、事件、方法、插槽、类型定义的顺序,若某一项缺失则跳过;如果组件有特殊项需要说明,需要在类型定义后面编写。 +2. API表格的标题,组成格式为:Xxx [参数 | 事件 | 方法 | 插槽],Xxx为组件名字,采用大驼峰书写,需要注意组件名字后面加一个空格,标题等级为三级;类型定义标题的格式为Xxx 类型定义,组件名字同样为大驼峰格式,中间同样需要加一个空格,标题等级同样为三级,具体类型名字跟随在后面用四级标题定义。 +3. API表格表头和内容应该左对齐。 +4. 参数表格需要具备的列名及顺序为:参数名、类型、默认值、说明、跳转Demo。 + - 参数不需要使用反引号。 + - 类型需要使用反引号包裹;类型需准确,简单枚举值类型可直接列出来,复杂一些的类型可以写类型名字(如SizeType),然后增加锚点定位;参数基本类型采用首字母小写string,自定义类型名字采用大驼峰命名,(如SizeType)。 + - 默认值不需要反引号包裹,如果默认值为字符串或者枚举类型,应该使用单引号包裹,若无默认值则用双横线--表示。 + - 说明中需要标注该参数为必选还是可选。 + - 跳转Demo中的链接需能够正确跳转,并且demo中需要展示对应API的用法;若无展示Demo,则空白展示。 +5. 事件表格需要具备的列名及顺序为:事件名、回调参数、说明、跳转Demo。 + - 事件名不需要使用反引号。 + - 回调参数需要使用反引号包裹;类型格式为Function(name: string)。 + - 跳转Demo中的链接需能够正确跳转,并且demo中需要展示对应API的用法;若无展示Demo,则空白展示。 +6. 方法表格需要具备的列名及顺序为:方法名、类型、说明。 + - 方法名不需要使用反引号。 + - 类型需要使用反引号包裹。 +7. 插槽表格需要具备的列名及顺序为:插槽名、说明、参数。 + - 默认插槽也需要做说明,并且插槽名字应该为default。 + - 参数为组件内部暴露出来的数据。 +8. 类型定义需要使用typescript代码块,代码块格式为type xxx = yyy。 diff --git a/packages/devui-vue/docs/contributing/development-specification/directory-organization/index.md b/packages/devui-vue/docs/contributing/development-specification/directory-organization/index.md new file mode 100644 index 0000000000..e5c5cede5d --- /dev/null +++ b/packages/devui-vue/docs/contributing/development-specification/directory-organization/index.md @@ -0,0 +1,153 @@ +# 组件目录和文件组织规范 + +Vue DevUI 包含丰富的组件,都在`devui-vue`子包的`devui`目录下,该目录下的每一个子目录都是一个组件的源码,每个组件都有一个或多个贡献者。 + +组件目录和文件组织规范的目的就是规范组件的目录结构和各组件文件的组织形式。 + +目录规范分成以下部分: + +1. 组件目录结构 +2. 入口文件 `index.ts` +3. 组件文件 `my-component.tsx` +4. 类型文件 `my-component-types.ts` +5. Composable `use-my-composable.ts` +6. 样式文件 `my-component-scss` +7. 单元测试文件 `my-component.spec.ts` + +### 组件目录结构 + + +以下是组件目录结构的基本模板 + +``` +my-component +├── __tests__ // 单元测试 +| └── my-component.spec.ts +├── index.ts // 入口文件 +└── src // 组件源码 + └── components // 子组件 + ├── my-sub-component.ts + └── composables // 组件的逻辑部分 composable + ├── my-use-composable.ts + ├── my-component-types.ts // 组件类型 + ├── my-component.scss // 组件样式 + └── my-component.tsx // 组件 +``` + +### 入口文件 `index.ts` + +```ts +import type { App } from 'vue'; +import MyComponent from './src/my-component'; + +export * from './src/my-component-types'; + +export { MyComponent }; + +export default { + title: 'MyComponent 我的组件', + category: '通用', + status: '100%', + install(app: App): void { + app.component(MyComponent.name, MyComponent); + }, +}; +``` + +### 组件文件 `my-component.tsx` + +```ts +import { defineComponent, toRefs } from 'vue'; +import type { SetupContext } from 'vue'; + +import { myComponentProps, MyComponentProps } from './my-component-types'; +import useMyComposable from './composables/use-my-composable'; + +import './my-component.scss'; + +export default defineComponent({ + name: 'DMyComponent', + props: myComponentProps, + emits: ['update:modelValue'], + setup(props: MyComponentProps, ctx: SetupContext) { + const { myProp } = toRefs(props); + const { myUseVar, myUseMethod } = useMyComposable(myUseParam); + + return () => { + return ( +
{ myProp.value }
+ ); + }; + }, +}); +``` + +### 类型文件 `my-component-types.ts` + +```ts +import { PropType, ExtractPropTypes } from 'vue'; + +export const myComponentProps = { + myProp: { + type: Number, + default: 1 + }, + myProp2: { + type: Array as PropType, + default: [5, 10, 20, 50] + }, +} as const; + +export type MyComponentProps = ExtractPropTypes; +``` + +### Composable `use-my-composable.ts` + +```ts +import { ref } from 'vue'; + +export default function useMyComposable(myUseParam) { + const myUseVar = ref(xxx); + + const myUseMethod = () => { + + }; + + return { myUseVar, myUseMethod }; +} +``` + +### 样式文件 `my-component-scss` + +```scss +@import '../../styles-var/devui-var.scss'; + +.devui-my-component { + +} +``` + +### 单元测试文件 `my-component.spec.ts` + +```ts +import { mount, DOMWrapper } from '@vue/test-utils'; +import { ref } from 'vue'; +import DMyComponent from '../src/my-component'; + +describe('MyComponent', () => { + it('should render correctly', async () => { + const wrapper = mount({ + components: { DMyComponent }, + template: ` + + `, + setup() { + const myVar = ref(xxx); + return { myVar }; + } + }); + + expect(xxx).toEqual(xxx); + }); +}); +``` diff --git a/packages/devui-vue/docs/contributing/development-specification/index.md b/packages/devui-vue/docs/contributing/development-specification/index.md new file mode 100644 index 0000000000..527aaea66f --- /dev/null +++ b/packages/devui-vue/docs/contributing/development-specification/index.md @@ -0,0 +1,10 @@ +# 开发规范 + +Vue DevUI 是一个社区共建的开源组件库,为了确保一致性和质量,需要所有参与 Vue DevUI 建设的贡献者都遵循同一份开发规范。 + +规范分成以下几个部分: + +1. [组件目录和文件组织规范](/contributing/development-specification/directory-organization/) +2. [组件 API 和 Demo 设计规范](/contributing/development-specification/api-demo-design/) +3. [组件 API 和 Demo 文档规范](/contributing/development-specification/component-document/) +4. [组件编码规范](/contributing/development-specification/coding-specification/) diff --git a/packages/devui-vue/docs/contributing/index.md b/packages/devui-vue/docs/contributing/index.md index a65600ad0e..12466402e7 100644 --- a/packages/devui-vue/docs/contributing/index.md +++ b/packages/devui-vue/docs/contributing/index.md @@ -2,7 +2,7 @@ 你好!我们很高兴你有兴趣为 Vue DevUI 做出贡献。在提交你的贡献之前,请花点时间阅读以下指南: -## 快速上手 +### 快速上手 Vue DevUI 使用 `pnpm` 构建 `monorepo` 仓库,你应该使用 [pnpm](https://www.pnpm.cn/) 包管理器,以确保不会因为包管理器的不同而引发异常。 @@ -23,13 +23,13 @@ pnpm i pnpm dev ``` -## 参与贡献 +### 参与贡献 Vue DevUI 是一个多人合作的开源项目,为了避免多人同时开发同一个组件/功能,请先在 [issues 列表](https://github.com/DevCloudFE/vue-devui/issues) 中选择自己感兴趣的任务,在评论区认领 1. 请确保你已经完成快速上手中的步骤,并且正常访问[http://localhost:3000/](http://localhost:3000/) 2. 创建新分支 `git checkout -b username/feature1`,分支名字建议为`username/feat-xxx`/`username/fix-xxx` -3. 本地编码,需遵循`ls-lint`/`eslint`/`stylelint`编码规范 +3. 本地编码,需遵循[开发规范](/contributing/development-specification/) 4. 遵循 [Angular Commit Message Format](https://github.com/angular/angular/blob/master/CONTRIBUTING.md#commit) 进行提交(**不符合规范的提交将不会被合并**) 5. 提交到远程仓库,也就是 Fork 后的仓库,`git push origin branchName` 6. (可选) 同步上游仓库dev分支最新代码,`git pull upstream dev`