使用provide和inject的Vue依賴項注入非常適合構(gòu)建Vue3插件或避免prop多層傳遞父叙。
盡管不經(jīng)常使用它躏率,但是您可以僅使用兩個內(nèi)置方法來實現(xiàn)依賴項注入:provide和inject软棺。
查看Composition API文檔县貌,在Vue 3.0中琳状,使用Provide和Inject進行依賴項注入將更為常見撕攒。這主要是因為由于Composition API對this
引用的更改蒸苇,插件將不得不切換為使用此模式磷蛹。
在本文中,我們將研究在Vue3中使用Provide和Inject以及如何將其用于構(gòu)建VueJS插件溪烤。
為什么Vue3插件的工作方式有所不同味咳?
在Vue2中庇勃,大多數(shù)插件會將屬性注入this
。例如槽驶,通過訪問Vue路由器this.$router
责嚷。
但是,該setup()
方法不再包含對的相同引用this
掂铐。進行此更改的主要原因是增加了對Typescript的支持罕拂。
Sooo,“我們現(xiàn)在要如何訪問我們的插件全陨?”
幸運的是爆班,我們可以使用provide
并inject
幫助在我們的Vue應(yīng)用程序中注入依賴項。
Provide / inject用于依賴項注入–使我們能夠在Vue應(yīng)用程序的根目錄中提供一個插件辱姨,然后將其注入子組件中柿菩。
在Composition API中,只能在setup()方法期間調(diào)用這兩種方法雨涛。
什么是provide / inject枢舶?
好的-我們知道我們必須使用provide和inject,但是那怎么工作呢替久?
基本上凉泄,我們只需要某種鍵來識別我們的依賴關(guān)系–出于我們的目的,我們將使用Javascript Symbol蚯根。
然后后众,我們的provide方法會將我們的Symbol與某個值相關(guān)聯(lián),而我們的inject方法將使用相同的Symbol檢索該值稼锅。
看一個例子更有意義吼具。
import { provide, inject } from 'vue'
const LoggedInSymbol = Symbol()
const ParentComponent = {
setup() {
provide(LoggedInSymbol, true)
}
}
const DeepDescendent = {
setup() {
// second optional param is a default value if it doesn't exist
const isLoggedIn = inject(LoggedInSymbol, false)
return {
isLoggedIn
}
}
}
通過這種模式,實際上Vue3可以完成一些很酷的技巧矩距。
我們可以在我們的應(yīng)用程序中全局提供依賴項
如果我們想在全球范圍內(nèi)提供某些東西拗盒,則可以app.provide
在聲明Vue應(yīng)用程序?qū)嵗娜魏蔚胤绞褂谩H缓笞墩覀兛梢韵褚郧耙粯幼⑷搿?/p>
main.js
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
const ThemeSymbol = Symbol()
app.provide(ThemeSymbol, 'dark')
app.mount('#app')
我們可以使用ref提供反應(yīng)數(shù)據(jù)
如果我們希望將反應(yīng)性數(shù)據(jù)傳遞給子組件陡蝇,這也非常方便。我們要做的就是使用傳遞給我們的提供方法一個反應(yīng)性ref()
哮肚。
// in provider (parent)
const LoggedInSymbol = Symbol()
const loggedIn = ref('true')
provide(LoggedInSymbol, loggedIn)
// in consumer (descendant)
const theme = inject(LoggedInSymbol, ref('false'))
我們?nèi)绾问褂胮rovide / inject登夫?
設(shè)計插件實際上與我們剛才看到的簡單的provide / inject示例非常相似。
但是允趟,我們不想使用單個值恼策,而是要使用合成函數(shù)。這是Vue3的巨大優(yōu)勢之一-能夠根據(jù)功能組織和提取代碼。
由于我們的代碼無論如何都應(yīng)該用有組織的組合函數(shù)編寫涣楷,因此我們只需要創(chuàng)建這些provide / inject方法以及BAM-我們就有了一個插件分唾。
讓我們快速看一下Vue3 Composition API文檔提供的假設(shè)插件。
Plugin.js
const StoreSymbol = Symbol()
export function provideStore(store) {
provide(StoreSymbol, store)
}
export function useStore() {
const store = inject(StoreSymbol)
if (!store) {
// throw error, no store provided
}
return store
}
然后狮斗,我們的實際組件將像這樣使用它绽乔。
// provide store at component root
//
const App = {
setup() {
provideStore(store)
}
}
const Child = {
setup() {
const store = useStore()
// use the store
}
}
如您所見,在某些根組件中碳褒,我們提供了插件折砸,并向其傳遞了composition函數(shù)。然后沙峻,無論我們想在哪里使用它睦授,都必須將其注入到我們的組件中。
組件永遠不必真正進行provide / inject調(diào)用摔寨,而只需調(diào)用插件公開的provideStore / useStore方法睹逃。
所以我仍然可以使用舊的插件嗎?
簡短的答案祷肯? 是的。
長答案疗隶? 取決于你的意思佑笋。
由于Composition API純粹是可加性的,因此您可以繼續(xù)使用Options API斑鼻,并具有與this
以前相同的引用蒋纬,并且所有舊插件都將工作相同。
但是赶促,繼續(xù)前進派撕,絕對值得過渡到Vue3并利用其所有功能蚁孔。
本質(zhì)上,只要您想堅持使用Vue2 Options API碾阁,您的插件就可以正常工作。但是些楣,無論如何脂凶,大多數(shù)維護良好的插件/庫都應(yīng)該添加對Vue3的支持。
結(jié)論
正確使用Provide / Inject絕對是 Vue開發(fā)中更高級的主題愁茁。
盡管大多數(shù)典型的應(yīng)用程序不會使用這些概念蚕钦,但是如果您對開發(fā)插件很認真,則Vue3 Composition API中的更改意味著您必須 使用provide / inject鹅很。
如果您想了解更多信息嘶居,請務(wù)必查看Composition API文檔。