Skip to content

Provide / Inject

এই পৃষ্ঠাটি ধরে নেওয়া হচ্ছে আপনি ইতিমধ্যেই Components Basics পড়েছেন। আপনি যদি কম্পোনেন্টগুলিতে নতুন হন তবে প্রথমে এটি পড়ুন।

Prop Drilling

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

prop drilling diagram

লক্ষ্য করুন যদিও <Footer> কম্পোনেন্টটি এই প্রপসগুলিকে মোটেও গুরুত্ব নাও দিতে পারে, তবুও এটিকে ঘোষণা করতে হবে এবং পাস করতে হবে যাতে <DeepChild> সেগুলি অ্যাক্সেস করতে পারে। যদি একটি দীর্ঘ অভিভাবক শৃঙ্খল থাকে, তবে আরও কম্পোনেন্টগুলি পথে প্রভাবিত হবে। এটিকে "প্রপস ড্রিলিং" বলা হয় এবং এটি মোকাবেলা করা অবশ্যই মজাদার নয়।

আমরা provide এবং inject দিয়ে প্রপস ড্রিলিং সমাধান করতে পারি। একটি অভিভাবক কম্পোনেন্ট তার সমস্ত বংশধরদের জন্য নির্ভরতা প্রদানকারী হিসেবে কাজ করতে পারে। বংশধর গাছের যেকোনো কম্পোনেন্ট, তা যতই গভীর হোক না কেন, inject করতে পারে তার মূল শৃঙ্খলে থাকা কম্পোনেন্টগুলির দ্বারা প্রদত্ত নির্ভরতা।

Provide/inject scheme

Provide

একটি কম্পোনেন্টের বংশধরদের ডেটা প্রদান করতে, provide() ফাংশনটি ব্যবহার করুন:

vue
<script setup>
import { provide } from 'vue'

provide(/* key */ 'message', /* value */ 'hello!')
</script>

<script setup> ব্যবহার না করলে, নিশ্চিত করুন যে setup() এর ভিতরে সিঙ্ক্রোনাসভাবে provide() বলা হয়েছে:

js
import { provide } from 'vue'

export default {
  setup() {
    provide(/* key */ 'message', /* value */ 'hello!')
  }
}

provide() ফাংশন দুটি আর্গুমেন্ট গ্রহণ করে। প্রথম যুক্তিটিকে injection key বলা হয়, যা একটি স্ট্রিং বা একটি Symbol হতে পারে। ইনজেকশন কীটি ইনজেকশনের জন্য পছন্দসই মান খুঁজতে বংশধর কম্পোনেন্ট দ্বারা ব্যবহৃত হয়। একটি একক কম্পোনেন্ট বিভিন্ন মান প্রদানের জন্য বিভিন্ন ইনজেকশন কী সহ একাধিকবার provide() কল করতে পারে।

দ্বিতীয় যুক্তি হল প্রদত্ত মান। মান যেকোন প্রকারের হতে পারে, যার মধ্যে প্রতিক্রিয়াশীল অবস্থা যেমন refs:

js
import { ref, provide } from 'vue'

const count = ref(0)
provide('key', count)

প্রতিক্রিয়াশীল মান প্রদানের মাধ্যমে সরবরাহকারী কম্পোনেন্টের সাথে একটি প্রতিক্রিয়াশীল সংযোগ স্থাপন করার জন্য প্রদত্ত মান ব্যবহার করে বংশধর কম্পোনেন্টগুলিকে অনুমতি দেয়।

একটি কম্পোনেন্টের বংশধরদের ডেটা প্রদান করতে, provide বিকল্পটি ব্যবহার করুন:

js
export default {
  provide: {
    message: 'hello!'
  }
}

provide অবজেক্টের প্রতিটি প্রপার্টির জন্য, কীটি চাইল্ড কম্পোনেন্ট দ্বারা ইনজেকশনের সঠিক মানটি সনাক্ত করতে ব্যবহার করা হয়, যখন মানটি ইনজেকশনের মাধ্যমে শেষ হয়।

যদি আমাদের প্রতি-দৃষ্টান্তের অবস্থা প্রদান করতে হয়, উদাহরণস্বরূপ data() এর মাধ্যমে ঘোষিত ডেটা, তাহলে provide একটি ফাংশন মান ব্যবহার করতে হবে:

js
export default {
  data() {
    return {
      message: 'hello!'
    }
  },
  provide() {
    // use function syntax so that we can access `this`
    return {
      message: this.message
    }
  }
}

যাইহোক, মনে রাখবেন যে এটি ইনজেকশনকে ক্রিয়াশীল করে তোলে না। আমরা নীচে making injections reactive নিয়ে আলোচনা করব।

App-level Provide

