Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide/Inject ("Context") API #13

Closed
LinusBorg opened this issue Oct 31, 2018 · 5 comments
Closed

Provide/Inject ("Context") API #13

LinusBorg opened this issue Oct 31, 2018 · 5 comments

Comments

@LinusBorg
Copy link
Member

LinusBorg commented Oct 31, 2018

For Reference: https://github.com/vuejs/vue-next/blob/master/packages/runtime-core/src/optional/context.ts

So I took a look at the new implementation and I have some reservations about it.

vuejs/vuex#1417

The current implementation in vue-next

As of this writing, vue-next will implement Context (or as we call it: provide/Inject) as a pair of components:

<!-- Parent.vue -->
<Provide id="someName" :value="{ message: 'Hello Vue!' }">
  <Child />
</Provide>
<!-- Child-vue -->
<Inject id="someName">
  <!-- side note: I couldn't determine if we will still require `slot-scope` 
       to be set on the root slot element, or if we provide a way to define it 
       on the component providing the slot itself.
  -->
  <div slot-scope="{ message }">
    {{ message }}
  <div>
</inject>

Reservations/Issues with this implementation

My reservations mostly originate from the discussions in the vuex repository about the proposed removal of mapXXX helpers in the next major of vuex here:

https://github.com/vuejs/vue-next/blob/master/packages/runtime-core/src/optional/context.ts

The important point is this one:

vuex state/getters/actions are only conveniently available in templates and render functions. That means the convenience is unavailable for computed properties that rely on Vuex state and methods that dispatch Vuex actions, which is a big limitation.

I think <Inject> suffers from similar problems. A component that uses <Inject> can only access the provided data within the template, so computed properties and watch callbacks have no way of accessing that data.

It works for React because React has neither of those things, it only has state, props and methods. So you can easily pass the injected data as an argument to a component method. But a similar thing is not possible for computed or watch functions since those don't take arguments.

Hooks

Maybe the new hot kid in town, Hooks, can solve this problem?

import { useInject } from 'vue'

export default {
  hooks() {
    const [injectedData] = useInject('someName')
    return {  
      injectedData 
    }
  }
}

That doesn't mean we have to drop <Inject>, I think it's still convenient for situations where accessing the injected Data in the template / render function is enough. But we need a way to allow users to actually inject this data as a property on the component instance.

The issue with a hook would be that we make this dependent on an experimental feature.

Backwards compatibility

We sold provide/inject as a feature primarily targeted at library authors. Dropping the old syntax from Vue 2 would be another breaking change that may be a roadblock for people updating their projects, as libs using this feature would have to find a way to make it work with the new component-based approach.

So this is another feature I think we should provide compat version for...

@LinusBorg LinusBorg changed the title New Provide/Inject ("Context") API Provide/Inject ("Context") API Oct 31, 2018
@znck
Copy link
Member

znck commented Oct 31, 2018

I share your concerns, I checked all the places I have used provide/inject and in most the injected state is used either in a method or in a computed property.

@yyx990803
Copy link
Member

Absolutely, I wanted to expose a Vue-2 similar API eventually. This was just an experiment to see how it would look like as components.

@LinusBorg
Copy link
Member Author

Great, that's what I hoped for 😁

@KaelWD
Copy link
Contributor

KaelWD commented Nov 1, 2018

👍 we use provide/inject pretty much everywhere in vuetify, so keeping the 2.x API (or something like it) is vital for us to be able to update to 3 without a massive rewrite. Also like @znck, most of our usage is in computed properties.

@rstoenescu
Copy link

Quasar relies on 2.x API for provide/inject in a lot of places too. I really like the useInject hook idea and I think that would fit great.

@github-actions github-actions bot locked and limited conversation to collaborators Nov 17, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants