免费照片的网站模板免费下载,wordpress 支付接口,网站导航做外链,域名主机基地1. 基本概念
provide/inject 是 Vue3 中实现跨层级组件通信的方案#xff0c;类似于 React 的 Context。它允许父组件向其所有子孙组件注入依赖#xff0c;无论层级有多深。
1.1 基本语法
// 提供方#xff08;父组件#xff09;
const value ref(hello)
provide(key, …1. 基本概念
provide/inject 是 Vue3 中实现跨层级组件通信的方案类似于 React 的 Context。它允许父组件向其所有子孙组件注入依赖无论层级有多深。
1.1 基本语法
// 提供方父组件
const value ref(hello)
provide(key, value)// 注入方子孙组件
const value inject(key)2. 基础用法
2.1 提供静态值
!-- Parent.vue --
script setup
import { provide } from vue// 提供静态值
provide(theme, dark)
provide(language, zh-CN)
/script!-- Child.vue --
script setup
import { inject } from vue// 注入值
const theme inject(theme)
const language inject(language)
/scripttemplatediv :classthemepCurrent Language: {{ language }}/p/div
/template2.2 提供响应式数据
!-- Parent.vue --
script setup
import { provide, ref } from vueconst count ref(0)
const updateCount () {count.value
}// 提供响应式数据和更新方法
provide(count, {count,updateCount
})
/script!-- Child.vue --
script setup
import { inject } from vueconst { count, updateCount } inject(count)
/scripttemplatedivpCount: {{ count }}/pbutton clickupdateCountIncrement/button/div
/template3. 进阶用法
3.1 使用 Symbol 作为 key
// injection-keys.ts
export const COUNT_KEY Symbol(count)
export const THEME_KEY Symbol(theme)!-- Parent.vue --
script setup langts
import { provide } from vue
import { COUNT_KEY, THEME_KEY } from ./injection-keysconst count ref(0)
provide(COUNT_KEY, count)
provide(THEME_KEY, dark)
/script!-- Child.vue --
script setup langts
import { inject } from vue
import { COUNT_KEY, THEME_KEY } from ./injection-keysconst count inject(COUNT_KEY)
const theme inject(THEME_KEY)
/script3.2 提供默认值
script setup
import { inject } from vue// 使用静态默认值
const theme inject(theme, light)// 使用工厂函数作为默认值
const now inject(timestamp, () Date.now())
/script3.3 只读数据
!-- Parent.vue --
script setup
import { provide, ref, readonly } from vueconst count ref(0)
// 提供只读版本防止子组件修改
provide(count, readonly(count))// 提供更新方法
provide(updateCount, () {count.value
})
/script!-- Child.vue --
script setup
import { inject } from vueconst count inject(count)
const updateCount inject(updateCount)
/script4. 实际应用场景
4.1 主题系统
!-- ThemeProvider.vue --
script setup
import { provide, ref } from vueconst theme ref(light)
const toggleTheme () {theme.value theme.value light ? dark : light
}provide(theme, {theme,toggleTheme
})
/scripttemplatediv :classtheme.valueslot/slot/div
/template!-- 使用组件 --
script setup
import { inject } from vueconst { theme, toggleTheme } inject(theme)
/scripttemplatebutton clicktoggleThemeSwitch to {{ theme light ? dark : light }} mode/button
/template4.2 多语言系统
!-- I18nProvider.vue --
script setup
import { provide, ref } from vueconst locale ref(en)
const messages {en: {greeting: Hello,farewell: Goodbye},zh: {greeting: 你好,farewell: 再见}
}const t (key) messages[locale.value][key]
const setLocale (lang) {locale.value lang
}provide(i18n, {locale,t,setLocale
})
/script!-- 使用组件 --
script setup
import { inject } from vueconst { t, setLocale, locale } inject(i18n)
/scripttemplatedivselect v-modellocaleoption valueenEnglish/optionoption valuezh中文/option/selectp{{ t(greeting) }}/p/div
/template4.3 状态管理
!-- Store.vue --
script setup
import { provide, reactive } from vueconst store reactive({user: null,todos: [],addTodo(text) {this.todos.push({ id: Date.now(), text, completed: false })},toggleTodo(id) {const todo this.todos.find(t t.id id)if (todo) {todo.completed !todo.completed}}
})provide(store, store)
/script!-- TodoList.vue --
script setup
import { inject } from vueconst store inject(store)
/scripttemplatedivinputv-modelnewTodokeyup.enterstore.addTodo(newTodo)ulliv-fortodo in store.todos:keytodo.idclickstore.toggleTodo(todo.id){{ todo.text }}/li/ul/div
/template5. TypeScript 支持
5.1 类型定义
// types.ts
export interface ThemeContext {theme: Reflight | darktoggleTheme: () void
}export const ThemeSymbol Symbol(theme)5.2 带类型的 provide/inject
script setup langts
import { provide, inject } from vue
import { ThemeContext, ThemeSymbol } from ./types// 提供方
provideThemeContext(ThemeSymbol, {theme: ref(light),toggleTheme: () { /* ... */ }
})// 注入方
const theme injectThemeContext(ThemeSymbol)
/script6. 最佳实践 使用 Symbol 作为 key const MyKey Symbol(my-key)
provide(MyKey, value)提供只读数据 provide(data, readonly(data))集中管理 injection key // keys.ts
export const THEME_KEY Symbol(theme)
export const I18N_KEY Symbol(i18n)使用组合式函数封装 // useTheme.ts
export function useTheme() {const theme inject(THEME_KEY)if (!theme) {throw new Error(useTheme must be used within ThemeProvider)}return theme
}7. 注意事项 响应性 确保提供响应式数据时使用 ref 或 reactive注意数据的可变性和只读性 默认值 提供合理的默认值考虑使用工厂函数作为默认值 类型安全 使用 TypeScript 定义接口使用 Symbol 作为 key 性能考虑 避免提供过大的数据结构合理划分提供的数据范围
通过合理使用 provide/inject我们可以有效地管理跨组件通信构建可维护的组件树。但要注意避免过度使用以免造成数据流向难以追踪的问题。