docs: improve component style guide
This commit is contained in:
parent
622d6ba831
commit
f2fe699f1e
|
@ -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
|
||||
|
||||
|
|
|
@ -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。
|
Loading…
Reference in New Issue