Computed Properties
Basic Example
ইন-টেমপ্লেট এক্সপ্রেশনগুলি খুব সুবিধাজনক, তবে সেগুলি সাধারণ ক্রিয়াকলাপের জন্য তৈরি৷ আপনার টেমপ্লেটগুলিতে অত্যধিক যুক্তি রাখলে সেগুলি ফুলে উঠতে পারে এবং বজায় রাখা কঠিন হতে পারে। উদাহরণস্বরূপ, যদি আমাদের একটি নেস্টেড অ্যারে সহ একটি অবজেক্ট থাকে:
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। সাধারণ রেফের মতো, আপনি গণনা করা ফলাফলটি publishedBooksMessage.value
হিসাবে অ্যাক্সেস করতে পারেন। কম্পিউটেড রেফগুলিও টেমপ্লেটগুলিতে স্বয়ংক্রিয়ভাবে আনর্যাপ করা হয় যাতে আপনি টেমপ্লেট এক্সপ্রেশনে .value
ছাড়াই তাদের উল্লেখ করতে পারেন।
একটি গণনাকৃত কম্পিউটেড প্রপার্টি স্বয়ংক্রিয়ভাবে তার প্রতিক্রিয়াশীল নির্ভরতা ট্র্যাক করে। Vue সচেতন যে publishedBooksMessage
-এর গণনা author.books
-এর উপর নির্ভর করে, তাই যখন author.books
পরিবর্তিত হয় তখন publishedBooksMessage
-এর উপর নির্ভর করে এমন কোনো বাঁধাই আপডেট করবে।
See also: Typing Computed
Computed Caching vs. Methods
আপনি হয়তো লক্ষ্য করেছেন যে আমরা অভিব্যক্তিতে একটি পদ্ধতি ব্যবহার করে একই ফলাফল অর্জন করতে পারি:
template
<p>{{ calculateBooksMessage() }}</p>
js
// in component
function calculateBooksMessage() {
return author.books.length > 0 ? 'Yes' : 'No'
}
একটি গণনাকৃত কম্পিউটেড প্রপার্টির পরিবর্তে, আমরা একটি পদ্ধতি হিসাবে একই ফাংশন সংজ্ঞায়িত করতে পারি। শেষ ফলাফলের জন্য, দুটি পন্থা আসলেই ঠিক একই। যাইহোক, পার্থক্য হল গণনা করা বৈশিষ্ট্যগুলি তাদের প্রতিক্রিয়াশীল নির্ভরতার উপর ভিত্তি করে ক্যাশে করা হয়। একটি গণনা করা কম্পিউটেড প্রপার্টি শুধুমাত্র তখনই পুনরায় মূল্যায়ন করবে যখন এর কিছু প্রতিক্রিয়াশীল নির্ভরতা পরিবর্তিত হয়। এর মানে যতক্ষণ author.books
পরিবর্তিত না হয়, publishedBooksMessage
-এ একাধিক অ্যাক্সেস অবিলম্বে পূর্বে গণনা করা ফলাফল আবার গেটার ফাংশন চালানো ছাড়াই ফিরিয়ে দিবে।
এর মানে হল নিম্নলিখিত গণনা করা কম্পিউটেড প্রপার্টি কখনই আপডেট হবে না, কারণ Date.now()
একটি প্রতিক্রিয়াশীল নির্ভরতা নয়:
js
const now = computed(() => Date.now())
তুলনামূলকভাবে, যখনই রি-রেন্ডার হবে তখন একটি পদ্ধতি আহ্বান সর্বদা ফাংশনটি চালাবে।
কেন আমরা ক্যাশিং প্রয়োজন? কল্পনা করুন আমাদের একটি ব্যয়বহুল গণনাকৃত কম্পিউটেড প্রপার্টি list
আছে, যার জন্য একটি বিশাল অ্যারের মাধ্যমে লুপ করা এবং প্রচুর গণনা করা প্রয়োজন। তারপরে আমাদের অন্যান্য গণনা করা বৈশিষ্ট্য থাকতে পারে যা ঘুরে list
-এর উপর নির্ভর করে। ক্যাশিং ছাড়া, আমরা প্রয়োজনের চেয়ে অনেক বেশি বার list
-এর গেটার চালাব! যে ক্ষেত্রে আপনি ক্যাশিং করতে চান না, পরিবর্তে একটি পদ্ধতি কল ব্যবহার করুন।
Writable Computed
গণনা করা বৈশিষ্ট্যগুলি ডিফল্ট গেটার-শুধুমাত্র। আপনি যদি একটি গণনা করা কম্পিউটেড প্রপার্টিতে একটি নতুন মান নির্ধারণ করার চেষ্টা করেন, আপনি একটি রানটাইম সতর্কতা পাবেন। বিরল ক্ষেত্রে যেখানে আপনার একটি "লেখাযোগ্য" গণনা করা কম্পিউটেড প্রপার্টি প্রয়োজন, আপনি একটি গেটার এবং একটি সেটার উভয় প্রদান করে একটি তৈরি করতে পারেন:
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'
চালাবেন, তখন সেটারকে ডাকা হবে এবং সেই অনুযায়ী firstName
এবং lastName
আপডেট করা হবে।
Best Practices
Getters should be side-effect free
এটা মনে রাখা গুরুত্বপূর্ণ যে কম্পিউটেড গেটার ফাংশনগুলি শুধুমাত্র বিশুদ্ধ গণনা করা উচিত এবং পার্শ্ব প্রতিক্রিয়া মুক্ত হওয়া উচিত। উদাহরণস্বরূপ, অন্য অবস্থার পরিবর্তন করবেন না, অ্যাসিঙ্ক রিকোয়েস্ট করবেন না, বা একটি গণনা করা গেটারের মধ্যে DOM-কে পরিবর্তন করবেন না! একটি গণনাকৃত সম্পত্তির কথা চিন্তা করুন যা ঘোষণামূলকভাবে বর্ণনা করে যে কীভাবে অন্যান্য মানের উপর ভিত্তি করে একটি মান অর্জন করা যায় - এর একমাত্র দায়িত্ব হওয়া উচিত কম্পিউটিং এবং যে মান ফেরত. পরবর্তীতে নির্দেশিকায় আমরা আলোচনা করব কিভাবে আমরা watchers এর সাথে রাষ্ট্রীয় পরিবর্তনের প্রতিক্রিয়ায় পার্শ্ব প্রতিক্রিয়া করতে পারি।
Avoid mutating computed value
একটি গণনাকৃত কম্পিউটেড প্রপার্টি থেকে প্রত্যাবর্তিত মানটি প্রাপ্ত অবস্থা। এটিকে একটি অস্থায়ী স্ন্যাপশট হিসাবে ভাবুন - প্রতিবার উত্স অবস্থা পরিবর্তিত হলে, একটি নতুন স্ন্যাপশট তৈরি করা হয়। এটি একটি স্ন্যাপশট পরিবর্তন করার কোন মানে হয় না, তাই একটি গণনাকৃত রিটার্ন মানকে শুধুমাত্র পঠনযোগ্য হিসাবে বিবেচনা করা উচিত এবং কখনই পরিবর্তিত করা উচিত নয় - পরিবর্তে, নতুন গণনাগুলি ট্রিগার করার জন্য এটির উপর নির্ভর করে এমন উত্স অবস্থা আপডেট করুন৷