Skip to content

Components Basics

উপাদানগুলি আমাদের UI কে স্বাধীন এবং পুনঃব্যবহারযোগ্য টুকরোগুলিতে বিভক্ত করার অনুমতি দেয় এবং প্রতিটি অংশকে বিচ্ছিন্নভাবে চিন্তা করতে দেয়৷ একটি অ্যাপকে নেস্টেড কম্পোনেন্টগুলির একটি গাছে সংগঠিত করা সাধারণ:

Component Tree

এটি আমরা যেভাবে নেটিভ HTML উপাদানগুলিকে নেস্ট করি তার সাথে খুব মিল, তবে Vue তার নিজস্ব উপাদান মডেল প্রয়োগ করে যা আমাদের প্রতিটি উপাদানে কাস্টম বিষয়বস্তু এবং যুক্তি এনক্যাপসুলেট করতে দেয়। Vue নেটিভ ওয়েব কম্পোনেন্টের সাথেও সুন্দরভাবে খেলে। আপনি যদি Vue উপাদান এবং নেটিভ ওয়েব উপাদানগুলির মধ্যে সম্পর্ক সম্পর্কে আগ্রহী হন, এখানে আরও পড়ুন

Defining a Component

একটি বিল্ড স্টেপ ব্যবহার করার সময়, আমরা সাধারণত .vue এক্সটেনশন ব্যবহার করে একটি ডেডিকেটেড ফাইলে প্রতিটি Vue কম্পোনেন্টকে সংজ্ঞায়িত করি - যা Single-File Component (সংক্ষেপে SFC):

vue
<script>
export default {
  data() {
    return {
      count: 0
    }
  }
}
</script>

<template>
  <button @click="count++">You clicked me {{ count }} times.</button>
</template>
vue
<script setup>
import { ref } from 'vue'

const count = ref(0)
</script>

<template>
  <button @click="count++">You clicked me {{ count }} times.</button>
</template>

একটি বিল্ড স্টেপ ব্যবহার না করার সময়, একটি Vue কম্পোনেন্টকে একটি প্লেইন জাভাস্ক্রিপ্ট অবজেক্ট হিসাবে সংজ্ঞায়িত করা যেতে পারে যেখানে Vue-নির্দিষ্ট বিকল্প রয়েছে:

js
export default {
  data() {
    return {
      count: 0
    }
  },
  template: `
    <button @click="count++">
      You clicked me {{ count }} times.
    </button>`
}
js
import { ref } from 'vue'

export default {
  setup() {
    const count = ref(0)
    return { count }
  },
  template: `
    <button @click="count++">
      You clicked me {{ count }} times.
    </button>`
  // Can also target an in-DOM template:
  // template: '#my-template-element'
}

টেমপ্লেটটি এখানে জাভাস্ক্রিপ্ট স্ট্রিং হিসাবে ইনলাইন করা হয়েছে, যা Vue ফ্লাইতে কম্পাইল করবে। আপনি একটি আইডি নির্বাচকও ব্যবহার করতে পারেন যেটি একটি কম্পোনেন্টের দিকে নির্দেশ করে (সাধারণত নেটিভ <template> কম্পোনেন্ট) - Vue এর সামগ্রীকে টেমপ্লেট উত্স হিসাবে ব্যবহার করবে৷

উপরের উদাহরণটি একটি একক কম্পোনেন্টকে সংজ্ঞায়িত করে এবং এটি একটি .js ফাইলের ডিফল্ট exports হিসাবে export করে, তবে আপনি একই ফাইল থেকে একাধিক কম্পোনেন্ট exports করতে নাম export ব্যবহার করতে পারেন।

Using a Component

TIP

আমরা এই গাইডের বাকি অংশের জন্য SFC সিনট্যাক্স ব্যবহার করব - আপনি একটি বিল্ড স্টেপ ব্যবহার করছেন বা না করছেন তা নির্বিশেষে কম্পোনেন্টগুলির চারপাশের ধারণাগুলি একই। Examples বিভাগটি উভয় পরিস্থিতিতেই কম্পোনেন্টের ব্যবহার দেখায়।