একটি কম্পোনেন্টে ডেটা প্রদানের পাশাপাশি, আমরা অ্যাপ স্তরেও প্রদান করতে পারি:

js
import { createApp } from 'vue'

const app = createApp({})

app.provide(/* key */ 'message', /* value */ 'hello!')

অ্যাপ-স্তরের প্রদানগুলি অ্যাপে রেন্ডার করা সমস্ত কম্পোনেন্টের জন্য উপলব্ধ। plugins লেখার সময় এটি বিশেষভাবে উপযোগী, কারণ প্লাগইনগুলি সাধারণত কম্পোনেন্ট ব্যবহার করে মান প্রদান করতে সক্ষম হয় না।

Inject

একটি ancestor component দ্বারা প্রদত্ত ডেটা ইনজেক্ট করতে, ইনজেক্ট() ফাংশনটি ব্যবহার করুন:

vue
<script setup>
import { inject } from 'vue'

const message = inject('message')
</script>

যদি প্রদত্ত মানটি একটি রেফ হয়, তাহলে এটি যেমন আছে-সেভাবেই ইনজেকশন করা হবে এবং না স্বয়ংক্রিয়ভাবে খুলে যাবে। এটি ইনজেক্টর কম্পোনেন্টটিকে প্রদানকারী কম্পোনেন্টের সাথে প্রতিক্রিয়াশীলতা সংযোগ বজায় রাখতে দেয়।

Full provide + inject Example with Reactivity

আবার, <script setup> ব্যবহার না করলে, inject() কে শুধুমাত্র setup()-এর ভিতরে সিঙ্ক্রোনাসভাবে বলা উচিত:

js
import { inject } from 'vue'

export default {
  setup() {
    const message = inject('message')
    return { message }
  }
}

ancestor component দ্বারা প্রদত্ত ডেটা ইনজেক্ট করতে, ইনজেক্ট বিকল্পটি ব্যবহার করুন:

js
export default {
  inject: ['message'],
  created() {
    console.log(this.message) // injected value
  }
}

ইনজেকশনগুলি কম্পোনেন্টের নিজস্ব অবস্থার before সমাধান করা হয়, যাতে আপনি data()-এ ইনজেকশনের বৈশিষ্ট্যগুলি অ্যাক্সেস করতে পারেন:

js
export default {
  inject: ['message'],
  data() {
    return {
      // initial data based on injected value
      fullMessage: this.message
    }
  }
}

Full provide + inject example

Injection Aliasing *

inject-এর জন্য অ্যারে সিনট্যাক্স ব্যবহার করার সময়, একই কী ব্যবহার করে কম্পোনেন্ট ইনস্ট্যান্সে ইনজেকশনের বৈশিষ্ট্যগুলি প্রকাশ করা হয়। উপরের উদাহরণে, প্রপার্টিটি "message"-এর অধীনে প্রদান করা হয়েছে এবং this.message হিসেবে ইনজেকশন করা হয়েছে। স্থানীয় কী ইনজেকশন কী হিসাবে একই।

যদি আমরা একটি ভিন্ন স্থানীয় কী ব্যবহার করে কম্পিউটেড প্রপার্টি ইনজেকশন করতে চাই, তাহলে আমাদের inject বিকল্পের জন্য অবজেক্ট সিনট্যাক্স ব্যবহার করতে হবে:

js
export default {
  inject: {
    /* local key */ localMessage: {
      from: /* injection key */ 'message'
    }
  }
}

এখানে, কম্পোনেন্টটি "message" কী সহ প্রদত্ত একটি কম্পিউটেড প্রপার্টি সনাক্ত করবে এবং তারপরে এটিকে this.localMessage হিসাবে প্রকাশ করবে।

Injection Default Values

ডিফল্টরূপে, inject অনুমান করে যে ইনজেকশন করা কীটি প্যারেন্ট চেইনের কোথাও সরবরাহ করা হয়েছে। যে ক্ষেত্রে কী প্রদান করা হয়নি, সেখানে একটি রানটাইম সতর্কতা থাকবে।

যদি আমরা ঐচ্ছিক প্রদানকারীদের সাথে একটি ইনজেকশনযুক্ত কম্পিউটেড প্রপার্টি কাজ করতে চাই, তাহলে আমাদের প্রপসের মতো একটি ডিফল্ট মান ঘোষণা করতে হবে:

js
// `value` will be "default value"
// if no data matching "message" was provided
const value = inject('message', 'default value')

কিছু ক্ষেত্রে, একটি ফাংশন কল করে বা একটি নতুন ক্লাস ইনস্ট্যান্টিয়েট করে ডিফল্ট মান তৈরি করতে হতে পারে। ঐচ্ছিক মান ব্যবহার না করা হলে অপ্রয়োজনীয় গণনা বা পার্শ্ব প্রতিক্রিয়া এড়াতে, আমরা ডিফল্ট মান তৈরি করার জন্য একটি কারখানা ফাংশন ব্যবহার করতে পারি:

