جاوااسکریپت | JavaScript
511 subscribers
664 photos
143 videos
3 files
520 links
کانال @IR_javascript حاوی اطلاعات مفید در حوزه برنامه نویس فرانت که بصورت روزانه بروز می‌شود.
در این کانال شما به:
[1] مطالب تازه
[2] تحلیل‌های عمیق
[3] نکات آموزشی
[4] چالش
[5] ابزار و راهنمایی‌های کاربردی
دسترسی خواهید داشت.

🆔@IR_javascript
Download Telegram
گاهی اوقات هنگام نوشتن یک کامپوننت، انواع ویژگی‌ها مانند 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
متوقف کردن یک Watcher

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
در هنگام استفاده از 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
👍31