একটি চাইল্ড কম্পোনেন্ট ব্যবহার করতে, আমাদের এটিকে প্যারেন্ট কম্পোনেন্টে ইম্পোর্ট করতে হবে। ধরে নিচ্ছি আমরা আমাদের কাউন্টার কম্পোনেন্টকে ButtonCounter.vue নামক একটি ফাইলের ভিতরে রেখেছি, কম্পোনেন্টটি ফাইলের ডিফল্ট এক্সপোর্ট হিসেবে উন্মুক্ত হবে:

vue
<script>
import ButtonCounter from './ButtonCounter.vue'

export default {
  components: {
    ButtonCounter
  }
}
</script>

<template>
  <h1>Here is a child component!</h1>
  <ButtonCounter />
</template>

আমাদের টেমপ্লেটে ইম্পোর্ট করা কম্পোনেন্ট এক্সপোজ করতে, আমাদের এটিকে ' কম্পোনেন্টস' বিকল্পের সাথে রেজিস্টার করতে হবে। কম্পোনেন্টটি তারপরে নিবন্ধিত কী ব্যবহার করে একটি ট্যাগ হিসাবে উপলব্ধ হবে।

vue
<script setup>
import ButtonCounter from './ButtonCounter.vue'
</script>

<template>
  <h1>Here is a child component!</h1>
  <ButtonCounter />
</template>

<script setup> এর সাথে, আমদানি করা কম্পোনেন্টগুলি স্বয়ংক্রিয়ভাবে টেমপ্লেটে উপলব্ধ করা হয়।

এটি আমদানি না করেই একটি প্রদত্ত অ্যাপের সমস্ত কম্পোনেন্টের জন্য উপলব্ধ করে, বিশ্বব্যাপী একটি কম্পোনেন্ট নিবন্ধন করাও সম্ভব। গ্লোবাল বনাম স্থানীয় রেজিস্ট্রেশনের ভালো-মন্দ আলোচনা করা হয়েছে ডেডিকেটেড কম্পোনেন্ট রেজিস্ট্রেশন বিভাগে।

উপাদানগুলি আপনি যতবার চান ততবার পুনরায় ব্যবহার করা যেতে পারে:

template
<h1>Here are many child components!</h1>
<ButtonCounter />
<ButtonCounter />
<ButtonCounter />

লক্ষ্য করুন যে বোতামগুলিতে ক্লিক করার সময়, প্রতিটি তার নিজস্ব, পৃথক count বজায় রাখে। কারণ প্রতিবার আপনি একটি কম্পোনেন্ট ব্যবহার করলে, এর একটি নতুন উদাহরণ তৈরি হয়।

SFC-তে, নেটিভ HTML কম্পোনেন্ট থেকে আলাদা করতে চাইল্ড কম্পোনেন্টের জন্য PascalCase ট্যাগ নাম ব্যবহার করার পরামর্শ দেওয়া হয়। যদিও নেটিভ HTML ট্যাগের নামগুলি কেস-সংবেদনশীল, তবে Vue SFC একটি সংকলিত বিন্যাস তাই আমরা এতে কেস-সংবেদনশীল ট্যাগ নামগুলি ব্যবহার করতে সক্ষম। আমরা ট্যাগ বন্ধ করতে /> ব্যবহার করতেও সক্ষম।

আপনি যদি আপনার টেমপ্লেটগুলি সরাসরি একটি DOM-এ রচনা করেন (যেমন একটি নেটিভ <template> কম্পোনেন্টের বিষয়অবজেক্ট হিসাবে), টেমপ্লেটটি ব্রাউজারের নেটিভ HTML পার্সিং আচরণের অধীন হবে। এই ধরনের ক্ষেত্রে, আপনাকে 'কাবাব-কেস' এবং কম্পোনেন্টগুলির জন্য স্পষ্ট ক্লোজিং ট্যাগ ব্যবহার করতে হবে:

template
<!-- if this template is written in the DOM -->
<button-counter></button-counter>
<button-counter></button-counter>
<button-counter></button-counter>

আরও বিশদ বিবরণের জন্য in-DOM template parsing caveats দেখুন।

Passing Props

