گاهی اوقات هنگام نوشتن یک کامپوننت، انواع ویژگیها مانند
### دقیقاً چه اتفاقی میافتد؟
Vue تمامی ویژگیهایی را که صراحتاً بهعنوان props تعریف نکردهاید**، جمعآوری کرده و آنها را روی **المان ریشهای (Root Element) کامپوننت شما قرار میدهد.
#### مثال:
و درون
در این صورت، ویژگیهای
ساده و کاربردی، نه؟
---
### اگر از ساختار سفارشی استفاده کرده باشم چه میشود؟
اگر نخواهید Vue بهطور خودکار این ویژگیها را به هر جایی منتقل کند و ترجیح دهید خودتان تعیین کنید این ویژگیها به کدام عنصر بروند**، در این صورت میتوانید از `v-bind="$attrs"` استفاده کنید.
#### نمونه:
در اینجا فقط دکمه دوم ویژگیهایی مثل `id` و `class` را دریافت میکند.
---
### اگر اصلاً نخواهید Vue چیزی منتقل کند چه؟
اگر بخواهید کنترل کامل را در دست داشته باشید، میتوانید انتقال خودکار ویژگیها را غیرفعال کنید. کافیست گزینه زیر را در کامپوننتتان اضافه کنید:
در این حالت، **هیچ ویژگیای به عنصر ریشهای (div) اضافه نمیشود و تنها به دکمه منتقل خواهد شد. این کار زمانی بسیار مفید است که بخواهید استایلها یا رویدادها دقیقاً روی یک عنصر تعاملی مثل دکمه اعمال شوند.
---
### نکات مهم:
- هر چیزی که prop نباشد، در
- بهصورت پیشفرض، تمام این ویژگیها به عنصر ریشهای کامپوننت افزوده میشوند.
- اگر میخواهید کنترل بیشتری داشته باشید، از
- میتوان
- اگر نام یک ویژگی با نام prop یکی باشد، آن ویژگی دیگر وارد
این ویژگیها به شما کمک میکنند کنترل دقیقتری بر ساختار، استایل و رفتار کامپوننتهای خود داشته باشید — خصوصاً در کامپوننتهای قابل استفاده مجدد و پیچیده.
#️⃣#tip #vue
👥@IR_javascript_group
🆔@IR_javascript
id`، `class`، `style
و یا ویژگیهایی با پیشوند data-*
را به آن ارسال میکنید، اما این ویژگیها در خروجی نهایی ناپدید میشوند. چرا؟ چون Vue بهصورت پیشفرض این ویژگیها را بهطور خودکار روی تمام المنتها اعمال نمیکند. ولی موضوع به همین سادگی هم نیست — ظرافتهایی دارد.### دقیقاً چه اتفاقی میافتد؟
Vue تمامی ویژگیهایی را که صراحتاً بهعنوان props تعریف نکردهاید**، جمعآوری کرده و آنها را روی **المان ریشهای (Root Element) کامپوننت شما قرار میدهد.
#### مثال:
<MyButton class="big red" id="super-btn" />
و درون
MyButton.vue
چنین چیزی نوشتهاید:<template>
<button>کلیک کن</button>
</template>
در این صورت، ویژگیهای
class="big red"
و id="super-btn"
به دکمه اضافه میشوند. ساده و کاربردی، نه؟
---
### اگر از ساختار سفارشی استفاده کرده باشم چه میشود؟
اگر نخواهید Vue بهطور خودکار این ویژگیها را به هر جایی منتقل کند و ترجیح دهید خودتان تعیین کنید این ویژگیها به کدام عنصر بروند**، در این صورت میتوانید از `v-bind="$attrs"` استفاده کنید.
#### نمونه:
<template>
<div>
<button>دکمه شماره یک</button>
<button v-bind="$attrs">دکمه شماره دو</button>
</div>
</template>
در اینجا فقط دکمه دوم ویژگیهایی مثل `id` و `class` را دریافت میکند.
---
### اگر اصلاً نخواهید Vue چیزی منتقل کند چه؟
اگر بخواهید کنترل کامل را در دست داشته باشید، میتوانید انتقال خودکار ویژگیها را غیرفعال کنید. کافیست گزینه زیر را در کامپوننتتان اضافه کنید:
<template>
<div class="wrapper">
<button v-bind="$attrs">دکمه</button>
</div>
</template>
<script setup>
defineOptions({
inheritAttrs: false
})
</script>
در این حالت، **هیچ ویژگیای به عنصر ریشهای (div) اضافه نمیشود و تنها به دکمه منتقل خواهد شد. این کار زمانی بسیار مفید است که بخواهید استایلها یا رویدادها دقیقاً روی یک عنصر تعاملی مثل دکمه اعمال شوند.
---
### نکات مهم:
- هر چیزی که prop نباشد، در
$attrs
قرار میگیرد.- بهصورت پیشفرض، تمام این ویژگیها به عنصر ریشهای کامپوننت افزوده میشوند.
- اگر میخواهید کنترل بیشتری داشته باشید، از
inheritAttrs: false
و v-bind="$attrs"
استفاده کنید.- میتوان
$attrs
را هم در بخش setup
و هم در template
بهکار برد.- اگر نام یک ویژگی با نام prop یکی باشد، آن ویژگی دیگر وارد
$attrs
نمیشود.این ویژگیها به شما کمک میکنند کنترل دقیقتری بر ساختار، استایل و رفتار کامپوننتهای خود داشته باشید — خصوصاً در کامپوننتهای قابل استفاده مجدد و پیچیده.
#️⃣#tip #vue
👥@IR_javascript_group
🆔@IR_javascript
👍2
کتاب Chibi Vue نوشتهی یویچی کیکوچی، راهنمایی جامع و دقیق دربارهی ساختار درونی فریمورک Vue ۳ است. این کتاب بهویژه برای توسعهدهندگانی که بهصورت عمیق در حال یادگیری Vue هستند، بسیار سودمند است.
در این کتاب میخوانید:
تحلیل جامع هستهی Vue، شامل: سامانهی واکنشپذیری، کامپایلر قالبها، و سیستم رندرینگ.
پیادهسازی عملی و گامبهگام نسخهای سادهشده از Vue از ابتدا.
زبان این کتاب انگلیسی است.
🔗https://book.chibivue.land/
#️⃣#tip #vue
👥@IR_javascript_group
🆔@IR_javascript
در این کتاب میخوانید:
تحلیل جامع هستهی Vue، شامل: سامانهی واکنشپذیری، کامپایلر قالبها، و سیستم رندرینگ.
پیادهسازی عملی و گامبهگام نسخهای سادهشده از Vue از ابتدا.
زبان این کتاب انگلیسی است.
🔗https://book.chibivue.land/
#️⃣#tip #vue
👥@IR_javascript_group
🆔@IR_javascript
chibivue
Writing Vue.js: Step by Step, from just one line of "Hello, World".
متوقف کردن یک Watcher
Watcher**هایی که بهصورت همزمان (synchronous) درون تابع `setup()` یا در قالب `<script setup>` تعریف میشوند، به نمونه (instance) کامپوننت مالک وابسته هستند و بهطور خودکار هنگام **unmount شدن آن کامپوننت متوقف خواهند شد. در اغلب موارد، نیازی نیست نگران متوقف کردن دستی آنها باشید.
نکتهی کلیدی در اینجاست که Watcher باید بهصورت همزمان ایجاد شود؛ اگر Watcher در یک تابع غیرهمزمان (asynchronous) مانند
برای متوقف کردن دستی یک Watcher**، میتوان از تابع بازگشتی استفاده کرد. این روش هم برای `watch` و هم برای `watchEffect` کاربرد دارد:
توجه داشته باشید که تنها در موارد بسیار محدود نیاز به ایجاد **Watcher بهصورت غیرهمزمان وجود دارد، و در هر زمان ممکن، بهتر است از ایجاد همزمان استفاده شود.
اگر نیاز دارید منتظر دادهای غیرهمزمان بمانید، میتوانید منطق Watcher خود را مشروط طراحی کنید:
#️⃣#tip #vue
👥@IR_javascript_group
🆔@IR_javascript
Watcher**هایی که بهصورت همزمان (synchronous) درون تابع `setup()` یا در قالب `<script setup>` تعریف میشوند، به نمونه (instance) کامپوننت مالک وابسته هستند و بهطور خودکار هنگام **unmount شدن آن کامپوننت متوقف خواهند شد. در اغلب موارد، نیازی نیست نگران متوقف کردن دستی آنها باشید.
نکتهی کلیدی در اینجاست که Watcher باید بهصورت همزمان ایجاد شود؛ اگر Watcher در یک تابع غیرهمزمان (asynchronous) مانند
setTimeout
ایجاد گردد، دیگر به کامپوننت والد وابسته نخواهد بود و باید بهصورت دستی متوقف شود تا از نشت حافظه (memory leak) جلوگیری شود. به مثال زیر توجه کنید:<script setup>
import { watchEffect } from 'vue'
// این Watcher بهصورت خودکار متوقف خواهد شد
watchEffect(() => {})
// ...اما این یکی نه!
setTimeout(() => {
watchEffect(() => {})
}, ۱۰۰)
</script>
برای متوقف کردن دستی یک Watcher**، میتوان از تابع بازگشتی استفاده کرد. این روش هم برای `watch` و هم برای `watchEffect` کاربرد دارد:
const unwatch = watchEffect(() => {})
// ...در زمانی دیگر، زمانی که دیگر نیازی نیست
unwatch()
توجه داشته باشید که تنها در موارد بسیار محدود نیاز به ایجاد **Watcher بهصورت غیرهمزمان وجود دارد، و در هر زمان ممکن، بهتر است از ایجاد همزمان استفاده شود.
اگر نیاز دارید منتظر دادهای غیرهمزمان بمانید، میتوانید منطق Watcher خود را مشروط طراحی کنید:
// دادهای که بهصورت غیرهمزمان بارگذاری میشود
const data = ref(null)
watchEffect(() => {
if (data.value) {
// انجام عملیات زمانی که داده بارگذاری شد
}
})
#️⃣#tip #vue
👥@IR_javascript_group
🆔@IR_javascript
❤1👍1
در هنگام استفاده از
تنها راهحل مؤثری که تاکنون یافته شده، غیرفعال کردن این حالت (mode) در زمان توسعه است.
نمونهای از کد مربوطه:
در این وضعیت، پیشنهاد میشود برای جلوگیری از بروز مشکل، در محیط توسعه از مقدار پیشفرض
#️⃣#tip #vue
👥@IR_javascript_group
🆔@IR_javascript
router-view
همراه با transition
و تعیین `mode="out-in"`، در حالت توسعه (dev mode)، هنگام جابهجایی بین مسیرها (routes) اغلب با مشکل نمایش صفحه سفید مواجه میشویم.تنها راهحل مؤثری که تاکنون یافته شده، غیرفعال کردن این حالت (mode) در زمان توسعه است.
نمونهای از کد مربوطه:
<router-view v-slot="{ Component }">
<Transition mode="out-in">
<component :is="Component" />
</Transition>
</router-view>
در این وضعیت، پیشنهاد میشود برای جلوگیری از بروز مشکل، در محیط توسعه از مقدار پیشفرض
mode
یا از حالتهایی مانند "in-out"
یا بدون مشخصکردن mode
استفاده شود و تنها در محیط تولید (production) از حالت out-in
بهره بگیرید، چرا که این حالت در محیط توسعه ممکن است باگهایی مانند نمایش صفحه سفید موقت ایجاد کند.#️⃣#tip #vue
👥@IR_javascript_group
🆔@IR_javascript
👍3❤1