Vue 3 چه تغییراتی دارد؟ این پرسشی است که هر تیمی که هنوز روی Vue 2 مانده، دیر یا زود با آن روبه‌رو می‌شود؛ پاسخ کوتاه این است که Vue 3 نه یک نسخهٔ به‌روزرسانی جزئی، بلکه بازطراحی کامل هستهٔ واکنش‌گرایی و سبک نوشتن کد است. در تجربهٔ کار روی چند پروژه که مهاجرت از Vue 2 به 3 را انجام داده‌ام، تفاوت اصلی را در سه نقطه دیدم: سبک نوشتن منطق، سرعت اجرای هسته، و اکوسیستمی که به‌سرعت حول Composition API بازسازی شد.

چرا Vue 3 این‌قدر متفاوت است؟

Vue 2 در سال ۲۰۱۶ منتشر شد و سیستم واکنش‌گرایی‌اش بر پایهٔ Object.defineProperty بنا شده بود. این روش برای مرورگرهای قدیمی مناسب بود، اما محدودیت‌های جدی داشت: نمی‌توانست تغییرات روی خصوصیات تازه‌اضافه‌شده به یک شیء را تشخیص دهد و برای هر خصوصیت، تعداد زیادی getter و setter می‌ساخت که در پروژه‌های بزرگ هزینهٔ حافظه‌ای داشت. Vue 3 این پایه را به کل عوض کرد و همین تغییر، نقطهٔ شروع همهٔ تغییرات دیگر شد.

پایان پشتیبانی رسمی از Vue 2 در ۳۱ دسامبر ۲۰۲۳ اعلام شد و از آن تاریخ به بعد، هیچ وصلهٔ امنیتی جدیدی منتشر نمی‌شود. اگر هنوز روی Vue 2 هستید، این تنها استدلال کافی برای مهاجرت است.

تغییرات Vue 3 بیشتر شبیه بازنویسی یک موتور است تا افزودن چند ویژگی جدید؛ به همین دلیل تیم‌هایی که درست مهاجرت می‌کنند، بعد از آن به‌ندرت به عقب برمی‌گردند.

بازنویسی کامل سیستم واکنش‌گرایی

Vue 3 برای واکنش‌گرایی از Proxy استفاده می‌کند. نتیجهٔ این تغییر:

  • افزودن یا حذف یک خصوصیت به یک شیء reactive، بدون نیاز به هیچ کار اضافه، تشخیص داده می‌شود.
  • دسترسی به ایندکس و اندازهٔ آرایه‌ها به‌صورت خودکار واکنش‌گرا است.
  • هزینهٔ حافظه در اشیاء بزرگ کاهش یافته، چون به‌جای استفاده از getter/setter برای هر کلید، تنها یک proxy ساخته می‌شود.
  • عملکرد روی داده‌های پیچیده و تودرتو بهتر شده است.

این تفاوت‌ها ممکن است در نگاه اول جزئی به‌نظر برسند، ولی در پروژه‌های واقعی — به‌خصوص وقتی با داده‌های تودرتوی پیچیده کار می‌کنید — تفاوت در عملکرد و پایداری کد کاملاً محسوس است. در نوشتن کد واکنش‌گرا هم مفاهیم بنیادی همان چیزی است که در جاوااسکریپت از صفر با آن آشنا می‌شوید؛ Vue 3 روی همان پایه بنا شده، ولی با کنترل دقیق‌تر.

Composition API در برابر Options API

شاید مشهودترین تغییر Vue 3 برای توسعه‌دهندگان، اضافه شدن Composition API باشد. در Options API، هر کامپوننت حول چند بخش بزرگ سازمان می‌یابد: data، methods، computed، watch. در پروژه‌های کوچک این سبک خوانا است، ولی در کامپوننت‌های بزرگ که چند منطق مختلف دارند، خواننده مجبور می‌شود مدام بین این بخش‌ها بپرد.

Composition API اجازه می‌دهد منطق مربوط به یک موضوع را در یک تابع بازاستفاده‌پذیر جمع کنید:

import { ref, computed } from "vue";

export function useCart() {
  const items = ref([]);
  const total = computed(() =>
    items.value.reduce((sum, item) => sum + item.price * item.qty, 0)
  );
  function add(item) {
    items.value.push(item);
  }
  return { items, total, add };
}

این الگو، الهام‌بخش چیزی است که در React به آن hooks می‌گویند. تفاوت مهم این است که در Vue، Composition API به‌صورت پیش‌فرض روی سیستم واکنش‌گرایی داخلی بنا شده و نیازی به قواعد خاصی مانند «قاعدهٔ هوک‌ها» ندارد. اگر پیش از این با فریم‌ورک‌های دیگر کار کرده‌اید، مقایسهٔ کلی در «فرانت‌اند چیست و چگونه کار می‌کند» به شما تصویر دقیق‌تری می‌دهد.

معیارOptions APIComposition API
سادگی برای مبتدیبالامتوسط
خوانایی در کامپوننت‌های بزرگپایینبالا
بازاستفادهٔ منطقمحدود (mixins)عالی (composables)
پشتیبانی از TypeScriptضعیفقوی

