美文网首页
使用Provide和Inject设计Vue3插件

使用Provide和Inject设计Vue3插件

作者: 魂斗驴 | 来源:发表于2021-04-21 10:00 被阅读0次

    使用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

    相关文章

      网友评论

          本文标题:使用Provide和Inject设计Vue3插件

          本文链接:https://www.haomeiwen.com/subject/ihmklltx.html