疯狂的技术宅

以前出于工作目的,编写和翻译了大量的技术文章,以前端为主,删掉了过时的、毫无营养的内容,留下的都是精华。


  • 首页

  • 分类

  • 标签

  • 归档

  • 关于本站

  • 回到主站

  • 搜索

用 Provide 和 Inject 设计Vue3插件

时间: 2021-05-26 分类: 前端技术   字数: 1267 字 阅读: 3分钟
标签: #Vue3# #插件# #Inject#

使用 Provide 和 Inject 的 Vue依赖项注入对于构建Vue3插件或避免 prop 钻取非常有用。

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

通过查看 Composition API 文档会发现,在 Vue 3.0 中,使用 Provide 和 Inject 进行依赖项注入更为常见。 这主要是因为 Composition API 对 this 引用的更改,插件必须切换为这种模式才行。

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

为什么 Vue3 插件的工作方式与以往不同

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

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

那么在 Vue3 中该如何访问我们的插件呢?可以用 provide 和 inject 来帮助我们在 Vue 程序中注入依赖项。 Provide/inject 用于依赖项注入,可以使我们能在 Vue 程序的根目录中提供插件,并且然后将其注入子组件中。

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

什么是 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() {
    // 第二个可选参数是默认值(如果不存在)
    const isLoggedIn = inject(LoggedInSymbol, false)
    return {
      isLoggedIn
    }
  }
}

Vue3 通过这种模式可以实现一些很实用的技巧。

可以在程序中全局提供依赖项

如果我们想在全局作用域中提供一些东西,可以在声明我们的 VUE 实例的时候下用 app.provide。然后可以用相同的方式进行注入。

main.jsimport { createApp } from 'vue'
import App from './App.vue'


const app = createApp(App)

const ThemeSymbol = Symbol()
app.provide(ThemeSymbol, 'dark')


app.mount('#app')

可以用 ref 提供响应式数据

如果我们希望将响应式数据传递给子组件,这也非常方便。只需要用 ref() 传递我们方法的一个响应式的属性。

// 生产者r (父组件)
const LoggedInSymbol = Symbol()
const loggedIn = ref('true')
provide(LoggedInSymbol, loggedIn)

// 消费者 (子组件)
const theme = inject(LoggedInSymbol, ref('false'))

怎样在插件中使用 provide 和 inject

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

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

由于我们的代码无论如何都应该用有组织的组合函数编写,所以只需要创建这些 provide 和 inject 方法就能够写出一个插件。

先简单的看一下 Vue3 Composition API 文档中提供的插件例子。

Plugin.jsconst 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
}

在实际的组件中会这样使用:

// 在组件根目录提供 store
//
const App = {
  setup() {
    provideStore(store)
  }
}

const Child = {
  setup() {
    const store = useStore()
    // use the store
  }
}

根据上述代码,在某些根组件中,我们提供了插件,并向其传递了组件函数。然后无论想在哪里使用都必须将其注入到我们的组件中。

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

还能用旧的插件吗

简单的来说是:能。如果多说点,那就是取决于你自己的想法。

可以继续使用 Options API,并且对 this 的引用方式与以前相同,并且所有旧插件的工作方式都不变。

但是迁移到 Vue3 并利用其所有功能觉得是值得的。

只要你想用 Vue2 的 Options API,你的插件就可以正常工作。但是,很多维护良好的插件或库都应该添加对 Vue3 的支持。

总结

正确使用 provide/inject 绝对能够提高你对 Vue 的驾驭能力。

尽管很多应用并不会使用这些概念,但是如果你认真开发插件,则 Vue3 的 Composition API 意味着你必须使用provide 和 inject。

标签: #Vue3# #插件# #Inject#

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

链接:https://fe-tech.viewnode.com/post/202105/26/

作者:疯狂的技术宅

声明: 本博客文章除特别声明外,均采用 CC BY-NC-ND 4.0 国际许可协议( 知识共享署名-非商业性使用-禁止演绎 4.0),转载请注明出处!

10 分钟用vue实现自定义 Tag Input 功能
Vue3 中的包装器组件
  • 文章目录
  • 站点概览
疯狂的技术宅

疯狂的技术宅

退休程序员,硬件发烧友,人工智能爱好者。写写代码喝喝茶,晒晒太阳带带娃。

457 日志
8 分类
583 标签
GitHub
友情链接
  • viewnode
  • mofish
标签云
  • Javascript 172
  • Node.Js 62
  • Vue 36
  • Typescript 28
  • 实战项目 28
  • 面试 21
  • React 20
  • Css 17
  • 面试题 16
  • 教程 13
  • Promise 12
  • Chrome 9
  • Debug 9
  • 调试 9
  • 资源 9
  • Deno 8
  • Dom 8
  • 杂谈 8
  • 正则表达式 8
  • 测试 8
  • 为什么 Vue3 插件的工作方式与以往不同
  • 什么是 provide 和 inject
    • 可以在程序中全局提供依赖项
    • 可以用 ref 提供响应式数据
  • 怎样在插件中使用 provide 和 inject
  • 还能用旧的插件吗
  • 总结
© 2018 - 2022 疯狂的技术宅 All Rights Reserved
Powered by - Hugo v0.99.0 / Theme by - NexT
Storage by 俺的服务器 / 冀ICP备2022010157号
0%