যদি আমরা একটি ব্লগ তৈরি করি, তাহলে আমাদের সম্ভবত একটি ব্লগ পোস্টের প্রতিনিধিত্বকারী একটি কম্পোনেন্টের প্রয়োজন হবে। আমরা চাই যে সমস্ত ব্লগ পোস্ট একই ভিজ্যুয়াল লেআউট শেয়ার করুক, কিন্তু ভিন্ন বিষয়অবজেক্ট সহ। এই ধরনের একটি কম্পোনেন্ট উপযোগী হবে না যদি না আপনি এটিতে ডেটা পাঠাতে পারেন, যেমন নির্দিষ্ট পোস্টের শিরোনাম এবং বিষয়অবজেক্ট আমরা প্রদর্শন করতে চাই। যে যেখানে প্রপস আসা.

প্রপগুলি হল কাস্টম বৈশিষ্ট্যগুলি যা আপনি একটি কম্পোনেন্টে নিবন্ধন করতে পারেন। আমাদের ব্লগ পোস্ট কম্পোনেন্টে একটি শিরোনাম পাস করার জন্য, props ব্যবহার করে এই কম্পোনেন্টটি গ্রহণ করে এমন প্রপসের তালিকায় আমাদের এটি ঘোষণা করতে হবে। বিকল্পdefineProps ম্যাক্রো:

vue
<!-- BlogPost.vue -->
<script>
export default {
  props: ['title']
}
</script>

<template>
  <h4>{{ title }}</h4>
</template>

যখন একটি মান একটি প্রপ অ্যাট্রিবিউটে পাস করা হয়, তখন এটি সেই কম্পোনেন্ট উদাহরণে একটি কম্পিউটেড প্রপার্টি হয়ে যায়। সেই কম্পিউটেড প্রপার্টির মান টেমপ্লেটের মধ্যে এবং কম্পোনেন্টের this প্রেক্ষাপটে অ্যাক্সেসযোগ্য, ঠিক অন্য কোনো কম্পোনেন্ট কম্পিউটেড প্রপার্টির মতো।

vue
<!-- BlogPost.vue -->
<script setup>
defineProps(['title'])
</script>

<template>
  <h4>{{ title }}</h4>
</template>

defineProps হল একটি কম্পাইল-টাইম ম্যাক্রো যা শুধুমাত্র <script setup>-এর মধ্যেই উপলব্ধ এবং স্পষ্টভাবে আমদানি করার প্রয়োজন নেই। ঘোষিত প্রপগুলি স্বয়ংক্রিয়ভাবে টেমপ্লেটের কাছে প্রকাশিত হয়। defineProps একটি অবজেক্টও ফেরত দেয় যাতে কম্পোনেন্টে পাস করা সমস্ত প্রপ থাকে, যাতে আমরা প্রয়োজনে জাভাস্ক্রিপ্টে সেগুলি অ্যাক্সেস করতে পারি:

js
const props = defineProps(['title'])
console.log(props.title)

আরো দেখুন: Typing Component Props

আপনি যদি <script setup> ব্যবহার না করেন, তাহলে প্রপসকে props বিকল্প ব্যবহার করে ঘোষণা করা উচিত এবং প্রপস অবজেক্টটি প্রথম আর্গুমেন্ট হিসেবে setup()-এ পাস করা হবে:

js
export default {
  props: ['title'],
  setup(props) {
    console.log(props.title)
  }
}

একটি কম্পোনেন্টে আপনার পছন্দ মতো অনেকগুলি প্রপ থাকতে পারে এবং ডিফল্টরূপে, যেকোন মান যেকোন প্রপে পাস করা যেতে পারে।

একবার একটি প্রপ নিবন্ধিত হয়ে গেলে, আপনি এটিতে একটি কাস্টম বৈশিষ্ট্য হিসাবে ডেটা প্রেরণ করতে পারেন, যেমন:

template
<BlogPost title="My journey with Vue" />
<BlogPost title="Blogging with Vue" />
<BlogPost title="Why Vue is so fun" />

একটি সাধারণ অ্যাপে, তবে, আপনার সম্ভবত আপনার অভিভাবক কম্পোনেন্টে পোস্টের একটি অ্যারে থাকবে:

