ویژگی های کامپیوتد
مثال پایه
عباراتی که در تمپلیت استفاده می شوند بسیار راحت هستند، اما برای عملیاتهای ساده طراحی شدهاند. قرار دادن منطق بیش از حد در قالبهای شما ممکن است باعث ناخوانی و دشواری در نگهداری کد ها شود. به عنوان مثال، اگر یک شیء با یک آرایه تو در تو داشته باشیم:
js
const author = reactive({
name: 'John Doe',
books: [
'Vue 2 - Advanced Guide',
'Vue 3 - Basic Guide',
'Vue 4 - The Mystery'
]
})
و میخواهیم پیامهای مختلفی را بر اساس اینکه آیا author
قبلاً کتابی داشته یا نه نمایش دهیم:
template
<p>Has published books:</p>
<span>{{ author.books.length > 0 ? 'Yes' : 'No' }}</span>
در این نقطه، قالب کمی پیچیده شده است.باید وقت بیشتری برای درک کد صرف کنیم که متوجه شویم شرط بر اساس author.books
یک محاسبه انجام میدهد. مهمتر از این، اگر نیاز باشد که این محاسبه را بیش از یک بار در قالب استفاده کنیم، احتمالاً نمی خواهیم یک کد را چندین بار بنویسیم.
به همین دلیل است که وقتی منطق پیچیده و دادههای داینامیک داریم ، استفاده از ویژگی کامپیوتد توصیه میشود. در اینجا همان مثال، بازسازی شده است:
vue
<script setup>
import { reactive, computed } from 'vue'
const author = reactive({
name: 'John Doe',
books: [
'Vue 2 - Advanced Guide',
'Vue 3 - Basic Guide',
'Vue 4 - The Mystery'
]
})
// a computed ref
const publishedBooksMessage = computed(() => {
return author.books.length > 0 ? 'Yes' : 'No'
})
</script>
<template>
<p>Has published books:</p>
<span>{{ publishedBooksMessage }}</span>
</template>
در اینجا یک ویژگی کامپیوتد به نام publishedBooksMessage
تعریف کردهایم. تابع computed()
انتظار دارد که یک تابع گرفته که مقدار بازگشتی آن از نوع computed ref باشد. مشابه ref های عادی، شما میتوانید به نتیجه محاسبه شده با عنوان publishedBooksMessage.value
دسترسی پیدا کنید. Computed ref ها همچنین در قالبها به صورت خودکار از حالت بسته خارج میشوند، بنابراین میتوانید بدون نیاز به .value
به آنها دسترسی پیدا کنید.
یک ویژگی کامپیوتد به طور خودکار وابستگیهای متغیر خود را دنبال میکند. Vue میداند که محاسبه publishedBooksMessage
به author.books
وابستگی دارد، بنابراین هنگامی که author.books
تغییر میکند، هر اتصالی که به publishedBooksMessage
وابسته باشد، بهروزرسانی میشود.
همچنین ببینید: Typing Computed
تفاوت کشینگ در کامپیوتد ها و متد ها
ممکن است متوجه شده باشید که میتوانیم با فراخوانی یک متد هم به همان نتیجه برسیم.
template
<p>{{ calculateBooksMessage() }}</p>
js
// in component
function calculateBooksMessage() {
return author.books.length > 0 ? 'Yes' : 'No'
}
به جای یک ویژگی کامپیوتد، می توانیم همان تابع را به عنوان یک متد تعریف کنیم. نتیجه نهایی این دو رویکرد دقیقاً یکسان است. با این حال، تفاوت این است که ویژگی های کامپیوتد بر اساس وابستگی های متغیر، کش می شوند. یک ویژگی کامپیوتد تنها زمانی دوباره ارزیابی می شود که برخی از وابستگی های متغیر آن تغییر کرده باشند. این بدان معناست که تا زمانی که author.books
تغییر نکرده باشد، دسترسی به publishedBooksMessage
نتیجه کامپیوتد قبلی را برمی گرداند ، بدون نیاز به اجرای مجدد تابع getter .
این به این معناهم هست که ویژگی محاسبهشده زیر هیچ وقت بهروز نمیشود، زیرا Date.now()
یک وابستگی متغیر نمیباشد.
js
const now = computed(() => Date.now())
در مقایسه با ویژگیهای کامپیوتد، فراخوانی متدها همیشه باعث اجرای تابع مربوطه میشود، حتی اگر هیچ یک از ویژگیهای وابسته تغییر نکرده باشند.
چرا به کش نیاز داریم؟ تصور کنید ما یک لیست داریم که یک ویژگی کامپیوتد دارد که نیاز به انجام محاسبات زیادی دارد. سپس ممکن است ویژگیهای کامپیوتد دیگری داشته باشیم که به نوبه خود به این لیست وابسته باشند. بدون کش، ما تابع دریافت کننده لیست را بیشتر از تعداد مورد نیاز اجرا میکنیم! در مواردی که نیاز به کش ندارید، به جای آن از فراخوانی متد استفاده کنید.
کامپیوتد قابل تغییر
ویژگیهای کامپیوتد به طور پیشفرض فقط امکان دریافت مقدار را دارند. اگر سعی کنید مقدار جدیدی به یک ویژگی کامپیوتد اختصاص دهید، یک هشدار در زمان اجرا دریافت خواهید کرد. در موارد نادری که نیاز به "ویژگی کامپیوتد قابل تغییر" دارید، میتوانید با ارائه همزمان یک تابع getter و یک تابع setter برای آن ، یکی ایجاد کنید.
vue
<script setup>
import { ref, computed } from 'vue'
const firstName = ref('John')
const lastName = ref('Doe')
const fullName = computed({
// getter
get() {
return firstName.value + ' ' + lastName.value
},
// setter
set(newValue) {
// Note: we are using destructuring assignment syntax here.
[firstName.value, lastName.value] = newValue.split(' ')
}
})
</script>
وقتی شما دستور fullName.value = 'John Doe'
را اجرا کنید، تابع setter فراخوانی خواهد شد و firstName
و lastName
بهطور متناسب بهروزرسانی می شوند.
بهترین روش ها
توابع getter باید فقط مقدار مورد نظر را برگردانند و تغییر دیگری در برنامه ایجاد نکنند.
مهم است به یاد داشته باشید که توابع getter کامپیوتد فقط باید محاسبات خالص را انجام دهند . به عبارت دیگر، درون تابع getter ، از درخواستهای async یا تغییر DOM استفاده نکنید! به ویژگی کامپیوتد به عنوان یک راه ساده برای محاسبه یک مقدار بر اساس مقادیر دیگر نگاه کنید - مسئولیت اصلی آن تنها محاسبه و بازگرداندن آن مقدار میباشد. در ادامه این بخش، به بحث در مورد انجام عملیات هایی در پاسخ به تغییرات state با ناظر ها خواهیم پرداخت.
مقادیر کامپیوتد را تغییر ندهید
مقدار بازگشتی از ویژگی کامپیوتد بر اساس مقادیر دیگر محاسبه میشود. این مقدار مانند یک عکس است که هر بار که وابستگیهای آن تغییر کنند، بهروز میشود. از آنجا که تغییر دادن عکسها منطقی نیست، مقدار بازگشتی باید فقط خوانده شود و روی آن عملیاتی انجام نشود. برای تغییر مقدار بازگشتی، باید متغیری که ویژگی کامپیوتد به آن وابسته است را بهروز کنید.