Add a doc section on composables with guidelines about how to write them in the correct idiomatic way
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-routeror should I export it as the default - global vs local/component scope in the composable
- if I create a composable
useFeatureand it needs to use vue router thenuseRouter()must be inside theuseFeaturefunction 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
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:
useSomethingmust 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)useSomethingmust 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.
I believe this chapter partly covers the request for Composables section: https://vuejs.org/guide/reusability/composables.html#async-state-example