本文内容主要以 Vue3 为前提背景
1. 组件分类
1.1 函数式组件
函数式组件可以用来实现不需要维护自身状态的组件。它们像纯函数一样简单:接收 props,返回 vnodes。
优点:高性能、视图的可复用性、简单易测试
缺点:没有状态、实例、生命周期钩子函数
适用场景:纯展示型组件、大量数据的列表渲染
1.2 无渲染组件
一些组件可能只包括了数据逻辑,不需要自己渲染视图,而将视图的渲染逻辑交给组件外部来决定。这类型的组件称为无渲染组件。
优点:数据逻辑的可复用性
缺点:复杂性
适用场景:使用相同的数据逻辑,渲染出不同的视图展示形式(比如看板视图、表格视图、时间线视图)
1.3 高阶组件
高阶组件是接收一个组件并返回另一个组件的组件。
优点:组件的可拓展性
缺点:复杂性、深层组件树的性能问题
适用场景:对通用组件的二次封装
2. 组件定义方式
2.1 单文件组件
单文件组件是网页开发中 HTML、CSS 和 JavaScript 三种语言经典组合的自然延伸。<template>、<script> 和 <style> 三个块在同一个文件中封装、组合了组件的视图、逻辑和样式。
优点:语法简单
缺点:需要构建工具支持、类型检查支持较弱
适用场景:简单的组件
2.2 defineComponent()
defineComponent 函数接受一个组件配置对象作为参数,并返回一个 Vue 组件。这个配置对象包含了组件的各种选项,如组件的模板、数据、方法、生命周期钩子等。
优点:完善的类型检查、易于测试
缺点:语法较复杂
适用场景:复杂的组件、使用TS开发的组件
3. 组件注册方式
3.1 全局注册
全局注册一个组件后,即可在任意地方直接使用该组件。
优点:使用方便
缺点:命名冲突、增加应用的体积
适用场景:使用频率较高的公共基础组件
3.2 局部注册
可在某个组件内局部注册某个组件,局部注册后,该组件只可在当前组件内使用。
优点:避免命名冲突、利于减小应用体积
缺点:每次都需要手动引入
适用场景:特定于当前视图的组件
4. 组件渲染方式
4.1 模板语法
Vue 使用一种基于 HTML 的模板语法,使我们能够声明式地将其组件实例的数据绑定到呈现的 DOM 上。所有的 Vue 模板都是语法层面合法的 HTML,可以被符合规范的浏览器和 HTML 解析器解析。
优点:语法简单
缺点:难以实现复杂的渲染交互逻辑
适用场景:简单的视图渲染交互逻辑
4.2 渲染函数
模板语法可以解决绝大多数的使用场景。然而在某些使用场景下,我们真的需要用到 JavaScript 的编程能力。这时渲染函数就派上用场了。
优点:易于实现复杂的渲染交互逻辑
缺点:语法复杂
适用场景:复杂的视图渲染交互逻辑
4.3 JSX
JSX 语法同时保留了模板语法与渲染函数的优点,既有模板的可读性,又有渲染函数的灵活性。
优点:语法简单、渲染性能好、TS支持较好、易于实现复杂的渲染交互逻辑
缺点:与vue生态有部分兼容问题
适用场景:对组件性能、灵活性和扩展性要求较高
5. 组件调用方式
5.1 动态调用
动态组件可以通过变量来动态地决定渲染哪个组件,并可以配合 <KeepAlive> 组件缓存被切换隐藏的组件及其状态
适用场景:多个组件间切换显示(如tab页、路由页间的切换显示)
5.2 异步调用
异步组件是指在需要时才会加载的组件(即按需加载),可以帮助我们优化应用程序的性能和提高用户体验。
优点:提高页面初始加载速度
缺点:增加复杂度、加载时会有等待时间
适用场景:页面初始加载时不需要的组件、按需加载的组件
5.3 createApp()
createApp 可以用来创建Vue应用实例
优点:可通过配置项扩展Vue应用实例
适用场景:一般用来创建根组件
5.4 递归调用
递归组件是指一个组件可以在自己的模板中调用自己。
适用场景:树形结构的组件(如文件夹、子级评论、子级部门)
5.5 指令调用
是指通过 vue 指令来调用的组件,比如Element UI中的 Loading 组件可以通过 v-loading 指令进行调用
优点:易于访问、操作 DOM
缺点:产生不可预期的 DOM 行为
适用场景:复用对 DOM 的访问、操作逻辑
5.5 JS调用
是指通过 JS 代码来调用的组件,比如Element UI中的 Message 组件可以通过以下方式调用:
import { Message } from 'element-ui';
Message.success(options);
优点:调用时较灵活方便,不需要在模板中预先定义
缺点:定义组件时较复杂
适用场景:脱离文档流的简单悬浮组件
6. 组件生命周期
每个 Vue 组件实例在创建时都需要经历一系列的初始化步骤,比如设置好数据侦听,编译模板,挂载实例到 DOM,以及在数据改变时更新 DOM。在此过程中,它也会运行被称为生命周期钩子的函数,让开发者有机会在特定阶段运行自己的代码。
7. 组件间通信方式
7.1 props/$emit/v-model
适用于父子组件间的直接通信,用法详见: props、 $emit、 v-model
7.2 Pinia
Pinia 可用来管理全局状态,多个不同层级的组件间的公共状态可放到 Pinia 中管理
7.3 provide/inject
适用于为固定结构的后代组件提供数据,相当于局部的全局状态,用法详见:provide/inject
7.4 attributes
透传 attribute 指的是传递给一个组件,却没有被该组件声明为 props 或 emits 的 attribute 或者 v-on 事件监听器。最常见的例子就是 class、style 和 id。透传 Attributes 可以让我们将未知属性传递给组件内部指定的 HTML 元素。
7.5 $root/$parent/$refs
可通过 $root、$parent、$refs 获取相应组件实例上的数据和方法等信息。