js
export default {
  // ...
  data() {
    return {
      posts: [
        { id: 1, title: 'My journey with Vue' },
        { id: 2, title: 'Blogging with Vue' },
        { id: 3, title: 'Why Vue is so fun' }
      ]
    }
  }
}
js
const posts = ref([
  { id: 1, title: 'My journey with Vue' },
  { id: 2, title: 'Blogging with Vue' },
  { id: 3, title: 'Why Vue is so fun' }
])

তারপর v-for ব্যবহার করে প্রত্যেকটির জন্য একটি কম্পোনেন্ট রেন্ডার করতে চান:

template
<BlogPost
  v-for="post in posts"
  :key="post.id"
  :title="post.title"
 />

লক্ষ্য করুন কিভাবে v-bind ডায়নামিক প্রপ মান পাস করতে ব্যবহৃত হয়। এটি বিশেষভাবে উপযোগী যখন আপনি সঠিক বিষয়অবজেক্ট জানেন না যে আপনি সময়ের আগে রেন্ডার করতে যাচ্ছেন।

আপাতত প্রপস সম্পর্কে আপনার এতটুকুই জানা দরকার, কিন্তু একবার আপনি এই পৃষ্ঠাটি পড়া শেষ করে এবং এর বিষয়অবজেক্টতে স্বাচ্ছন্দ্য বোধ করলে, আমরা প্রপস এর সম্পূর্ণ নির্দেশিকা পড়তে পরে ফিরে আসার পরামর্শ দিই।

Listening to Events

যেহেতু আমরা আমাদের <BlogPost> কম্পোনেন্টটি বিকাশ করি, কিছু বৈশিষ্ট্যের জন্য অভিভাবকের সাথে ব্যাক আপ যোগাযোগের প্রয়োজন হতে পারে। উদাহরণস্বরূপ, আমরা পৃষ্ঠার বাকি অংশটিকে ডিফল্ট আকারে রেখে ব্লগ পোস্টের পাঠ্যকে বড় করার জন্য একটি অ্যাক্সেসিবিলিটি বৈশিষ্ট্য অন্তর্ভুক্ত করার সিদ্ধান্ত নিতে পারি।

অভিভাবকদের মধ্যে, আমরা একটি পোস্টফন্ট সাইজ যোগ করে এই বৈশিষ্ট্যটিকে সমর্থন করতে পারি data propertyref:

js
data() {
  return {
    posts: [
      /* ... */
    ],
    postFontSize: 1
  }
}
js
const posts = ref([
  /* ... */
])

const postFontSize = ref(1)

যা সমস্ত ব্লগ পোস্টের ফন্ট সাইজ নিয়ন্ত্রণ করতে টেমপ্লেটে ব্যবহার করা যেতে পারে:

template
<div :style="{ fontSize: postFontSize + 'em' }">
  <BlogPost
    v-for="post in posts"
    :key="post.id"
    :title="post.title"
   />
</div>

এখন আসুন <BlogPost> কম্পোনেন্টের টেমপ্লেটে একটি বোতাম যোগ করি:

vue
<!-- BlogPost.vue, omitting <script> -->
<template>
  <div class="blog-post">
    <h4>{{ title }}</h4>
    <button>Enlarge text</button>
  </div>
</template>

বোতামটি এখনও কিছু করে না - আমরা অভিভাবকদের সাথে যোগাযোগ করতে বোতামটি ক্লিক করতে চাই যে এটি সমস্ত পোস্টের পাঠ্যকে বড় করবে৷ এই সমস্যাটি সমাধান করার জন্য, কম্পোনেন্টগুলি একটি কাস্টম ইভেন্ট সিস্টেম প্রদান করে। অভিভাবক চাইল্ডর কম্পোনেন্ট ইন্সট্যান্সে v-on বা @ দিয়ে যেকোনো ইভেন্ট শোনার জন্য বেছে নিতে পারেন, ঠিক যেমনটি আমরা একটি নেটিভ DOM ইভেন্টে করব:

template
<BlogPost
  ...
  @enlarge-text="postFontSize += 0.1"
 />

তারপর চাইল্ড কম্পোনেন্ট বিল্ট-ইন $emit পদ্ধতি কল করে ইভেন্টের নাম পাস করে নিজেই একটি ইভেন্ট নির্গত করতে পারে:

