Vue 穿透属性(Fallthrough )
可以使用未声明为 props 的属性来调用组件,这些属性将 穿透(fall through) 到组件中的根元素。
使用穿透属性,您可以从创建组件的父级获得更多属性,并且它简化了我们的代码,因为我们不需要将属性声明为 props。
用于穿透的典型属性是 class, style 和 v-on。
穿透属性
例如,从父级控制组件样式可能很好,而不是将样式隐藏在组件内部。
让我们创建一个新的例子,Vue 中的基本 todo 列表,看看 style 属性是如何穿透到目标组件的。
So, our App.vue should contain the list of things to do, and an <input> element and a <button> to add new things to do. Each list item is a <todo-item /> component.
因此,我们的 App.vue 应该包含要做的事情的列表,以及一个 <input> 元素和一个 <button> 来添加要做的新事情。每个列表项都是一个 <todo-item /> 组件。
App.vue:
<template><h3>Todo List</h3><ul><todo-itemv-for="x in items":key="x":item-name="x"></todo></ul><input v-model="newItem"><button @click="addItem">Add</button></template><script>export default {data() {return {newItem: '',items: ['Buy apples','Make pizza','Mow the lawn']};},methods: {addItem() {this.items.push(this.newItem),this.newItem = '';}}}</script>
TodoItem.vue 刚刚收到了作为 prop 该做什么的描述:
TodoItem.vue:
<template><li>{{ itemName }}</li></template><script>export default {props: ['itemName']}</script>
为了正确构建我们的应用程序,我们还需要在 main.js 中进行正确的设置:
main.js:
import { createApp } from 'vue'import App from './App.vue'import TodoItem from './components/TodoItem.vue'const app = createApp(App)app.component('todo-item', TodoItem)app.mount('#app')
为了了解本节的要点,即属性可以延伸到组件的 <template> 中的根元素,我们可以从 App.vue 中为列表项提供一些样式:
实例
我们从 App.vue 中为组件内部的 <li> 元素提供样式:
<template><h3>Todo List</h3><ul><todo-itemv-for="x in items":key="x":item-name="x"style="background-color: lightgreen;"/></ul><input v-model="newItem"><button @click="addItem">Add</button></template>
要确认样式属性实际上已经失败,我们可以右键单击浏览器中 todo 列表中的 <li> 元素,选择 'Inspect',我们可以看到样式属性现在位于 <li> 元素上:

合并 'class' 和 'style' 属性
如果已经设置了 'class' 或 'style' 属性,并且 'class' 或 'style' 属性也作为穿透属性来自父级,则这些属性将被合并。
实例
除了来自父级的现有样式外,我们还在 TodoItem.vue 组件内的 <li> 元素中添加了一个边距:
<template><li style="margin: 5px 0;">{{ itemName }}</li></template><script>export default {props: ['itemName']}</script>
如果我们右键单击浏览器中的 <li> 元素,我们可以看到属性已经合并。边距直接设置在组件内部的 <li> 元素上,并与从父元素穿过的背景颜色合并:

$attrs
如果我们在组件的根级别上有多个元素,那么就不再清楚属性应该属于哪个元素。
为了定义哪一个根元素获得穿透属性,我们可以用内置的 $attrs 对象标记该元素,如下所示:
实例
TodoItem.vue:
<template><div class="pinkBall"></div><li v-bind="$attrs">{{ itemName }}</li><div class="pinkBall"></div></template>