Vue3新体验

组件name

当你在使用单文件组件时,组件已经会根据其文件名推导出其名称。举例来说,一个名为 MyComponent.vue 的文件会推导出显示名称为“MyComponent”。

另一种场景是当一个组件通过 app.component 被全局注册时,这个全局 ID 就自动被设为了其名称。

使用 name 选项使你可以覆盖推导出的名称,或是在没有推导出名字时显式提供一个。(例如没有使用构建工具时,或是一个内联的非 SFC 式的组件)

有一种场景下 name 必须是已显式声明的:即 通过其 include / exclude prop 来匹配其需要缓存的组件时。

在 3.2.34 或以上的版本中,使用 <script setup> `的单文件组件会自动根据文件名生成对应的 name 选项,即使是在配合 `<KeepAlive> 使用时也无需再手动声明。

暴露公共属性

expose 函数用于显式地限制该组件暴露出的属性,当父组件通过模板引用访问该组件的实例时,将仅能访问expose函数暴露出的内容:

export default {
  setup(props, { expose }) {
    // 让组件实例处于 “关闭状态”
    // 即不向父组件暴露任何东西
    expose()

    const publicCount = ref(0)
    const privateCount = ref(0)
    // 有选择地暴露局部状态
    expose({ count: publicCount })
  }
}

script setup

要启用该语法,需要在 <script> 代码块上添加 setup attribute:

<script setup>
console.log('hello script setup')
</script>

当使用 <script setup> `的时候,任何在 `<script setup> 声明的顶层的绑定 (包括变量,函数声明,以及 import 导入的内容) 都能在模板中直接使用。import 导入的内容也会以同样的方式暴露。这意味着我们可以在模板表达式中直接使用导入的 helper 函数,而不需要通过 methods 选项来暴露它:

<script setup>
import { capitalize } from './helpers'
</script>

<template>
  <div>{{ capitalize('hello') }}</div>
</template>

单文件组件CSS

深度选择器

处于 scoped 样式中的选择器如果想要做更“深度”的选择,也即:影响到子组件,可以使用 :deep() 这个伪类:

<style scoped>
.a :deep(.b) {
  /* ... */
}
</style>

代码会被编译成:

.a[data-v-f3f3eg9] .b {
  /* ... */
}

通过 v-html 创建的 DOM 内容不会被作用域样式影响,但仍然可以使用深度选择器来设置其样式。

插槽选择器

默认情况下,作用域样式不会影响到 <slot/> 渲染出来的内容,因为它们被认为是父组件所持有并传递进来的。使用 :slotted 伪类以明确地将插槽内容作为选择器的目标:

<style scoped>
:slotted(div) {
  color: red;
}
</style>

全局选择器

如果想让其中一个样式规则应用到全局,比起另外创建一个 <style>,可以使用 :global 伪类来实现 (看下面的代码):

<style scoped>
:global(.red) {
  color: red;
}
</style>

CSS Modules

一个 <style module> 标签会被编译为 CSS Modules 并且将生成的 CSS class 作为 $style 对象暴露给组件:

<template>
  <p :class="$style.red">This should be red</p>
</template>

<style module>
.red {
  color: red;
}
</style>