vuejs / core

🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
https://vuejs.org/
MIT License
47.79k stars 8.35k forks source link

Using provide/inject in a directive #5002

Open LancerComet opened 3 years ago

LancerComet commented 3 years ago

What problem does this feature solve?

Sometime you need to provide something from the root component, then the provide is really useful for this:

<MyApp>
   // This thing just provides something, like: provide('my-stuff', ...)
</MyApp>

And sometime you want to inject my-stuff into a directive:

const MyDirective: Directive = {
  created: (el, binding) => {
    inject('my-stuff')  // [Vue warn]: inject() can only be used inside setup() or functional components.
  }
}

For now you can't do that. And yes, there are many workarounds to solve this problem, but I think this, lets say, is the most decent way to perform.

Any possibility?

What does the proposed API look like?

const MyDirective: Directive = {
  created: (el, binding) => {
    const myStuff = inject('my-stuff')  // It works!
  }
}
liuzw2579 commented 1 year ago

why this not to do?

cmath10 commented 1 year ago

Any updates? In my application, I create smaller Vue apps for custom tooltips, and Inject API can significantly reduce the number of options I need to pass to my directive.

MetRonnie commented 6 months ago

I think it would be really useful to have a directive called v-provide so that you can make any component a dependency provider without being required to add this to the component's setup, or having to user a wrapper component.

E.g.,

<!-- A root component -->
<template>
  <div>
    <component
      v-for="{ component, thing } in components"
      :is="component"
      v-provide:mykey="thing"
    />
  ...
</template>

<script setup>
import { provide } from 'vue'
...
const vProvide = {
  created (el, binding) {
    provide(binding.arg, binding.value)
  }
}
...
</script>

My specific use case at the moment is I need to provide siloed event buses for each component in the v-for loop.