docs: improve component style guide

This commit is contained in:
Sagi 2022-09-15 20:23:48 +08:00
parent 622d6ba831
commit f2fe699f1e
7 changed files with 64 additions and 60 deletions

View File

@ -20,9 +20,9 @@
为了保证项目代码质量,我们指定了详细的编码风格指南。
为了你的PR可以顺利通过代码审查请在编码前认真阅读以下**编码指南**
- [Farris UI TypeScript 编码指南](./style-guid/typescript_style_guid.md)
- [Farris UI TypeScript 编码指南](./style-guide/typescript_style_guide.md)
- [Farris UI Vue 组件编码指南](./style-guid/vue_component_style_guid.md)
- [Farris UI Vue 组件编码指南](./style-guide/vue_component_style_guide.md)
## 提交Pull Request

View File

@ -14,19 +14,18 @@ Farris UI Vue 的组件,都包含在`ui-vue`包的`components`目录下,每
以下是单个组件目录的结构
```
farris-component
├── specs // 单元测试
| └── farris-component.spec.ts
input-group
├── test // 单元测试
| └── input-group.spec.tsx
├── src // 组件源码
| ├── components // 子组件
| | └── farris-child-component.ts
| ├── services // 组件的可复用逻辑
| | ├── some-feature.service.ts
| | ├── some-feature.render.ts
| | ├── some-feature.template.ts
| | └── some-event.handler.ts
| ├── farris-component.types.ts // 组件类型
| └── farris-component.tsx // 组件代码
| | └── input-group-sub.component.tsx
| ├── composition // 组件的可复用逻辑
| | ├── types.ts // 组合式Api返利值接口类型
| | ├── use-append-button.ts // 实现组件特性1的组合式Api
| | └── use-clear.ts // 实现组件特性2的组合式Api
| ├── input-group.component.tsx // 组件代码
| └── input-group.props.ts // 定义组件Api
└── index.ts // 组件入口文件
```
@ -34,102 +33,107 @@ farris-component
```TypeScript
import type { App } from 'vue';
import FarrisComponent from './src/farris-component';
import InputGroup from './src/input-group.component';
export * from './src/farris-component.types';
export * from './src/input-group.props';
export { FarrisComponent };
export { InputGroup };
export default {
install(app: App): void {
app.component(FarrisComponent.name, FarrisComponent);
app.component(InputGroup.name, InputGroup);
},
};
```
### 组件文件 `my-component.tsx`
### 组件文件 `input-group.component.tsx`
```TypeScript
import { defineComponent, toRefs } from 'vue';
import type { SetupContext } from 'vue';
import { someComponentProps, SomeComponentProps } from './farris-component.types';
import { someFeatureService } from './services/some-feature.service';
import { InputGroupProps, inputGroupProps } from './input-group.props';
import { useClear } from './composition/use-clear';
export default defineComponent({
name: 'f-some-component',
props: someComponentProps,
name: 'FInputGroup',
props: inputGroupProps,
emits: ['update:modelValue'],
setup(props: SomeComponentProps, setupContext: SetupContext) {
setup(props: InputGroupProps, setupContext: SetupContext) {
const { someProp } = toRefs(props);
const { someVarieble, someMethod } = someFeatureService();
const { showClearButton, onClearValue } = useClear();
return () => {
return (
<div class="f-some-component">{ someProp.value }</div>
<div class="f-input-group">{ someProp.value }</div>
);
};
},
});
```
### 类型文件 `farris-component.types.ts`
### 类型文件 `input-group.props.ts`
```TypeScript
import { PropType, ExtractPropTypes } from 'vue';
export const someComponentProps = {
pageIndex: {
type: Number,
default: 1
},
pageSize: {
type: Array as PropType<number[]>,
default: [5, 10, 20, 50]
}
export const inputGroupProps = {
/**
* 显示输入框的标签
*/
enableTitle: { type: Boolean, default: false },
/**
* 输入框提示文本
*/
placeholder: { type: String, default: '' },
/**
* 输入框Tab键索引
*/
tabIndex: Number
};
export type SomeComponentProps = ExtractPropTypes<typeof someComponentProps>;
export type InputGroupProps = ExtractPropTypes<typeof inputGroupProps>;
```
### 控制逻辑 `some-feature.service.ts`
### 组合式Api `use-clear.ts`
```TypeScript
import { ref } from 'vue';
import { computed, SetupContext } from 'vue';
import { InputGroupProps } from '../input-group.props';
import { UseClear } from './types';
export function someFeatureService() {
const someVarieble = ref(xxx);
export function useClear(props: InputGroupProps, setupContext: SetupContext): UseClear {
const showClearButton = computed(() => props.enableClear && !props.readonly && !props.disable);
const someMethod = () => {
function onClearValue($event: Event) {
console.log('on onClearValue');
}
return {
showClearButton,
onClearValue
};
return { someVarieble, someMethod };
}
```
### 单元测试 `farris-component.spec.ts`
### 单元测试 `input-group.spec.tsx`
```ts
import { mount, DOMWrapper } from '@vue/test-utils';
import { ref } from 'vue';
import FSomeComponent from '../src/farris-component';
import { mount } from '@vue/test-utils';
import { InputGroup } from '..';
describe('SomeComponent', () => {
it('should render correctly', async () => {
describe('f-input-group', () => {
it('variant', () => {
const wrapper = mount({
components: { FSomeComponent },
template: `
<f-some-component some-prop="xxx" />
`,
setup() {
const someVarieble = ref(xxx);
return { someVarieble };
}
return () => {
return <InputGroup editable={false}></InputGroup>;
};
},
});
expect(xxx).toEqual(xxx);
expect(wrapper.find('.f-cmp-inputgroup').exists()).toBeTruthy();
expect(wrapper.find('div').find('div').find('input').find('[readlony]').exists).toBeTruthy();
});
});
```
@ -142,7 +146,7 @@ describe('SomeComponent', () => {
- 使用属性透传传递原生属性不允许在单独定义API声明原生属性。
- 正确定义和使用TypeScript类型代码中无TypeScript类型报错。
- 变量采用语义化命名,原则上不需要通过注释说明变量或函数功能,详细命名规则参考[Farris UI TypeScript 编码指南](./style-guid/typescript_style_guid.md)。
- 需要将组件的props定义在独立的文件some-component.types.ts文件中并在此文件中同时导出props和PropsType。
- 需要将组件的props定义在独立的文件some-component.props.ts文件中并在此文件中同时导出props和PropsType。
- 应该在setup函数返回的render函数中编写组件的Html模板。
- 必须在组件的index.ts文件中导出组件参数的类型以便于在引用组件时方便TypeScript进行类型提示。
- defineComponent函数接收的参数顺序为name、props、emits、inheritAttrs、setup。