当前位置: 首页 > news >正文

Vue3 + TS组件封装指南

在 Vue 3 + TypeScript 中封装组件时,需要注意以下几点:

1. Props 定义

  • 使用 definePropsPropType 定义组件的 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

  • 使用 provideinject 实现跨组件数据传递,并为其添加类型。

  • 示例:

    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. 单元测试

  • 使用 JestVitest 编写单元测试,确保组件功能正确。

  • 示例:

    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-ifv-showkeep-alive 等优化组件渲染性能。
  • 避免不必要的重新渲染。

13. 错误处理

  • 在组件中添加错误处理逻辑,确保组件在异常情况下仍能正常工作。

14. 国际化

  • 如果组件需要支持多语言,使用 vue-i18n 或其他国际化方案。

15. 可访问性

  • 确保组件符合可访问性标准(如 ARIA 属性),提升用户体验。

通过以上步骤,可以确保封装的 Vue 3 + TypeScript 组件具备良好的可维护性、可复用性和类型安全性。

相关文章:

  • 大模型面试高频考点-显存占用
  • QoS 技术详解:原理、应用与配置实践
  • Java中,`Thread`类的`sleep`方法使用整理
  • 日语学习-日语知识点小记-构建基础-JLPT-N4N5阶段(23):たら ても
  • 如果etc里的文件缺失,或者etc被删除了导致无法正常启动该怎么做?
  • python-leetcode 54.全排列
  • 详细解释javascript的GO对象和AO对象
  • pandas学习笔记(一)——基础知识和应用案例
  • PixelCLIP
  • 系统思考:恶性循环
  • 万字面试题助力春招(待补充)
  • Node.js中SerialPort(串口)模块使用详解
  • Spring 原生启动过程
  • 高数1.5 极限的运算法则
  • Tree of Thought Prompting(思维树提示)
  • Android的消息机制
  • 激光雷达“开卷”2.0,头部Tier1入局
  • 图神经网络学习笔记-图神经网络可解释性应用详解(专题二十二)
  • 算法-除自身以外数组的乘积
  • pfsense部署二(ips基本使用)
  • 见微知沪|科学既要勇攀高峰,又要放低身段
  • 雅典卫城上空现“巨鞋”形状无人机群,希腊下令彻查
  • 著名心血管病学专家李国庆教授逝世,享年63岁
  • 以军向也门3个港口的居民发布撤离令
  • 崔登荣任国家游泳队总教练
  • 中哥两国元首共同见证签署《中华人民共和国政府与哥伦比亚共和国政府关于共同推进丝绸之路经济带和21世纪海上丝绸之路建设的合作规划》