Vue3 组件

关键要点

  • Vue3 组件是可复用的独立单元,包含模板、逻辑和样式,适合模块化开发。
  • 支持单文件组件(.vue)、全局/局部注册,以及 Props 和事件通信。
  • Composition API 提供更灵活的逻辑组织,推荐与单文件组件结合使用。

直接回答

Vue3 的组件是构建用户界面的核心,允许将 UI 拆分为独立、可复用的部分。以下是关键内容:

  • 创建组件:通过 defineComponent 或单文件组件(.vue)定义,包含 <template><script><style>
  • 注册组件:全局注册用 app.component('name', Component),局部注册在 components 选项中。
  • Props 和事件:用 Props 传递数据(如 :msg="parentMsg"),通过 $emit 触发事件(如 @update="handleUpdate")。
  • API 风格:Options API 适合简单场景,Composition API 适合复杂逻辑,使用 refreactive 管理状态。

单文件组件示例:

<template>
  <div>{{ msg }}</div>
</template>
<script>
export default {
  props: ['msg']
}
</script>
<style scoped>
div { color: blue; }
</style>

更多详情见 Vue.js 官方文档 – 组件基础


详细报告

Vue3 的组件系统是其核心特性之一,允许开发者将用户界面拆分为独立、可复用的模块。组件可以包含模板(HTML)、逻辑(JavaScript)和样式(CSS),支持模块化开发和高效维护。以下是 Vue3 组件的全面讲解,涵盖定义、注册、通信、API 风格和最佳实践。

1. 什么是 Vue3 组件?

  • 定义:组件是 Vue3 中可复用的代码单元,类似于自定义 HTML 元素,具有独立的模板、逻辑和样式。
  • 作用:通过组件化,开发者可以将复杂 UI 拆分为小块,提高代码复用性和可维护性。
  • 特点
  • 支持单文件组件(.vue 文件),将模板、逻辑和样式封装在一起。
  • 基于虚拟 DOM 和响应式系统(Proxy),性能提升 20-50% 相比 Vue2。
  • 提供 Options API 和 Composition API 两种逻辑组织方式。

2. 创建组件

Vue3 支持多种方式创建组件,最常见的是单文件组件(SFC)和 JavaScript 对象定义。

  • 单文件组件(SFC)
    单文件组件以 .vue 为后缀,包含三个部分:
  • <template>:定义 HTML 模板。
  • <script>:定义组件逻辑,支持 export default 导出。
  • <style>:定义 CSS 样式,支持 scoped 限制样式作用域。 示例:
  <template>
    <div class="greeting">{{ message }}</div>
  </template>
  <script>
  export default {
    data() {
      return {
        message: 'Hello, Vue 3!'
      }
    }
  }
  </script>
  <style scoped>
  .greeting {
    color: green;
  }
  </style>
  • JavaScript 对象定义
    使用 defineComponent 创建组件,适合不使用构建工具的场景。例如:
  import { defineComponent } from 'vue';
  export default defineComponent({
    template: `<div>{{ message }}</div>`,
    data() {
      return { message: 'Hello, Vue 3!' };
    }
  });

3. 注册组件

组件创建后需注册才能在模板中使用,支持全局注册和局部注册。

  • 全局注册
    使用 app.component() 注册,组件可在整个应用中使用。例如:
  import { createApp } from 'vue';
  import MyComponent from './MyComponent.vue';
  const app = createApp({});
  app.component('my-component', MyComponent);
  app.mount('#app');

使用:

  <my-component></my-component>
  • 局部注册
    在组件的 components 选项中注册,仅在当前组件可用。例如:
  import MyComponent from './MyComponent.vue';
  export default {
    components: {
      MyComponent
    }
  };

使用:

  <my-component></my-component>
  • 命名规范
  • 组件名推荐使用 kebab-case(如 my-component),因为 HTML 不区分大小写。
  • PascalCase(如 MyComponent)也支持,但在模板中需转为 kebab-case。