vue
<!-- BlogPost.vue, omitting <script> -->
<template>
  <div class="blog-post">
    <h4>{{ title }}</h4>
    <button @click="$emit('enlarge-text')">Enlarge text</button>
  </div>
</template>

@enlarge-text="postFontSize += 0.1" শ্রোতাকে ধন্যবাদ, অভিভাবক ইভেন্টটি পাবেন এবং postFontSize-এর মান আপডেট করবেন।

আমরা ঐচ্ছিকভাবে emits বিকল্প ব্যবহার করে নির্গত ইভেন্ট ঘোষণা করতে পারি defineEmits ম্যাক্রো:

vue
<!-- BlogPost.vue -->
<script>
export default {
  props: ['title'],
  emits: ['enlarge-text']
}
</script>
vue
<!-- BlogPost.vue -->
<script setup>
defineProps(['title'])
defineEmits(['enlarge-text'])
</script>

এটি সমস্ত ইভেন্টগুলিকে নথিভুক্ত করে যা একটি কম্পোনেন্ট নির্গত করে এবং ঐচ্ছিকভাবে তাদের যাচাই করে। এটি Vue-কে চাইল্ড কম্পোনেন্টের মূল কম্পোনেন্টে নেটিভ শ্রোতা হিসাবে প্রয়োগ করা এড়াতেও অনুমতি দেয়।

defineProps এর মতো, defineEmits শুধুমাত্র <script setup>-এ ব্যবহারযোগ্য এবং আমদানি করার প্রয়োজন নেই। এটি একটি emit ফাংশন প্রদান করে যা $emit পদ্ধতির সমতুল্য। এটি একটি কম্পোনেন্টের <script setup> বিভাগে ইভেন্ট নির্গত করতে ব্যবহার করা যেতে পারে, যেখানে $emit সরাসরি অ্যাক্সেসযোগ্য নয়:

vue
<script setup>
const emit = defineEmits(['enlarge-text'])

emit('enlarge-text')
</script>

See also: Typing Component Emits

আপনি যদি <script setup> ব্যবহার না করেন, তাহলে আপনি emits বিকল্প ব্যবহার করে নির্গত ইভেন্ট ঘোষণা করতে পারেন। আপনি সেটআপ প্রসঙ্গের একটি বৈশিষ্ট্য হিসাবে emits ফাংশনটি অ্যাক্সেস করতে পারেন (দ্বিতীয় আর্গুমেন্ট হিসাবে setup() এ পাস করা হয়েছে):

js
export default {
  emits: ['enlarge-text'],
  setup(props, ctx) {
    ctx.emit('enlarge-text')
  }
}

কাস্টম কম্পোনেন্ট ইভেন্টগুলি সম্পর্কে আপনার আপাতত এতটুকুই জানা দরকার, কিন্তু একবার আপনি এই পৃষ্ঠাটি পড়া শেষ করে এবং এর সামগ্রীর সাথে স্বাচ্ছন্দ্য বোধ করলে, আমরা সম্পূর্ণ নির্দেশিকাটি Custom Events পড়ার জন্য পরে ফিরে আসার পরামর্শ দিই।

Content Distribution with Slots

ঠিক HTML কম্পোনেন্টগুলির মতো, এটি প্রায়শই একটি কম্পোনেন্টে সামগ্রী প্রেরণ করতে সক্ষম হওয়া দরকারী, যেমন:

template
<AlertBox>
  Something bad happened.
</AlertBox>

যা কিছু রেন্ডার করতে পারে:

এটি ডেমো উদ্দেশ্যের জন্য একটি ত্রুটি

খারাপ কিছু ঘটেছে.

এটি Vue এর কাস্টম <slot> কম্পোনেন্ট ব্যবহার করে অর্জন করা যেতে পারে:

vue
<template>
  <div class="alert-box">
    <strong>This is an Error for Demo Purposes</strong>
    <slot />
  </div>
</template>

<style scoped>
.alert-box {
  /* ... */
}
</style>

আপনি উপরে দেখতে পাবেন, আমরা <slot> একটি স্থানধারক হিসাবে ব্যবহার করি যেখানে আমরা বিষয়অবজেক্টটি যেতে চাই - এবং এটাই। সম্পন্ন করা হয়েছে!

