Fallthrough Attributes
این صفحه فرض میکند شما قبلاً مبانی کامپوننتها را خواندهاید. اگر با کامپوننتها آشنایی ندارید، ابتدا آن را بخوانید.
Attribute Inheritance
یک "fallthrough attribute" ویژگی یا listener رویداد v-on
است که به کامپوننت پاس داده میشود، اما به طور صریح در props یا emits تعریف نشده است. مثالهای رایج این موارد ویژگیهای class
، style
و id
هستند.
وقتی یک کامپوننت root element اصلی خود را رندر میکند، ویژگیهای fallthrough به طور خودکار به attributeهای root element اضافه میشوند. به عنوان مثال، با در نظر گرفتن یک کامپوننت <MyButton>
با تمپلیت زیر:
template
<!-- template of <MyButton> -->
<button>click me</button>
و یک والد که از این کامپوننت با این موارد استفاده میکند:
template
<MyButton class="large" />
DOM نهایی رندر شده به این صورت خواهد بود:
html
<button class="large">click me</button>
اینجا، <MyButton>
ویژگی class
را به عنوان یک prop پذیرفته شده اعلام نکرده است. بنابراین، class
به عنوان یک ویژگی fallthrough در نظر گرفته میشود و به طور خودکار به عنصر ریشه <MyButton>
اضافه میشود.
ادغام class
و style
اگر root element کامپوننت فرزند از قبل ویژگیهای class
یا style
را داشته باشد، آن با مقادیر class
و style
به ارث برده شده از والد ادغام میشود. فرض کنید تمپلیت <MyButton>
در مثال قبلی را به این صورت تغییر دهیم:
template
<!-- template of <MyButton> -->
<button class="btn">click me</button>
سپس DOM نهایی رندر شده به این صورت خواهد بود:
html
<button class="btn large">click me</button>
v-on
Listener Inheritance
همان قانون برای listenerهای رویداد v-on
اعمال میشود:
template
<MyButton @click="onClick" />
دریافتکننده رویداد click
به root element کامپوننت <MyButton>
اضافه میشود، یعنی عنصر <button>
. وقتی <button>
اصلی کلیک شود، متد onClick
از کامپوننت والد را فراخوانی میکند. اگر <button>
از قبل یک دریافتکننده رویداد click
با v-on
داشته باشد، آنگاه هر دو فراخوانی میشوند.
Nested Component Inheritance
اگر یک کامپوننت، کامپوننت دیگری را به عنوان نود ریشهاش (root node) رندر کند، به عنوان مثال، <MyButton>
را بازنویسی کردیم تا <BaseButton>
را به عنوان ریشهاش رندر کند:
template
<!-- که صرفاً یک کامپوننت دیگر را رندر میکند <MyButton/> تمپلیت -->
<BaseButton />
سپس ویژگیهای fallthrough دریافت شده توسط <MyButton>
به طور خودکار به <BaseButton>
ارسال میشوند.
توجه داشته باشید که:
ویژگیهای ارسال شده شامل هیچکدام از attributeهایی که به عنوان props تعریف شدهاند، یا listenerهای
v-on
رویدادهای تعریف شده توسط<MyButton>
نمیشوند - به عبارت دیگر، props و listenerهای تعریف شده توسط<MyButton>
"مصرف" شدهاند.ویژگیهای ارسال شده ممکن است به عنوان props توسط
<BaseButton>
پذیرفته شوند، اگر توسط آن اعلام شده باشند.
غیرفعال کردن Attribute Inheritance
اگر نمیخواهید یک کامپوننت به طور خودکار ویژگیها را به ارث ببرد، میتوانید inheritAttrs: false
را در آپشنهای کامپوننت تنظیم کنید.
از نسخه 3.3 میتوانید از defineOptions
مستقیماً در <script setup>
استفاده کنید:
vue
<script setup>
defineOptions({
inheritAttrs: false
})
// ...setup logic
</script>
سناریوی رایج برای غیرفعال کردن وراثت ویژگیها زمانی است که attributeها نیاز دارند به عناصر دیگری به غیر از نود ریشه اعمال شوند. با تنظیم گزینه inheritAttrs
بر روی false
، میتوانید کنترل کاملی بر اینکه ویژگیهای fallthrough کجا باید اعمال شوند، داشته باشید.
میتوانید به این ویژگیهای fallthrough مستقیماً در expressionهای تمپلیت به عنوان $attrs
دسترسی داشته باشید:
template
<span>Fallthrough attributes: {{ $attrs }}</span>
شی $attrs
شامل تمام ویژگیهایی است که توسط props
یا emits
کامپوننت اعلام نشدهاند (مثلا class
، style
، v-on
و غیره).
توجه داشته باشید که:
برخلاف props، ویژگیهای fallthrough حروف بزرگ و کوچک اصلی خود را در جاوااسکریپت حفظ میکنند، بنابراین یک ویژگی مثل
foo-bar
نیاز دارد که به صورت$attrs['foo-bar']
صدا زده شود.یک دریافتکننده رویداد
v-on
مثل@click
در شی به عنوان یک تابع تحت$attrs.onClick
در دسترس است.
با استفاده از مثال کامپوننت <MyButton>
از بخش قبلی - گاهی اوقات ممکن است نیاز داشته باشیم <button>
واقعی را درون یک <div>
اضافی برای اهداف استایلی قرار دهیم:
template
<div class="btn-wrapper">
<button class="btn">click me</button>
</div>
میخواهیم تمام ویژگیهای fallthrough مثل class
و listenerهای v-on
به <button>
داخلی اعمال شوند، نه <div>
بیرونی. میتوانیم با استفاده از inheritAttrs: false
و v-bind="$attrs"
این کار را انجام دهیم:
template
<div class="btn-wrapper">
<button class="btn" v-bind="$attrs">click me</button>
</div>
به یاد داشته باشید که v-bind بدون آرگومان تمام پراپرتیهای یک شی را به عنوان attributeهای عنصر هدف متصل میکند.
Attribute Inheritance on Multiple Root Nodes
برخلاف کامپوننتهایی با یک root node، کامپوننتهایی با چندین root node رفتار خودکار اتصال attributeها را ندارند. اگر $attrs
به طور صریح اتصال داده نشده باشد، یک هشدار زمان اجرا صادر میشود.
template
<CustomLayout id="custom-layout" @click="changeValue" />
اگر <CustomLayout>
تمپلیت چند ریشهای زیر را داشته باشد، به دلیل اینکه Vue نمیتواند مطمئن باشد که ویژگیها را کجا اعمال کند، هشداری نمایش داده میشود:
template
<header>...</header>
<main>...</main>
<footer>...</footer>
هشدار سرکوب میشود اگر $attrs
به طور صریح متصل شود:
template
<header>...</header>
<main v-bind="$attrs">...</main>
<footer>...</footer>
دسترسی به Fallthrough Attributes در جاوااسکریپت
اگر نیاز باشد، میتوانید در <script setup>
با استفاده از API تعریف شده useAttrs()
به ویژگیهای fallthrough یک کامپوننت دسترسی پیدا کنید:
vue
<script setup>
import { useAttrs } from 'vue'
const attrs = useAttrs()
</script>
اگر از <script setup>
استفاده نمیکنید، attrs
به عنوان یک خاصیت از context در setup()
در دسترس خواهد بود:
js
export default {
setup(props, ctx) {
// در دسترس هستند ctx.attrs به عنوان fallthrough ویژگیهای
console.log(ctx.attrs)
}
}
توجه داشته باشید اگرچه شی attrs
اینجا همیشه آخرین fallthrough attributes را منعکس میکند، واکنشگرا نیست (به دلایل عملکردی). نمیتوانید از watcherها برای مشاهده تغییرات آن استفاده کنید. اگر به واکنشگرایی نیاز دارید، از یک prop استفاده کنید. به عنوان جایگزین، میتوانید از onUpdated()
برای افکت جانبی با آخرین attrs
در هر بهروزرسانی استفاده کنید.