diff --git a/client/docs/composables.md b/client/docs/composables.md new file mode 100644 index 00000000000..af133410444 --- /dev/null +++ b/client/docs/composables.md @@ -0,0 +1,106 @@ +# Composables + +Composables are way of splitting up your code into distinct, reusable chunks. +They can replace providers, mixins and more. Any code you can put into a component, can also be written as a composable. +Using them effectively can make your code more reusable, decoupled, and easier to follow. + +## Using Composables in the Composition API + +Example: accessing the current user from the store + +```vue + +``` + +You can now access the current user with `currentUser.value`. + +## Using Composables in the Options API + +Composables are not limited to the composition api. This is the same example from above, using the options api. + +```vue + +``` + +You can now access the current user with `this.currentUser` from anywhere within the component. + +## Testing Components with Composable Stores + +When writing a test which includes a component that has a composable store (like useCurrentUser), +there are two ways to test it. + +### Mocking the store + +You can provide the store in the mount function as follows: + +```js +const wrapper = shallowMount(TestedComponent, + localVue, + provide: { store }, +}); +``` + +`store` must be a Vuex store. +The `mockModule` helper can help creating a store for the required modules: + +```js +const store = new Vuex.Store({ + modules: { + user: mockModule(userStore), + }, +}); +``` + +### Mocking the composable + +The second option is to mock the composable: + +```js +import { useCurrentUser } from "composables/user"; + +jest.mock("composables/user"); +useCurrentUser.mockReturnValue({ + currentUser: {} +}); +``` + +While simpler in this example, you may need to manually mock more return values and composables than the other method, depending on the composables the component is using. + +## Using Composables for more than Stores + +Composables can be of great use to extract any reactive code from your components. For an example of this, take a look at [userFilterObjectArray](https://github.com/galaxyproject/galaxy/blob/dev/client/src/composables/utils/filter.js). + +Usage: + +```vue + +``` + +It's a simple filtering function, but fully reactive. +Whenever any of the inputs changes, the return value is re-computed, without having to call the function again. + +## Further Reading + +* [Composition API](https://vuejs.org/api/composition-api-setup.html) +* [\