使用Provide和Inject设计Vue3插件

使用provide和inject的Vue依赖项注入非常适合构建Vue3插件或避免prop多层传递。

尽管不经常使用它,但是您可以仅使用两个内置方法来实现依赖项注入:provide和inject。

查看Composition API文档,在Vue 3.0中,使用Provide和Inject进行依赖项注入将更为常见。这主要是因为由于Composition API对this引用的更改,插件将不得不切换为使用此模式。

在本文中,我们将研究在Vue3中使用Provide和Inject以及如何将其用于构建VueJS插件

为什么Vue3插件的工作方式有所不同?

在Vue2中,大多数插件会将属性注入this。例如,通过访问Vue路由器this.$router

但是,该setup()方法不再包含对的相同引用this。进行此更改的主要原因是增加了对Typescript的支持。

Sooo,“我们现在要如何访问我们的插件?”

幸运的是,我们可以使用provideinject帮助在我们的Vue应用程序中注入依赖项。

Provide / inject用于依赖项注入–使我们能够在Vue应用程序的根目录中提供一个插件,然后将其注入子组件中。

在Composition API中,只能在setup()方法期间调用这两种方法。

什么是provide / inject?

好的-我们知道我们必须使用provide和inject,但是那怎么工作呢?

基本上,我们只需要某种键来识别我们的依赖关系–出于我们的目的,我们将使用Javascript Symbol

然后,我们的provide方法会将我们的Symbol与某个值相关联,而我们的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可以完成一些很酷的技巧。

我们可以在我们的应用程序中全局提供依赖项

如果我们想在全球范围内提供某些东西,则可以app.provide在声明Vue应用程序实例的任何地方使用。然后,我们可以像以前一样注入。

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提供反应数据

如果我们希望将反应性数据传递给子组件,这也非常方便。我们要做的就是使用传递给我们的提供方法一个反应性ref()

// in provider (parent)
const LoggedInSymbol = Symbol()
const loggedIn = ref('true')
provide(LoggedInSymbol, loggedIn)

// in consumer (descendant)
const theme = inject(LoggedInSymbol, ref('false'))

我们如何使用provide / inject?

设计插件实际上与我们刚才看到的简单的provide / inject示例非常相似。

但是,我们不想使用单个值,而是要使用合成函数。这是Vue3的巨大优势之一-能够根据功能组织和提取代码。

由于我们的代码无论如何都应该用有组织的组合函数编写,因此我们只需要创建这些provide / inject方法以及BAM-我们就有了一个插件。

让我们快速看一下Vue3 Composition API文档提供的假设插件。

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函数。然后,无论我们想在哪里使用它,都必须将其注入到我们的组件中。

组件永远不必真正进行provide / inject调用,而只需调用插件公开的provideStore / useStore方法。

所以我仍然可以使用旧的插件吗?

简短的答案? 是的。

长答案? 取决于你的意思。

由于Composition API纯粹是可加性的,因此您可以继续使用Options API,并具有与this以前相同的引用,并且所有旧插件都将工作相同。

但是,继续前进,绝对值得过渡到Vue3并利用其所有功能。

本质上,只要您想坚持使用Vue2 Options API,您的插件就可以正常工作。但是,无论如何,大多数维护良好的插件/库都应该添加对Vue3的支持。

结论

正确使用Provide / Inject绝对是 Vue开发中更高级的主题。

尽管大多数典型的应用程序不会使用这些概念,但是如果您对开发插件很认真,则Vue3 Composition API中的更改意味着您必须 使用provide / inject。

如果您想了解更多信息,请务必查看Composition API文档

参考

Designing Vue3 Plugins Using Provide and Inject

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容