定义一个组件
单文件组件 (简称 SFC):
使用组件
组件可以被重用任意多次:
会注意到,每当点击这些按钮时,每一个组件都维护着自己的状态,是不同的 count
。因为使用一个组件,就创建了一个新的实例。
在单文件组件中,推荐为子组件使用 PascalCase
的标签名,
如果你是直接在 DOM 中书写模板 (例如原生 <template>
元素的内容),模板的编译需要遵从浏览器中 HTML 的解析行为。需要使用 kebab-case
形式并显式地关闭这些组件的标签。
传递 props
Props 是一种特别的 attributes,你可以在组件上声明注册。要传递给博客文章组件一个标题,我们必须在组件的 props 列表上声明它。这里要用到 defineProps 宏:
defineProps
是一个仅 <script setup>
中可用的编译宏命令,并不需要显式地导入。声明的 props 会自动暴露给模板。defineProps
会返回一个对象,其中包含了可以传递给组件的所有 props:
没有使用 <script setup>
,props 必须以 props
选项的方式声明,props 对象会作为 setup()
函数的第一个参数被传入:
一个组件可以有任意多的 props,默认情况下,所有 prop 都接受任意类型的值。
在实际应用中,我们可能在父组件中会有如下的一个博客文章数组:
可以使用 v-for
来渲染它们:
如下图:
或者这样:
这是没有用defineprops的用的原先的props
监听事件
发现有时候需要与父组件进行交互。例如,要在此处实现 A11y 的需求,将博客文章的文字能够放大,而页面的其余部分仍使用默认字号。
在父组件中,添加一个 postFontSize
ref ,用它来控制所有博客文章的字体大小。给子组件添加按钮,想要点击这个按钮来告诉父组件它应该放大所有博客文章的文字。父组件,提供了一个自定义事件系统。
子组件可以通过调用内置的 $emit 方法,通过传入事件名称来抛出一个事件:
通过 defineEmits 宏来声明需要抛出的事件:
和 defineProps
类似,defineEmits
仅可用于 <script setup>
之中,并且不需要导入,它返回一个等同于 $emit
方法的 emit
函数。它可以被用于在组件的 <script setup>
中抛出事件,因为此处无法直接访问 $emit
:
如果你没有在使用 <script setup>
,你可以通过 emits
选项定义组件会抛出的事件。你可以从 setup()
函数的第二个参数,即 setup 上下文对象上访问到 emit
函数:
通过插槽来分配内容
可以通过 Vue 的自定义 <slot>
元素来实现
app.vue
AlertBox.vue ,<slot>就是插槽语句所放的位置
动态组件
有些场景会需要在两个组件间来回切换,比如 Tab 界面:
通过 Vue 的 <component>
元素和特殊的 is
attribute 实现的:
被传给 :is
的值可以是以下几种:
- 被注册的组件名
- 导入的组件对象
当使用 <component :is="...">
来在多个组件间作切换时,被切换掉的组件会被卸载。我们可以通过 <KeepAlive> 组件强制被切换掉的组件仍然保持“存活”的状态。
DOM 模板解析注意事项 (脑壳大)