تغییرات قالب و Fragmentها

در Vue 2، هر کامپوننت باید دقیقاً یک ریشه در قالب خود داشت. Vue 3 این محدودیت را برداشت و امکان استفاده از چند ریشه (multiple root nodes) را فراهم کرد. این تغییر ساده، جلوی بسیاری از wrapping divهای اضافی را می‌گیرد که هم DOM را پیچیده می‌کردند و هم روی برخی چیدمان‌های CSS اثر می‌گذاشتند.

همچنین در Vue 3 دایرکتیو v-model روی کامپوننت‌ها منعطف‌تر شده و اجازه می‌دهد چند v-model هم‌زمان داشته باشید، همراه با نام‌های سفارشی. این تغییر برای کسانی که روی کامپوننت‌های پیچیدهٔ فرم کار می‌کنند، بسیار کاربردی است.

تغییرات v-model و کاستوم دایرکتیوها

API کاستوم دایرکتیوها نیز در Vue 3 تغییر کرده است. اگر در Vue 2 به‌جای bind و inserted از mounted و beforeMount استفاده می‌شد، در Vue 3 نام‌گذاری یکنواخت‌تر شده و با چرخهٔ عمر کامپوننت هم‌راستا شده است. این هم‌راستایی، تشخیص ترتیب اجرا را ساده‌تر می‌کند.

پیش از مهاجرت، بررسی کنید کدام کاستوم دایرکتیوها در پروژه‌تان استفاده می‌شود. برخی نام‌های قدیمی در نسخهٔ جدید هشدار deprecation می‌دهند و بهتر است همان ابتدا اصلاح شوند.

سرعت و اندازه بسته در Vue 3

Vue 3 بازنویسی کامپایلر و زمان اجرا را تجربه کرد که نتیجه‌اش چندین بهبود قابل‌اندازه‌گیری است:

  • اندازهٔ بستهٔ runtime در نسخهٔ ۳ (core) حدود یک‌سوم نسخهٔ ۲ است؛ در برخی بسته‌بندی‌ها حتی کوچک‌تر.
  • رندر اولیه و به‌روزرسانی‌ها معمولاً سریع‌تر از نسخهٔ قبل اجرا می‌شوند.
  • با ابزار Shaking Tree و کامپایلر AOT، حجم بستهٔ نهایی برای اپلیکیشن‌های بزرگ کاهش می‌یابد.
  • حافظهٔ مصرفی در رندر لیست‌های بزرگ کاهش پیدا کرده است.

این تغییرات در سایت‌های پربازدید اهمیت زیادی دارند. اگر با مباحث Core Web Vitals و بهینه‌سازی سرعت هم درگیر هستید، نقش فریم‌ورک در عملکرد نهایی را در «پیدا کردن خطاهای جاوااسکریپت در کنسول مرورگر» و مقالات سرعت، بخشی از تصویر می‌بینید.

در مقایسهٔ عملکرد Vue 2 و Vue 3، بزرگ‌ترین برد نه در بنچمارک‌های خام بلکه در رفتار طبیعی برنامه‌های بزرگ نمود پیدا می‌کند.

پشتیبانی از TypeScript و وضعیت رسمی آن

Vue 3 از ابتدا با TypeScript نوشته شده است. این تصمیم معماری، نتیجه‌اش این است که اگر امروز با تایپ‌اسکریپت از صفر کار کنید، تجربهٔ توسعه در Vue 3 به‌مراتب بهتر از Vue 2 است. تعریف props، رویدادها، اسلات‌ها و رفرنس‌ها همگی با تایپ دقیق قابل‌بیان است.

در اکوسیستم جانبی، Pinia (که جانشین رسمی Vuex در نسخهٔ ۳ است) از ابتدا با TypeScript هماهنگ طراحی شده. این هماهنگی، یکی از دلایلی است که تیم‌های حرفه‌ای به‌سرعت از Vue 2 جدا شده‌اند.

مهاجرت از Vue 2 به Vue 3: چه چیزی شکسته می‌شود؟

مهاجرت بی‌هزینه نیست، اما مسیر آن مستند و نسبتاً شفاف است. مهم‌ترین مواردی که در پروژه‌ها به آن‌ها برخوردم:

  1. Filters حذف شده‌اند. باید با computed properties یا متدها جایگزین شوند.
  2. API رویدادها تغییر کرده. برای emit کردن رویداد، به‌جای $emit در بعضی زمینه‌ها باید از options صریح استفاده کنید.
  3. حذف $on، $off و $once. این متدها به‌نفع روش‌های استاندارد event bus جایگزین شده‌اند.
  4. تغییرات در slots. syntax slot-scope به v-slot تغییر یافته است.
  5. تغییر ترتیب hooks. برخی از hooks قدیمی حذف یا ادغام شده‌اند.
  6. حذف پشتیبانی از برخی سینتکس‌های قدیمی. تعدادی از آن‌ها به افزونهٔ جانبی یا بازنویسی نیاز دارند.