4. Props 与事件通信

组件通过 Props 和事件实现父子通信。

  • Props
    Props 是父组件向子组件传递数据的机制,子组件通过 props 选项声明。例如:
  <template>
    <div>{{ msg }}</div>
  </template>
  <script>
  export default {
    props: {
      msg: String
    }
  }
  </script>

父组件使用:

  <my-component msg="Hello from parent"></my-component>
  • 支持类型校验,如 props: { msg: { type: String, required: true } }
  • 动态绑定用 :msg="parentMsg"
  • 事件
    子组件通过 $emit 触发事件,父组件通过 @event 监听。例如:
    子组件:
  <template>
    <button @click="$emit('increment')">点击</button>
  </template>
  <script>
  export default {
    emits: ['increment']
  }
  </script>

父组件:

  <my-component @increment="count++"></my-component>
  • 使用 emits 选项声明事件,增强代码可读性。
  • 支持传递参数,如 $emit('update', newValue)
  • 双向绑定
    使用 v-model 实现双向绑定,子组件需触发 update:modelValue 事件。例如:
    子组件:
  <template>
    <input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)">
  </template>
  <script>
  export default {
    props: ['modelValue'],
    emits: ['update:modelValue']
  }
  </script>

父组件:

  <my-component v-model="inputValue"></my-component>

5. API 风格

Vue3 支持两种 API 风格,用于组织组件逻辑。

  • Options API
    适合简单场景,使用 datamethods 等选项。例如:
  export default {
    data() {
      return { count: 0 };
    },
    methods: {
      increment() {
        this.count++;
      }
    }
  };
  • 结构清晰,适合初学者。
  • 对于复杂组件,逻辑可能分散。
  • Composition API
    更灵活,适合复杂逻辑,使用 refreactive 管理状态。例如:
  import { ref } from 'vue';
  export default {
    setup() {
      const count = ref(0);
      const increment = () => count.value++;
      return { count, increment };
    }
  };
  • 使用 <script setup> 简化语法:
    vue ¨K42K
  • 优点:逻辑按功能组织,支持更好的类型推导和复用。

6. 插槽(Slots)

插槽允许父组件向子组件传递内容,增强组件灵活性。

  • 默认插槽
    子组件:
  <template>
    <div><slot>默认内容</slot></div>
  </template>

父组件:

  <my-component>自定义内容</my-component>
  • 具名插槽
    子组件:
  <template>
    <slot name="header"></slot>
    <slot name="footer"></slot>
  </template>

父组件:

  <my-component>
    <template v-slot:header>头部</template>
    <template v-slot:footer>底部</template>
  </my-component>
  • 作用域插槽
    子组件传递数据给父组件插槽:
  <template>
    <slot :item="item">{{ item.name }}</slot>
  </template>
  <script>
  export default {
    data() {
      return { item: { name: 'Vue' } };
    }
  }
  </script>

父组件:

  <my-component v-slot="{ item }">
    {{ item.name }} is great!
  </my-component>

7. 动态组件

使用 <component :is> 动态切换组件。例如:

<component :is="currentComponent"></component>
data() {
  return {
    currentComponent: 'ComponentA'
  };
}

8. 最佳实践

  • 单一职责:每个组件专注单一功能,避免过于复杂。
  • 命名规范:组件名使用 kebab-case(如 my-component),Props 和事件使用 camelCase。
  • Props 校验:为 Props 定义类型和默认值,增强健壮性。
  • 性能优化:避免在 v-for 中使用复杂组件,必要时用 keep-alive 缓存。
  • 代码复用:使用 Composition API 的组合函数(如 useCounter)复用逻辑。

9. 学习资源

以下是学习 Vue3 组件的推荐资源:

10. 总结

Vue3 组件是构建现代 Web 应用的基石,通过单文件组件、Props、事件和插槽实现模块化和复用。Options API 和 Composition API 提供灵活的开发方式,推荐结合单文件组件和 Composition API 进行开发。


关键引文

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注