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-item
v-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-item
v-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>