ابزار رسمی @vue/compat برای مهاجرت تدریجی طراحی شده است. همچنین مستندات رسمی Vue یک راهنمای گام‌به‌گام بسیار کامل دارند. اگر پروژهٔ بزرگی دارید، پیشنهاد می‌کنم ابتدا با یک زیربخش کوچک شروع کنید، مهاجرت را روی آن بیازمایید و بعد بقیهٔ کد را مرحله‌به‌مرحله منتقل کنید. الگوی مشابهی در مهاجرت‌های سخت‌افزاری و سینتکسی سایر زبان‌ها هم دیده می‌شود — مثلاً در مهاجرت‌های نسخه‌ای که در «گیت از صفر» یا «داکر با مثال‌های واقعی» توضیح داده‌ام، انضباط گام‌به‌گام همه‌چیز را نجات می‌دهد.

پرسش‌های پرتکرار درباره Vue 3

آیا Vue 3 را باید از ابتدا یاد بگیرم یا از Vue 2 شروع کنم؟ مستقیماً Vue 3. نسخهٔ ۲ دیگر پشتیبانی نمی‌شود و بسیاری از منابع آموزشی جدید هم فقط Vue 3 را پوشش می‌دهند. اگر تازه شروع می‌کنید، «Vue.js برای مبتدیان» مسیر را از ابتدا تا انتها پوشش می‌دهد.

آیا Composition API جایگزین Options API شده است؟ نه به‌معنای حذف. Options API در Vue 3 کاملاً معتبر است و برای پروژه‌های کوچک همچنان گزینهٔ خوبی است. اما در پروژه‌های بزرگ و در کتابخانه‌ها، Composition API سبک توصیه‌شده است.

آیا Vue 3 روی IE11 اجرا می‌شود؟ به‌طور رسمی نه. Vue 3 برای استفاده از Proxy طراحی شده که در IE11 وجود ندارد. اگر پشتیبانی از مرورگرهای قدیمی حیاتی است، باید از نسخهٔ سازگار استفاده کنید یا از فریم‌ورک دیگری استفاده کنید.

تفاوت اصلی Vue 3 با Vue 2 در چه سطحی است؟ در سه لایه: هستهٔ واکنش‌گرایی (از defineProperty به Proxy)، API نوشتن کامپوننت (اضافه شدن Composition)، و ابزارها (Vite، Pinia). تغییرات سطح قالب هم بخشی از تصویر است، ولی ثانویه محسوب می‌شود.

با Vue 3 می‌توان سایت واقعی ساخت؟ بله، و نه فقط سایت؛ Nuxt 3 به‌عنوان چارچوب متا مبتنی بر Vue 3 برای ساخت اپلیکیشن‌های SSR و SSG استفاده می‌شود. اگرچه Nuxt خارج از این مقاله است، بدانید که اکوسیستم Vue 3 کاملاً بالغ شده است.

چرا در Vue 3 از ref در کنار reactive استفاده می‌کنیم؟ چون این دو مکمل هم هستند. ref برای مقادیر اولیه‌ای (primitive) که می‌خواهیم واکنش‌گرا شوند، و reactive برای اشیائی که می‌خواهیم proxy واکنش‌گرا داشته باشند. خطا در انتخاب یکی از این دو، منبع بسیاری از باگ‌ها در پروژه‌های تازه‌مهاجرت‌کرده است.

تکلیف نهایی: مهاجرت کنید یا نه

پاسخ صریح من به این سؤال: اگر امروز روی Vue 2 هستید، بهتر است هرچه سریع‌تر نقشهٔ مهاجرت را بریزید. نه به این دلیل که Vue 2 به‌صورت لحظه‌ای می‌شکند، بلکه به این دلیل که هر ماه تأخیر، ریسک امنیتی و هزینهٔ آینده را بیشتر می‌کند. سه شرط زیر را در نظر بگیرید:

  1. اگر پروژه‌تان هنوز در مراحل اولیه است و کد کمی دارید، مهاجرت را الان انجام دهید؛ هزینهٔ آن نزدیک به صفر است.
  2. اگر پروژهٔ بزرگ با کد قدیمی دارید، از ابزار @vue/compat استفاده کنید و به‌شکل مرحله‌ای مهاجرت کنید.
  3. اگر پروژه در حالت انجماد است (یعنی دیگر توسعه نمی‌یابد و فقط باید کار کند)، نگه داشتن Vue 2 با ریسک امنیتی و در صورت امکان مهاجرت در فصل‌های خلوت توصیه می‌شود.

تفاوت Vue 3 با نسخهٔ قبل تنها در چند ویژگی جدید نیست؛ در فلسفهٔ معماری فریم‌ورک است. هر ساعت کار روی مهاجرت، با ساعت‌ها نگهداری ساده‌تر در سال‌های بعد بازمی‌گردد. اگر تجربهٔ مهاجرتی دارید — چه سریع، چه دردناک — برایم بنویسید دقیقاً کدام بخش بیشترین وقت شما را گرفت؛ همان نقطه، تجربهٔ ارزشمندی برای تیم‌های بعدی خواهد بود.