Vue-next: Provide/Inject ("Context") API

Created on 31 Oct 2018  路  5Comments  路  Source: vuejs/vue-next

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.

https://github.com/vuejs/vuex/issues/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>

``html <!-- Child-vue --> <Inject id="someName"> <!-- side note: I couldn't determine if we will still requireslot-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.
-->


{{ message }}

## 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?

```javascript
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...

Most helpful comment

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.

All 5 comments

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.

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.

Great, that's what I hoped for 馃榿

:+1: 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.

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mika76 picture mika76  路  3Comments

NMFES picture NMFES  路  3Comments

harrytran998 picture harrytran998  路  3Comments

pearofducks picture pearofducks  路  3Comments

jods4 picture jods4  路  4Comments