আপাতত স্লট সম্পর্কে আপনার এতটুকুই জানা দরকার, কিন্তু একবার আপনি এই পৃষ্ঠাটি পড়া শেষ করে এবং এর বিষয়অবজেক্টতে স্বাচ্ছন্দ্য বোধ করলে, আমরা Slots এর সম্পূর্ণ নির্দেশিকা পড়তে পরে ফিরে আসার পরামর্শ দিই।

Dynamic Components

কখনও কখনও, ট্যাবযুক্ত ইন্টারফেসের মতো কম্পোনেন্টগুলির মধ্যে গতিশীলভাবে স্যুইচ করা দরকারী:

উপরেরটি Vue এর <component> কম্পোনেন্ট দ্বারা বিশেষ is বৈশিষ্ট্যের দ্বারা সম্ভব হয়েছে:

template
<!-- Component changes when currentTab changes -->
<component :is="currentTab"></component>
template
<!-- Component changes when currentTab changes -->
<component :is="tabs[currentTab]"></component>

উপরের উদাহরণে, :is-এ পাস করা মানটিতে যে কোনো একটি থাকতে পারে:

  • একটি নিবন্ধিত component নাম স্ট্রিং, বা
  • imported কম্পোনেন্ট অবজেক্ট

আপনি নিয়মিত HTML কম্পোনেন্ট তৈরি করতে is বৈশিষ্ট্য ব্যবহার করতে পারেন।

<component :is="..."> দিয়ে একাধিক কম্পোনেন্টের মধ্যে স্যুইচ করার সময়, একটি কম্পোনেন্ট আনমাউন্ট করা হবে যখন এটি থেকে সুইচ করা হবে। আমরা বিল্ট-ইন <KeepAlive> কম্পোনেন্ট দিয়ে নিষ্ক্রিয় কম্পোনেন্টগুলিকে "জীবিত" থাকতে বাধ্য করতে পারি।

in-DOM Template Parsing Caveats

আপনি যদি সরাসরি DOM-এ আপনার Vue টেমপ্লেট লিখছেন, Vue-কে DOM থেকে টেমপ্লেট স্ট্রিং পুনরুদ্ধার করতে হবে। এটি ব্রাউজারের নেটিভ HTML পার্সিং আচরণের কারণে কিছু সতর্কতার দিকে নিয়ে যায়।

TIP

এটি লক্ষ করা উচিত যে নীচে আলোচনা করা সীমাবদ্ধতাগুলি শুধুমাত্র তখনই প্রযোজ্য হবে যদি আপনি সরাসরি DOM-এ আপনার টেমপ্লেটগুলি লিখছেন৷ আপনি যদি নিম্নলিখিত উত্স থেকে স্ট্রিং টেমপ্লেট ব্যবহার করেন তবে সেগুলি প্রযোজ্য হবে না:

  • একক ফাইল কম্পোনেন্ট
  • ইনলাইনড টেমপ্লেট স্ট্রিং (e.g. template: '...')
  • <script type="text/x-template">

Case Insensitivity

HTML ট্যাগ এবং অ্যাট্রিবিউটের নামগুলি অক্ষর-সংবেদনশীল, তাই ব্রাউজারগুলি বড় হাতের অক্ষরগুলিকে ছোট হাতের অক্ষর হিসাবে ব্যাখ্যা করবে। এর মানে হল আপনি যখন ইন-ডোম টেমপ্লেটগুলি ব্যবহার করছেন, তখন PascalCase কম্পোনেন্টের নাম এবং ক্যামেলকেসড প্রপ নাম বা v-on ইভেন্টের নামগুলিকে তাদের কাবাব-কেসড (হাইফেন-ডিলিমিটেড) সমতুল্য ব্যবহার করতে হবে:

js
// camelCase in JavaScript
const BlogPost = {
  props: ['postTitle'],
  emits: ['updatePost'],
  template: `
    <h3>{{ postTitle }}</h3>
  `
}
template
<!-- kebab-case in HTML -->
<blog-post post-title="hello!" @update-post="onUpdatePost"></blog-post>

Self Closing Tags

আমরা পূর্ববর্তী কোড নমুনাগুলিতে কম্পোনেন্টগুলির জন্য স্ব-ক্লোজিং ট্যাগ ব্যবহার করছি:

