在 Vue 3 + TypeScript 中封装组件时,需要注意以下几点:
1. Props 定义
-
使用
defineProps
或PropType
定义组件的 props,并为其添加类型。 -
示例:
import { defineComponent, PropType } from 'vue'; export default defineComponent({ props: { title: { type: String as PropType<string>, required: true, }, count: { type: Number as PropType<number>, default: 0, }, }, });
2. Emit 事件
-
使用
defineEmits
定义组件发出的事件,并为其添加类型。 -
示例:
import { defineComponent } from 'vue'; export default defineComponent({ emits: ['update:count'], setup(props, { emit }) { const increment = () => { emit('update:count', props.count + 1); }; return { increment, }; }, });
3. Slots 插槽
-
使用
slots
定义插槽,并通过v-slot
或#
语法使用。 -
示例:
<template> <div> <slot name="header"></slot> <slot></slot> <slot name="footer"></slot> </div> </template>
4. Scoped Slots 作用域插槽
-
通过
v-slot
或#
语法传递数据给插槽。 -
示例:
<template> <div> <slot :item="item"></slot> </div> </template> <script lang="ts"> import { defineComponent } from 'vue'; export default defineComponent({ setup() { const item = { name: 'Vue 3' }; return { item, }; }, }); </script>
5. Provide/Inject
-
使用
provide
和inject
实现跨组件数据传递,并为其添加类型。 -
示例:
import { defineComponent, provide, inject } from 'vue'; const key = Symbol(); export default defineComponent({ setup() { provide(key, 'some value'); }, }); export const useInjectedValue = () => inject(key);
6. Composable 函数
-
将可复用的逻辑提取到
composable
函数中,并为其添加类型。 -
示例:
import { ref, computed } from 'vue'; export function useCounter() { const count = ref(0); const double = computed(() => count.value * 2); function increment() { count.value++; } return { count, double, increment, }; }
7. 类型推断
-
利用 TypeScript 的类型推断功能,确保组件内部逻辑的类型安全。
-
示例:
import { defineComponent, ref } from 'vue'; export default defineComponent({ setup() { const count = ref(0); // TypeScript 会自动推断 count 为 Ref<number> return { count, }; }, });
8. 组件引用
-
使用
ref
引用子组件,并为其添加类型。 -
示例:
import { defineComponent, ref } from 'vue'; import ChildComponent from './ChildComponent.vue'; export default defineComponent({ components: { ChildComponent, }, setup() { const childRef = ref<InstanceType<typeof ChildComponent>>(); return { childRef, }; }, });
9. 样式隔离
-
使用
scoped
样式或 CSS Modules 确保样式隔离。 -
示例:
<template> <div class="my-component"> <p>Hello World</p> </div> </template> <style scoped> .my-component { color: red; } </style>
10. 单元测试
-
使用
Jest
或Vitest
编写单元测试,确保组件功能正确。 -
示例:
import { mount } from '@vue/test-utils'; import MyComponent from './MyComponent.vue'; test('MyComponent', () => { const wrapper = mount(MyComponent, { props: { title: 'Hello', }, }); expect(wrapper.text()).toContain('Hello'); });
11. 文档和示例
- 为组件编写清晰的文档和使用示例,方便其他开发者理解和使用。
12. 性能优化
- 使用
v-if
、v-show
、keep-alive
等优化组件渲染性能。 - 避免不必要的重新渲染。
13. 错误处理
- 在组件中添加错误处理逻辑,确保组件在异常情况下仍能正常工作。
14. 国际化
- 如果组件需要支持多语言,使用
vue-i18n
或其他国际化方案。
15. 可访问性
- 确保组件符合可访问性标准(如 ARIA 属性),提升用户体验。
通过以上步骤,可以确保封装的 Vue 3 + TypeScript 组件具备良好的可维护性、可复用性和类型安全性。