Skip to content

Vue DevUI 组件库规范文档

行言 edited this page May 9, 2022 · 4 revisions
  1. API表格规范
  2. 组件API规范
  3. 演示demo规范
  4. 编码规范
  5. 组件目录/文件规范
  6. 样式命名规范

1 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

2 组件API规范

  1. 命名方式用中划线风格:组件的参数名和事件名统一使用中划线格式。
  2. 组件名称前缀:组件的命名统一使用D前缀。
  3. 针对需要双向绑定的参数,需要直接用v-model,避免增加额外参数,例如v-model:xxx
  4. 原生支持的属性尽量不再用API去单独声明,直接通过attrs透传即可,比如placeholder

3 演示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. 【何时使用】标题等级应该为四级。

4 编码规范

  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参数顺序为namepropsemitsinheritAttrssetupcomponentsdirectives不需要在组件内显示声明。
  17. 变量和函数的声明顺序需要按照字典序排列。

5 组件目录/文件规范

  1. 整体目录结构
  2. 组件文件my-component.tsx
  3. 组件入口文件index.ts
  4. 组件类型文件规范my-component-types.ts
  5. Composable规范useMyComponent.ts
  6. 样式文件规范my-component.scss
  7. 单元测试文件规范my-component.spec.ts

5.1 目录整体结构

my-component
├── __tests__                 // 组件单元测试
|  └── my-component.spec.ts
├── index.ts                  // 组件入口文件
└── src                       // 组件源码
   └── components             // 子组件
      ├── my-sub-component.ts
   └── composables            // 组件的逻辑部分 composable
      ├── my-use-component.ts
   ├── my-component-types.ts  // 组件类型文件
   ├── my-component.scss      // 组件样式
   └── my-component.tsx       // 组件

5.2 组件文件my-component.tsx

import { defineComponent, toRefs } from 'vue';
import type { SetupContext } from 'vue';
import { myComponentProps, MyComponentProps } from './my-component-types';
import useMyComponent from './use-button';
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 } = useMyComponent(myUseParam);

    return () => {
      return (
        <div class="devui-my-component">{ myProp.value }</div>
      );
    };
  },
});

5.3 组件入口文件index.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);
  },
};

5.4 组件类型文件规范my-component-types.ts

import { PropType, ExtractPropTypes } from 'vue';

export const myComponentProps = {
  myProp: {
    type: Number,
    default: 1
  },
  myProp2: {
    type: Array as PropType<number[]>,
    default: [5, 10, 20, 50]
  },
} as const;

export type MyComponentProps = ExtractPropTypes<typeof myComponentProps>;

5.5 Composable规范useMyComponent.ts

import { ref } from 'vue';

export default function useMyComponent(myUseParam) {
  const myUseVar = ref(xxx);

  const myUseMethod = () => {
    
  };

  return { myUseVar, myUseMethod };
}

5.6 样式文件规范my-component.scss

@import '../../styles-var/devui-var.scss';

.devui-my-component {

}

5.7 单元测试文件规范my-component.spec.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: `
        <d-my-component my-prop="xxx" />
      `,
      setup() {
        const myVar = ref(xxx);
        return { myVar };
      }
    });

    expect(xxx).toEqual(xxx);
  });
});

6 样式命名规范

use-namespace文件中,封装了样式命名的相关方法。样式命名采用BEM规范use-namespace提供了如下几个方法:

// 以 Button 组件为例

// 创建 Button 组件的命名空间
const ns = useNamespace('button');

// 根组件一般采用此命名
ns.b();  // devui-button

// 组件内的块元素样式命名,即 BEM 规范的 Element 部分
ns.e('content');  // devui-button__content

// 组件的修饰类样式命名,即 BEM 规范的 Modifier 部分
ns.m('primary');  // devui-button--primary

// 块元素和修饰类样式组合使用
ns.em('content', 'primary');  // devui-button__content--primary

目前use-namespace只封装了如上几个方法,在使用中如有新的需求可继续丰富扩展。

在使用use-namespace重构样式命名的时候,tsx文件中采用如上几个方法进行重命名,scss中修改对应的样式名字即可。