js
const value = inject('key', () => new ExpensiveClass(), true)

The third parameter indicates the default value should be treated as a factory function.

js
export default {
  // object syntax is required
  // when declaring default values for injections
  inject: {
    message: {
      from: 'message', // this is optional if using the same key for injection
      default: 'default value'
    },
    user: {
      // use a factory function for non-primitive values that are expensive
      // to create, or ones that should be unique per component instance.
      default: () => ({ name: 'John' })
    }
  }
}

Working with Reactivity

প্রতিক্রিয়াশীল প্রদান / ইনজেকশন মান ব্যবহার করার সময়, যখনই সম্ভব যেকোন মিউটেশনকে provider এর ভিতরে প্রতিক্রিয়াশীল অবস্থায় রাখার পরামর্শ দেওয়া হয়। এটি নিশ্চিত করে যে প্রদত্ত অবস্থা এবং এর সম্ভাব্য মিউটেশনগুলি একই কম্পোনেন্টে সহ-অবস্থিত রয়েছে, যা ভবিষ্যতে বজায় রাখা সহজ করে তোলে।

এমন সময় হতে পারে যখন আমাদের একটি ইনজেক্টর কম্পোনেন্ট থেকে ডেটা আপডেট করতে হবে। এই ধরনের ক্ষেত্রে, আমরা এমন একটি ফাংশন প্রদান করার পরামর্শ দিই যা রাষ্ট্রকে পরিবর্তন করার জন্য দায়ী:

vue
<!-- inside provider component -->
<script setup>
import { provide, ref } from 'vue'

const location = ref('North Pole')

function updateLocation() {
  location.value = 'South Pole'
}

provide('location', {
  location,
  updateLocation
})
</script>
vue
<!-- in injector component -->
<script setup>
import { inject } from 'vue'

const { location, updateLocation } = inject('location')
</script>

<template>
  <button @click="updateLocation">{{ location }}</button>
</template>

পরিশেষে, আপনি প্রদত্ত মানটিকে readonly() দিয়ে মুড়ে দিতে পারেন যদি আপনি নিশ্চিত করতে চান যে provide-এর মাধ্যমে পাস করা ডেটা ইনজেক্টর কম্পোনেন্ট দ্বারা পরিবর্তিত হতে পারে না।

vue
<script setup>
import { ref, provide, readonly } from 'vue'

const count = ref(0)
provide('read-only-count', readonly(count))
</script>

ইনজেকশনগুলিকে সরবরাহকারীর সাথে প্রতিক্রিয়াশীলভাবে সংযুক্ত করার জন্য, আমাদের computed() ফাংশন ব্যবহার করে একটি গণনা করা কম্পিউটেড প্রপার্টি প্রদান করতে হবে:

js
import { computed } from 'vue'

export default {
  data() {
    return {
      message: 'hello!'
    }
  },
  provide() {
    return {
      // explicitly provide a computed property
      message: computed(() => this.message)
    }
  }
}

Full provide + inject Example with Reactivity

computed() ফাংশনটি সাধারণত কম্পোজিশন API কম্পোনেন্টগুলিতে ব্যবহৃত হয়, তবে বিকল্প API-এ নির্দিষ্ট ব্যবহারের ক্ষেত্রে পরিপূরক করতেও ব্যবহার করা যেতে পারে। আপনি কম্পোজিশন এপিআই-এ সেট করা API পছন্দের সাথে Reactivity Fundamentals এবং Computed Properties পড়ে এর ব্যবহার সম্পর্কে আরও জানতে পারেন।

Working with Symbol Keys

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

একটি ডেডিকেটেড ফাইলে প্রতীকগুলি রপ্তানি করার পরামর্শ দেওয়া হচ্ছে:

js
// keys.js
export const myInjectionKey = Symbol()
js
// in provider component
import { provide } from 'vue'
import { myInjectionKey } from './keys.js'

provide(myInjectionKey, {
  /* data to provide */
})
js
// in injector component
import { inject } from 'vue'
import { myInjectionKey } from './keys.js'

const injected = inject(myInjectionKey)

আরো দেখুন: Typing Provide / Inject

js
// in provider component
import { myInjectionKey } from './keys.js'

export default {
  provide() {
    return {
      [myInjectionKey]: {
        /* data to provide */
      }
    }
  }
}
js
// in injector component
import { myInjectionKey } from './keys.js'

export default {
  inject: {
    injected: { from: myInjectionKey }
  }
}
Provide / Inject has loaded