Vue3 12.组件01
组件允许将UI划分为独立可重用的部分,并且可以对每个部分进行单独的处理。在实际应用中,组件常常被组织成一个层层嵌套的树状结构:
定义组件
使用构建步骤
当使用构建步骤时,一般会将Vue组件定义在一个单独的.vue
文件中,这被叫做单文件组件(SFC):
<script setup> |
不使用构建步骤
当不使用构建步骤时,一个Vue组件以一个包含Vue特定选项的Javascript对象来定义:
import { ref } from 'vue' |
这个例子定义了一个组件,并在一个.js
文件里面默认导出了它自己,也可以通过具名导出在一个文件中导出多个组件。
这里的模板是一个内联的Javascript字符串,Vue将在运行时编译它。也可以使用ID选择器来指向一个元素(通常是原生的<template>
元素),Vue将会使用其内容作为模板来源。
组件使用
要使用一个子组件,需要在父组件中导入它。假设把计数器组件放在一个叫做ButtonCounter.vue
的文件中,这个组件将会以默认导出的的形式被暴露给外部。
<script setup> |
通过<script setup>
导入的组件都可以在模板中直接使用。这称之为局部注册。
当然也可以全局注册一个组件,这样它在当前应用中的任何组件上都可以使用,而不需要额外再导入。
组件可以被重用任意多次:
<h1>Here is a child component!</h1> |
经过测试可以发现,每当点击这些按钮时,每个组件都维护着自己的状态,是不同的count
。这是因为每当使用一个组件,就创建了一个新的实例。
组件标签名注意事项⚠️
在单文件组件中,推荐为子组件使用
PascalCase
标签名,以此来区分原生HTML元素。虽然原生HTML标签名是不区分大小写的,但是Vue单文件组件是可以在编译中区分大小写的。可以使用/>
来关闭一个标签。如果是直接在DOM中书写模板,那么模板的编译需要遵从浏览器中HTML的解析行为。在这种情况下,应该使用
kebab-case
形式并显式的关闭这些组件的标签。
<!-- 如果是在 DOM 中书写该模板 --> |
组件注册
一个Vue组件在使用前需要先被注册,这样Vue才能在渲染模板时找到其对应的实现。组件注册有两种方式:全局注册和局部注册。
全局注册
可以使用Vue实例对象的.component()
方法,让组件在当前Vue应用中全局可用。
import { createApp } from 'vue' |
如果是使用单文件组件,可以注册被导入的.vue
文件:
import MyComponent from './App.vue' |
.component()
方法可以被链式调用
app |
全局注册的组件可以在此应用的任意组件的模板中使用:
<!-- 这在当前应用的任意组件中都可用 --> |
所有的子组件也可以使用全局注册的组件,这意味着这三个组件也可以在彼此内部使用。
局部注册
在使用<script setup>
的单文件组件中,导入的组件可以直接在模板中使用,无需注册:
<script setup> |
如果没有使用<script setup>
,则需要使用components
选项来显式注册:
import ComponentA from './ComponentA.js' |
对于每个components
对象里的属性,它们的Key名就是注册的朱建明,而值就是相应组件的实现。上面的例子等价于:
export default { |
注意点⚠️:局部注册的组件在后代组件中不可用。在这个例子中,
ComponentA
注册后仅在当前组件可用,而在任何的子组件或更深层的子组件中都不可用。
全局注册,局部注册的区别
- 全局注册,但并没有被使用的组件无法在生产打包时被自动移除(也叫”tree-shaking”)。如果全局注册了一个组件,即使它没有被实际使用,它仍然会出现在打包后的js文件中。
- 全局注册在大型项目中使项目的依赖关系变得不那么明确。在父组件中使用子组件时,不太容易定位子组件的实现。和使用过多的全局变量一样,这可能会影响应用长期的可维护性。
- 局部注册的组件需要在使用它的父组件中显式导入,并且只能在该父组件中使用。这样会让组件之间的依赖关系更加明确。
- 局部注册的组件对
tree-shaking
更加友好。