provide() และ inject() สำหรับการฉีดการพึ่งพา
ให้ค่าที่คอมโพเนนต์บรรพบุรุษและฉีดค่าเหล่านั้นลงไปยังส่วนลึกของทรี เพื่อหลีกเลี่ยงการส่งพร็อพส์ผ่านคอมโพเนนต์หลายชั้นโดยไม่ต้องใช้ไลบรารีจัดการสถานะเต็มรูปแบบ
provide() และ inject() สำหรับการฉีดการพึ่งพา เป็นบทเรียน Frontend Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Frontend Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Frontend Academy มีบทเรียนทั้งหมด 4 บทเรียน
ปัญหาการส่งพร็อพต่อผ่านทุกชั้น
บางครั้งข้อมูลอยู่ในคอมโพเนนต์ระดับบนและต้องส่งไปยังคอมโพเนนต์ลูกหลานที่อยู่ลึกลงไป การส่งข้อมูลผ่านคอมโพเนนต์ตัวกลางทุกตัว หรือที่เรียกว่าการส่งพร็อพต่อผ่านทุกชั้น เป็นเรื่องยุ่งยากและเปราะบาง
provide() — การประกาศค่า
คอมโพเนนต์บรรพบุรุษเรียก provide(key, value) ใน setup() จากนั้นค่าดังกล่าวจะพร้อมใช้งานในคอมโพเนนต์ลูกหลานทั้งหมด
<!-- ParentComponent.vue -->
<script setup>
import { provide, ref } from 'vue';
const theme = ref('dark');
provide('theme', theme);
</script>inject() — การใช้ค่า
คอมโพเนนต์ลูกหลานใด ๆ ก็สามารถเรียก inject(key) เพื่ออ่านค่าได้
<!-- DeepChild.vue -->
<script setup>
import { inject } from 'vue';
const theme = inject('theme');
</script>
<template>
<div :class="theme">Theme is: {{ theme }}</div>
</template>การทำงานแบบรีแอกทีฟด้วย ref/reactive
หากคุณ provide อ็อบเจ็กต์แบบ ref หรือ reactive คอมโพเนนต์ลูกหลานจะได้รับค่าแบบรีแอกทีฟ และการอัปเดตจะส่งต่อโดยอัตโนมัติ
// Parent
const user = reactive({ name: 'Alice', role: 'admin' });
provide('user', user);
// Anywhere descendant
const user = inject('user');
user.role; // 'admin' — reactiveใช้คีย์แบบ Symbol เพื่อหลีกเลี่ยงการชนกัน
คีย์แบบสตริงมีความเสี่ยงที่จะชนกันในแอปขนาดใหญ่ ส่วน Symbol รับประกันความไม่ซ้ำกัน ควรกำหนดคีย์เหล่านี้ไว้ในไฟล์ที่ใช้ร่วมกัน
// keys.ts
export const ThemeKey = Symbol('theme');
export const UserKey = Symbol('user');
// Parent
provide(ThemeKey, ref('dark'));
// Child
const theme = inject(ThemeKey);การรองรับ TypeScript
ใช้ InjectionKey<T> เพื่อกำหนดชนิดข้อมูลให้ทั้งสองฝั่งอย่างปลอดภัย
import type { InjectionKey, Ref } from 'vue';
export const ThemeKey: InjectionKey<Ref<string>> = Symbol('theme');
// Provider:
provide(ThemeKey, ref('dark'));
// Consumer (type-checked):
const theme = inject(ThemeKey); // Ref<string> | undefinedค่าเริ่มต้น
หากไม่มีคอมโพเนนต์บรรพบุรุษใด provide คีย์ inject จะคืนค่า undefined เว้นแต่คุณจะส่งค่าเริ่มต้นเข้าไป
const theme = inject('theme', 'light'); // default if missing
const lazy = inject('user', () => createDefaultUser(), true); // factoryค่าที่ provide แบบอ่านอย่างเดียว
เพื่อป้องกันไม่ให้คอมโพเนนต์ลูกหลานแก้ไขสถานะที่ใช้ร่วมกัน ให้ครอบค่าด้วย readonly()
import { readonly } from 'vue';
const user = reactive({ name: 'Alice' });
provide('user', readonly(user));
// Children can read but cannot mutateการ provide ระดับแอป
Provide ค่าในระดับแอปเพื่อให้พร้อมใช้งานได้ทุกที่ ซึ่งมีประโยชน์สำหรับปลั๊กอิน
// main.ts
import { createApp } from 'vue';
import App from './App.vue';
const app = createApp(App);
app.provide('apiClient', new ApiClient());
app.mount('#app');ตัวห่อแบบ Composable
ห่อ provide/inject ไว้ใน composable เพื่อให้ API สำหรับผู้ใช้เรียบง่ายยิ่งขึ้น
// useTheme.ts
import { inject, type InjectionKey, type Ref } from 'vue';
export const ThemeKey: InjectionKey<Ref<string>> = Symbol('theme');
export function useTheme() {
const theme = inject(ThemeKey);
if (!theme) throw new Error('useTheme: no provider in tree');
return theme;
}provide/inject เทียบกับ Pinia
provide/inject: น้ำหนักเบา ไม่ต้องใช้ไลบรารี เหมาะสำหรับค่ารูปแบบปลั๊กอิน เช่น ธีม ภาษาท้องถิ่น และผู้ใช้ปัจจุบัน ส่วน Pinia: เป็นการจัดการสถานะแบบเต็มรูปแบบพร้อม DevTools เหมาะสำหรับสถานะแบบรีแอกทีฟทั่วทั้งแอปที่มีการอัปเดตซับซ้อน
ตรวจสอบความเข้าใจอย่างรวดเร็ว
วิธีที่แนะนำเพื่อหลีกเลี่ยงการชนกันของคีย์เมื่อใช้ provide/inject ทั่วทั้งแอป Vue ขนาดใหญ่คืออะไร
ทบทวน: provide/inject
คอมโพเนนต์บรรพบุรุษเป็นผู้ provide และคอมโพเนนต์ลูกหลานเป็นผู้ inject จึงไม่ต้องส่งพร็อพต่อผ่านทุกชั้น ค่าแบบรีแอกทีฟ (ref/reactive) จะส่งต่อการเปลี่ยนแปลงแบบรีแอกทีฟ ใช้คีย์แบบ Symbol ร่วมกับ InjectionKey เพื่อให้การ inject มีชนิดข้อมูลปลอดภัยและไม่ชนกัน ส่งค่าเริ่มต้นเป็นอาร์กิวเมนต์ตัวที่สองของ inject ใช้ readonly() เพื่อป้องกันการแก้ไข และใช้การ provide ระดับแอปสำหรับปลั๊กอินที่ทำงานข้ามแอป เป็นทางเลือกน้ำหนักเบาแทน Pinia สำหรับค่ารูปแบบปลั๊กอิน
คำถามที่พบบ่อย
บทเรียน “provide() และ inject() สำหรับการฉีดการพึ่งพา” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “provide() และ inject() สำหรับการฉีดการพึ่งพา” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Frontend Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Frontend Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “provide() และ inject() สำหรับการฉีดการพึ่งพา”
ให้ค่าที่คอมโพเนนต์บรรพบุรุษและฉีดค่าเหล่านั้นลงไปยังส่วนลึกของทรี เพื่อหลีกเลี่ยงการส่งพร็อพส์ผ่านคอมโพเนนต์หลายชั้นโดยไม่ต้องใช้ไลบรารีจัดการสถานะเต็มรูปแบบ คุณปฏิบัติ Frontend Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Frontend Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Frontend Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน
บทเรียน “provide() และ inject() สำหรับการฉีดการพึ่งพา” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Frontend Academy นี้ได้ไหม
ได้ บทเรียน Frontend Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- provide() และ inject() สำหรับการฉีดการพึ่งพา
- คอมโพเนนต์อะซิงก์และ Suspense
- คำสั่งกำหนดเอง
- ระบบปลั๊กอิน: app.use()