List Rendering
v-for
অ্যারের উপর ভিত্তি করে আইটেমগুলির একটি তালিকা রেন্ডার করতে আমরা v-for
নির্দেশিকা ব্যবহার করতে পারি। v-for
নির্দেশের জন্য item in items
আকারে একটি বিশেষ সিনট্যাক্স প্রয়োজন, যেখানে items
হল উৎস ডেটা অ্যারে এবং item
হল একটি alias যে অ্যারে কম্পোনেন্টটির উপর পুনরাবৃত্তি করা হচ্ছে:
js
const items = ref([{ message: 'Foo' }, { message: 'Bar' }])
template
<li v-for="item in items">
{{ item.message }}
</li>
v-for
স্কোপের ভিতরে, টেমপ্লেট এক্সপ্রেশনের সমস্ত প্যারেন্ট স্কোপের বৈশিষ্ট্যগুলিতে অ্যাক্সেস রয়েছে। উপরন্তু, v-for
বর্তমান আইটেমের সূচীর জন্য একটি ঐচ্ছিক দ্বিতীয় উপনাম সমর্থন করে:
js
const parentMessage = ref('Parent')
const items = ref([{ message: 'Foo' }, { message: 'Bar' }])
template
<li v-for="(item, index) in items">
{{ parentMessage }} - {{ index }} - {{ item.message }}
</li>
v-for
এর পরিবর্তনশীল স্কোপিং নিম্নলিখিত জাভাস্ক্রিপ্টের অনুরূপ:
js
const parentMessage = 'Parent'
const items = [
/* ... */
]
items.forEach((item, index) => {
// has access to outer scope `parentMessage`
// but `item` and `index` are only available in here
console.log(parentMessage, item.message, index)
})
লক্ষ্য করুন কিভাবে v-for
মান forEach
কলব্যাকের ফাংশন স্বাক্ষরের সাথে মেলে। প্রকৃতপক্ষে, আপনি v-for
আইটেম উপনামে ধ্বংস ফাংশন আর্গুমেন্টের অনুরূপ ডিস্ট্রাকচারিং ব্যবহার করতে পারেন:
template
<li v-for="{ message } in items">
{{ message }}
</li>
<!-- with index alias -->
<li v-for="({ message }, index) in items">
{{ message }} {{ index }}
</li>
নেস্টেড v-for
এর জন্য, স্কোপিং নেস্টেড ফাংশনের মতোই কাজ করে। প্রতিটি v-for
স্কোপের প্যারেন্ট স্কোপের অ্যাক্সেস আছে:
template
<li v-for="item in items">
<span v-for="childItem in item.children">
{{ item.message }} {{ childItem }}
</span>
</li>
আপনি in
-এর পরিবর্তে পরিসীমাক হিসেবে of
ব্যবহার করতে পারেন, যাতে এটি পুনরাবৃত্তিকারীদের জন্য জাভাস্ক্রিপ্টের সিনট্যাক্সের কাছাকাছি হয়:
template
<div v-for="item of items"></div>
v-for
with an Object
আপনি একটি অবজেক্ট পুনরাবৃত্তি করতে v-for
ব্যবহার করতে পারেন। পুনরাবৃত্তির ক্রম অবজেক্টে Object.values()
কল করার ফলাফলের উপর ভিত্তি করে করা হবে:
js
const myObject = reactive({
title: 'How to do lists in Vue',
author: 'Jane Doe',
publishedAt: '2016-04-10'
})
template
<ul>
<li v-for="value in myObject">
{{ value }}
</li>
</ul>
আপনি কম্পিউটেড প্রপার্টির নামের জন্য একটি দ্বিতীয় উপনামও প্রদান করতে পারেন (ওরফে key):
template
<li v-for="(value, key) in myObject">
{{ key }}: {{ value }}
</li>
এবং সূচকের জন্য আরেকটি:
template
<li v-for="(value, key, index) in myObject">
{{ index }}. {{ key }}: {{ value }}
</li>
v-for
with a Range
v-for
একটি পূর্ণসংখ্যাও নিতে পারে। এই ক্ষেত্রে এটি 1...n
এর পরিসরের উপর ভিত্তি করে বহুবার টেমপ্লেটটি পুনরাবৃত্তি করবে।
template
<span v-for="n in 10">{{ n }}</span>
এখানে নোট করুন n
0
এর পরিবর্তে 1
এর প্রাথমিক মান দিয়ে শুরু হয়।
v-for
on <template>
টেমপ্লেট v-if
এর মতো, আপনি একাধিক কম্পোনেন্টের একটি ব্লক রেন্ডার করতে v-for
সহ একটি <template>
ট্যাগও ব্যবহার করতে পারেন। উদাহরণ স্বরূপ:
template
<ul>
<template v-for="item in items">
<li>{{ item.msg }}</li>
<li class="divider" role="presentation"></li>
</template>
</ul>
v-for
with v-if
Note
অন্তর্নিহিত অগ্রাধিকারের কারণে একই এলিমেন্টে v-if
এবং v-for
ব্যবহার করার পরামর্শ নয়। বিস্তারিত জানার জন্য স্টাইল গাইড পড়ুন।
যখন তারা একই নোডে উপস্থিত থাকে, v-if
এর থেকে v-for
এর চেয়ে উচ্চ অগ্রাধিকার থাকে। এর মানে v-if
শর্তের v-for
এর সুযোগ থেকে ভেরিয়েবলে অ্যাক্সেস থাকবে না:
template
<!--
This will throw an error because property "todo"
is not defined on instance.
-->
<li v-for="todo in todos" v-if="!todo.isComplete">
{{ todo.name }}
</li>
এটি একটি মোড়ানো <template>
ট্যাগে v-for
সরানোর মাধ্যমে ঠিক করা যেতে পারে (যা আরও স্পষ্ট):
template
<template v-for="todo in todos">
<li v-if="!todo.isComplete">
{{ todo.name }}
</li>
</template>
Maintaining State with key
Vue যখন v-for
দিয়ে রেন্ডার করা কম্পোনেন্টগুলির একটি তালিকা আপডেট করে, ডিফল্টরূপে এটি একটি "ইন-প্লেস প্যাচ" কৌশল ব্যবহার করে। যদি ডেটা আইটেমগুলির ক্রম পরিবর্তিত হয়, আইটেমগুলির ক্রম মেলে DOM কম্পোনেন্টগুলি সরানোর পরিবর্তে, Vue প্রতিটি কম্পোনেন্টকে জায়গায় প্যাচ করবে এবং নিশ্চিত করবে যে এটি সেই নির্দিষ্ট সূচকে কী রেন্ডার করা উচিত তা প্রতিফলিত করে।
এই ডিফল্ট মোডটি কার্যকর, কিন্তু শুধুমাত্র তখনই উপযুক্ত যখন আপনার তালিকা রেন্ডার আউটপুট চাইল্ড কম্পোনেন্ট স্টেট বা অস্থায়ী DOM স্টেট (যেমন ফর্ম ইনপুট মান) উপর নির্ভর করে না।
Vue-কে একটি ইঙ্গিত দিতে যাতে এটি প্রতিটি নোডের পরিচয় ট্র্যাক করতে পারে, এবং এইভাবে বিদ্যমান কম্পোনেন্টগুলিকে পুনরায় ব্যবহার এবং পুনরায় সাজাতে, আপনাকে প্রতিটি আইটেমের জন্য একটি অনন্য key
বৈশিষ্ট্য প্রদান করতে হবে:
template
<div v-for="item in items" :key="item.id">
<!-- content -->
</div>
<template v-for>
ব্যবহার করার সময়, key
টি <template>
কন্টেইনারে স্থাপন করা উচিত:
template
<template v-for="todo in todos" :key="todo.name">
<li>{{ todo.name }}</li>
</template>
বিঃদ্রঃ
key
এখানে v-bind
এর সাথে আবদ্ধ একটি বিশেষ বৈশিষ্ট্য। এটি প্রপার্টি কী ভেরিয়েবলের সাথে বিভ্রান্ত হওয়া উচিত নয় যখন কোন অবজেক্টর সাথে v-for
ব্যবহার করে।
এটি সুপারিশ করা হয় যখনই সম্ভব v-for
এর সাথে একটি key
বৈশিষ্ট্য প্রদান করা, যদি না পুনরাবৃত্তি করা DOM বিষয়অবজেক্ট সহজ হয় (যেমন কোনো কম্পোনেন্ট বা রাষ্ট্রীয় DOM কম্পোনেন্ট), অথবা আপনি ইচ্ছাকৃতভাবে কর্মক্ষমতা লাভের জন্য ডিফল্ট আচরণের উপর নির্ভর করছেন।
key
বাইন্ডিং আদিম মান আশা করে - যেমন স্ট্রিং এবং সংখ্যা। অবজেক্টকে v-for
কী হিসেবে ব্যবহার করবেন না। key
অ্যাট্রিবিউটের বিস্তারিত ব্যবহারের জন্য, অনুগ্রহ করে key
API ডকুমেন্টেশন দেখুন।
v-for
with a Component
এই বিভাগটি Components সম্পর্কে জ্ঞান গ্রহণ করে। নির্দ্বিধায় এটি এড়িয়ে যান এবং পরে ফিরে আসুন।
আপনি একটি কম্পোনেন্টে সরাসরি v-for
ব্যবহার করতে পারেন, যেকোনো সাধারণ কম্পোনেন্টের মতো (একটি key
প্রদান করতে ভুলবেন না):
template
<MyComponent v-for="item in items" :key="item.id" />
যাইহোক, এটি স্বয়ংক্রিয়ভাবে কম্পোনেন্টটিতে কোনো ডেটা পাঠাবে না, কারণ কম্পোনেন্টগুলির নিজস্ব বিচ্ছিন্ন সুযোগ রয়েছে। কম্পোনেন্টে পুনরাবৃত্ত ডেটা পাস করার জন্য, আমাদের প্রপসও ব্যবহার করা উচিত:
template
<MyComponent
v-for="(item, index) in items"
:item="item"
:index="index"
:key="item.id"
/>
কম্পোনেন্টে স্বয়ংক্রিয়ভাবে item
ইনজেকশন না করার কারণ হল এটি কম্পোনেন্টটিকে কীভাবে v-for
কাজ করে তার সাথে শক্তভাবে সংযুক্ত করে। এর ডেটা কোথা থেকে আসে সে সম্পর্কে স্পষ্ট হওয়া কম্পোনেন্টটিকে অন্যান্য পরিস্থিতিতে পুনরায় ব্যবহারযোগ্য করে তোলে।
দেখুন একটি সহজ করণীয় তালিকার এই উদাহরণ to see how to render a list of components using v-for
, passing different data to each instance.
Array Change Detection
Mutation Methods
Vue সনাক্ত করতে সক্ষম হয় যখন একটি প্রতিক্রিয়াশীল অ্যারের মিউটেশন পদ্ধতিগুলিকে কল করা হয় এবং প্রয়োজনীয় আপডেটগুলি ট্রিগার করে৷ এই মিউটেশন পদ্ধতিগুলি হল:
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
Replacing an Array
মিউটেশন পদ্ধতি, নাম থেকে বোঝা যায়, মূল অ্যারেকে মিউটেশন করে যেটিতে তারা কল করা হয়। তুলনামূলকভাবে, নন-মিউটেটিং পদ্ধতিও রয়েছে, যেমন filter()
, concat()
এবং slice()
, যা মূল অ্যারেকে পরিবর্তন করে না কিন্তু সর্বদা একটি নতুন অ্যারে প্রদান করে। নন-মিউটেটিং পদ্ধতির সাথে কাজ করার সময়, আমাদের পুরানো অ্যারেটিকে নতুন দিয়ে প্রতিস্থাপন করা উচিত:
js
// `items` is a ref with array value
items.value = items.value.filter((item) => item.message.match(/Foo/))
আপনি ভাবতে পারেন যে এটি Vue কে বিদ্যমান DOM ছুঁড়ে ফেলে দিবে এবং পুরো তালিকাটি পুনরায় রেন্ডার করবে - ভাগ্যক্রমে, এটি এমন নয়। Vue কিছু স্মার্ট হিউরিস্টিক প্রয়োগ করে DOM এলিমেন্টের পুনঃব্যবহারকে সর্বাধিক করার জন্য, তাই ওভারল্যাপিং অবজেক্ট সমন্বিত অন্য অ্যারের সাথে একটি অ্যারে প্রতিস্থাপন করা একটি অত্যন্ত দক্ষ অপারেশন।
Displaying Filtered/Sorted Results
কখনও কখনও আমরা আসল ডেটা পরিবর্তন বা রিসেট না করে একটি অ্যারের ফিল্টার করা বা সাজানো সংস্করণ প্রদর্শন করতে চাই। এই ক্ষেত্রে, আপনি একটি কম্পিউটেড প্রপার্টি তৈরি করতে পারেন যা ফিল্টার করা বা সাজানো অ্যারে প্রদান করে।
উদাহরণ স্বরূপ:
js
const numbers = ref([1, 2, 3, 4, 5])
const evenNumbers = computed(() => {
return numbers.value.filter((n) => n % 2 === 0)
})
template
<li v-for="n in evenNumbers">{{ n }}</li>
এমন পরিস্থিতিতে যেখানে গণনা করা বৈশিষ্ট্যগুলি সম্ভব নয় (যেমন নেস্টেড v-for
লুপের ভিতরে), আপনি একটি পদ্ধতি ব্যবহার করতে পারেন:
js
const sets = ref([
[1, 2, 3, 4, 5],
[6, 7, 8, 9, 10]
])
function even(numbers) {
return numbers.filter((number) => number % 2 === 0)
}
template
<ul v-for="numbers in sets">
<li v-for="n in even(numbers)">{{ n }}</li>
</ul>
একটি কম্পিউটেড প্রপার্টিতে reverse()
এবং sort()
এর সাথে সতর্ক থাকুন! এই দুটি পদ্ধতি মূল অ্যারেকে রূপান্তরিত করবে, যা গণিত গেটারগুলিতে এড়ানো উচিত। এই পদ্ধতিগুলি কল করার আগে মূল অ্যারের একটি অনুলিপি তৈরি করুন:
diff
- return numbers.reverse()
+ return [...numbers].reverse()