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

Setup context hook for dependency injection #1598

Closed
AlexandreBonaventure opened this issue Jul 16, 2020 · 8 comments
Closed

Setup context hook for dependency injection #1598

AlexandreBonaventure opened this issue Jul 16, 2020 · 8 comments
Labels
✨ feature request New feature or request

Comments

@AlexandreBonaventure
Copy link
Contributor

What problem does this feature solve?

Here is a utility helper I like to use

export function useLocalModel ({ props, emit }, propName) {
  return computed({
    get () {
      return props[propName];
    },
    set (val) {
      emit(`update:${propName}`, val);
    },
  });
}

Here, the dependency injection is cumbersome / no conventions + no standard (should the argument be the first one ? the last one ?)

What does the proposed API look like?

Thinking about it, I came up with an elegant solution, that I don't think would be super difficult to implement:
Introduce a new built-in useContext composition function that would allow users to get the current setup function context (props, attrs, emit, slots).
Here it will make this composition a lot more clean and simple:

import { useContext } from 'vue'
export function useLocalModel (propName) {
  const { props, emit } = useContext()
  return computed({
    get () {
      return props[propName];
    },
    set (val) {
      emit(`update:${propName}`, val);
    },
  });
}

This is probably too simple to raise a RFCs but if there is a need, feel free to ask.
Regards.

@aztalbot
Copy link
Contributor

aztalbot commented Jul 16, 2020

Could you use the existing getCurrentInstance function for what you are trying to do?

import { getCurrentInstance } from "vue"
export function useContext() {
  const { props, emit, slots, attrs } = getCurrentInstance()
  return { props, emit, slots, attrs } // assuming you aren't interested in the whole vm
}

The main caveat here I think is that the props, slots, and attrs in setup have an additional proxy wrapper around each of them, and when using getCurrentInstance you have unproxied slots and attrs (and one less proxy around props). Not sure if that might introduce some inconsistencies.

@AlexandreBonaventure
Copy link
Contributor Author

@aztalbot I was not aware of this API, sounds like it's exactly what I'm looking for! thanks.
I leave it open because of

The main caveat here I think is that the props, slots, and attrs in setup have an additional proxy wrapper around each of them, and when using getCurrentInstance you have unproxied slots and attrs (and one less proxy around props). Not sure if that might introduce some inconsistencies.

@AlexandreBonaventure
Copy link
Contributor Author

AlexandreBonaventure commented Jul 16, 2020

well, in my mind composition API scope is much bigger than just dealing with reusable state & lifecycle. To me it was brought in to overcome shared component logic issues with mixins as a whole.

@CyberAP
Copy link
Contributor

CyberAP commented Jul 16, 2020

You can have the same thing in options API without the need for extra hooks just by using a factory function:

export const createPropModel = (propName) => ({
  get () { return this[propName] },
  set (value) { this.$emit(`update:${propName}`, value) }
})

@AlexandreBonaventure
Copy link
Contributor Author

@CyberAP I don't really get your point..
The goal is to use the composition API here.

@CyberAP
Copy link
Contributor

CyberAP commented Jul 16, 2020

Composition API is not an ideal candidate for this task it seems to me. getCurrentInstance is an advanced API for plugins and I think it's not a best suit to automate computed model creation. Instead I'd suggest to take a look at this RFC which aims to simplify the exact same task, but in a declarative manner.

@pikax
Copy link
Member

pikax commented Jul 19, 2020

getCurrentInstance is advanced api and you should be really careful using it, in this case I believe is fair to use it.

There's my implementation of the vmodel composable https://github.com/pikax/vue-composable/blob/master/packages/vue-composable/src/misc/vmodel.ts

@LinusBorg LinusBorg added the ✨ feature request New feature or request label Dec 17, 2020
@HcySunYang
Copy link
Member

@github-actions github-actions bot locked and limited conversation to collaborators Oct 22, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
✨ feature request New feature or request
Projects
None yet
Development

No branches or pull requests

6 participants