template
<MyComponent />

এর কারণ হল Vue-এর টেমপ্লেট পার্সার />কে যে কোনো ট্যাগ শেষ করার ইঙ্গিত হিসেবে সম্মান করে, তার ধরন নির্বিশেষে।

ইন-ডোম টেমপ্লেটগুলিতে, তবে, আমাদের অবশ্যই সর্বদা স্পষ্ট ক্লোজিং ট্যাগ অন্তর্ভুক্ত করতে হবে:

template
<my-component></my-component>

এর কারণ হল HTML স্পেক শুধুমাত্র কিছু নির্দিষ্ট কম্পোনেন্ট ক্লোজিং ট্যাগগুলিকে বাদ দেওয়ার অনুমতি দেয়, সবচেয়ে সাধারণ হল <input> এবং <img>। অন্য সব কম্পোনেন্টের জন্য, আপনি যদি ক্লোজিং ট্যাগটি বাদ দেন, তাহলে নেটিভ HTML পার্সার মনে করবে আপনি কখনই ওপেনিং ট্যাগটি বন্ধ করেননি। উদাহরণস্বরূপ, নিম্নলিখিত স্নিপেট:

template
<my-component /> <!-- we intend to close the tag here... -->
<span>hello</span>

will be parsed as:

template
<my-component>
  <span>hello</span>
</my-component> <!-- but the browser will close it here. -->

Element Placement Restrictions

কিছু HTML কম্পোনেন্ট, যেমন <ul>, <ol>, <table> এবং <select>-এর মধ্যে কী কম্পোনেন্ট উপস্থিত হতে পারে তার উপর সীমাবদ্ধতা রয়েছে এবং কিছু কম্পোনেন্ট যেমন <li>, <tr>, এবং <option> শুধুমাত্র কিছু অন্যান্য কম্পোনেন্টের মধ্যে উপস্থিত হতে পারে।

এই ধরনের বিধিনিষেধ আছে এমন কম্পোনেন্টগুলির সাথে কম্পোনেন্টগুলি ব্যবহার করার সময় এটি সমস্যার দিকে পরিচালিত করবে। উদাহরণ স্বরূপ:

template
<table>
  <blog-post-row></blog-post-row>
</table>

কাস্টম কম্পোনেন্ট <blog-post-row> অবৈধ বিষয়অবজেক্ট হিসাবে উত্তোলন করা হবে, যার ফলে চূড়ান্ত রেন্ডার করা আউটপুটে ত্রুটি দেখা দিবে। আমরা একটি সমাধান হিসাবে বিশেষ is বৈশিষ্ট্য ব্যবহার করতে পারি:

template
<table>
  <tr is="vue:blog-post-row"></tr>
</table>

TIP

যখন নেটিভ এইচটিএমএল কম্পোনেন্টগুলিতে ব্যবহার করা হয়, তখন একটি Vue কম্পোনেন্ট হিসাবে ব্যাখ্যা করার জন্য is এর মান অবশ্যই vue: এর সাথে প্রিফিক্স করা উচিত। স্থানীয় কাস্টমাইজড বিল্ট-ইন elements নিয়ে বিভ্রান্তি এড়াতে এটি প্রয়োজন।

এখনকার জন্য ইন-ডোম টেমপ্লেট পার্সিং সতর্কতা সম্পর্কে আপনার এতটুকুই জানা দরকার - এবং আসলে, Vue এর Essentials এর শেষ। অভিনন্দন! শেখার জন্য এখনও আরও অনেক কিছু আছে, কিন্তু প্রথমে, আমরা Vue এর সাথে অনুশীলন করা জন্য বিরতি নেওয়ার পরামর্শ দিই - মজাদার কিছু তৈরি করুন, অথবা আপনি যদি ইতিমধ্যে না করে থাকেন তবে কিছু Examples দেখুন।

একবার আপনি যে জ্ঞানটি হজম করেছেন তাতে স্বাচ্ছন্দ্য বোধ করলে, কম্পোনেন্টগুলি সম্পর্কে গভীরভাবে আরও জানতে গাইডের সাথে এগিয়ে যান।

Components Basics has loaded