docs icon indicating copy to clipboard operation
docs copied to clipboard

Add a doc section on composables with guidelines about how to write them in the correct idiomatic way

Open julie777 opened this issue 4 years ago • 2 comments

There are some significant composable libraries out there. And, since using the composition api and composables is such a great reuse tool it would be nice to know how to avoid problems.

Document the "useFeature" paradigm and how it interacts with the component scope and how reactivity works. Examples, some of which I still don't understand fully:

  • why the useFeature naming is a good idea
  • does useFeature need to be exported by name like import {useRoute} from 'vue-router or should I export it as the default
  • global vs local/component scope in the composable
  • if I create a composable useFeature and it needs to use vue router then useRouter() must be inside the useFeature function so it ends up in the proper scope in the component.
  • how does reactivity work
    • computed function inside useFeature function
    • computed function outside useFeature function
    • passing a component prop to useFeature(props.something)
    • etc

julie777 avatar Oct 22 '21 19:10 julie777

Would be great to have this kind of guidance in the style guide. This could be a good issue to start collecting people's opinions.

Here are my opinions on the points you raised (informed by my work on Baleada Vue Features):

why the useFeature naming is a good idea

  • Consistent naming is a good idea in general
  • useFeature has emerged from React as a standard in the front end community. No good reason to break that rule since it seems to work well in the Vue ecosystem too

I have a personal style guide that requires useSomething functions to meet two conditions:

  • useSomething must internally use reactivity APIs, and possibly perform side effects during a component lifecycle (i.e. I must set up at least one watcher or lifecycle hook)
  • useSomething must have a return value that includes reactive state

does useFeature need to be exported by name

Exporting by name and avoiding export default, even when we're only exporting one thing from a file, is generally considered the best way to avoid edge cases and difficult bugs with build tools.

global vs local/component scope in the composable

We shouldn't use global stores until we have a good reason to do so. I'm not clear yet on exactly what those reasons might be, but I believe the VueUse project does some global store stuff internally, so that code is worth studying.

Using third party composition functions like useRouter inside your own composition functions

Always pretend we're writing code inside a setup function, even if we've abstracted several steps away from setup. Reactivity APIs should never be used outside setup, unless we fully understand why and how to use effectScope to collect and clean up side effects.

Same goes for third party code. Don't use third party composition functions outside of setup unless we're confident the authors understand and use effectScope. Pinia, for example, allows us to use reactivity APIs inside its defineStore function, because it uses effectScope to collect any side effects we create, and clean them up if the root Vue instance gets torn down.

how does reactivity work

Exactly the same as it would in a setup function.

AlexVipond avatar Nov 17 '21 18:11 AlexVipond

I believe this chapter partly covers the request for Composables section: https://vuejs.org/guide/reusability/composables.html#async-state-example

NataliaTepluhina avatar Feb 07 '22 12:02 NataliaTepluhina