vuex-composition-helpers
Version:
Helpers to use Vuex store form Vue Composition API
284 lines (231 loc) • 6.93 kB
Markdown
# vuex-composition-helpers

[](https://badge.fury.io/js/vuex-composition-helpers)
A util package to use Vuex with Composition API easily.
## Installation
```shell
$ npm install vuex-composition-helpers
```
For Vue 3.x - use the `next` tag:
```shell
$ npm install vuex-composition-helpers@next
```
This library is not transpiled by default. Your project should transpile it, which makes the final build smaller and more tree-shakeable. Take a look at [transpiling](#transpiling).
Non-typescript projects may import the library from the `dist` subdirectory, where plain javascript distribution files are located.
```
import { useState, ... } from 'vuex-composition-helpers/dist';
```
### Basic Usage Examples
```js
import { useState, useActions } from 'vuex-composition-helpers';
export default {
props: {
articleId: String
},
setup(props) {
const { fetch } = useActions(['fetch']);
const { article, comments } = useState(['article', 'comments']);
fetch(props.articleId); // dispatch the "fetch" action
return {
// both are computed compositions for to the store
article,
comments
}
}
}
```
### Namespaced Usage Examples
#### `createNamespacedHelpers`
```js
import { createNamespacedHelpers } from 'vuex-composition-helpers';
const { useState, useActions } = createNamespacedHelpers('articles'); // specific module name
export default {
props: {
articleId: String
},
setup(props) {
const { fetch } = useActions(['fetch']);
const { article, comments } = useState(['article', 'comments']);
fetch(props.articleId); // dispatch the "fetch" action
return {
// both are computed compositions for to the store
article,
comments
}
}
}
```
You can also import your store from outside the component, and create the helpers outside of the `setup` method, for example:
```js
import { createNamespacedHelpers } from 'vuex-composition-helpers';
import store from '../store'; // local store file
import const { useState, useActions } = createNamespacedHelpers(store, 'articles'); // specific module name
const { fetch } = useActions(['fetch']);
export default {
props: {
articleId: String
},
setup(props) {
const { article, comments } = useState(['article', 'comments']);
fetch(props.articleId); // dispatch the "fetch" action
return {
// both are computed compositions for to the store
article,
comments
}
}
}
```
#### Inline namespacing
```js
import { useState, useActions } from 'vuex-composition-helpers';
export default {
setup(props) {
const { article, comments } = useState('sections/blog', ['article', 'comments']);
return { article, comments }
}
}
```
### Typescript mappings
You can also supply typing information to each of the mapping functions to provide a fully typed mapping.
```ts
import { useState, useActions } from 'vuex-composition-helpers';
interface RootGetters extends GetterTree<any, any> {
article: string;
comments: string;
}
interface RootActions extends ActionTree<any, any> {
fetch: (ctx: ActionContext<any, any>, payload: number);
}
export default {
props: {
articleId: String
},
setup(props) {
const { fetch } = useActions<RootActions>(['fetch']);
const { article, comments } = useGetters<RootGetters>(['article', 'comments']);
fetch(props.articleId); // dispatch the "fetch" action
return {
// both are computed compositions for to the store
article,
comments
}
}
}
```
#### Typescript Namespaced Usage Example
```ts
import { useState, useActions } from 'vuex-composition-helpers';
import { ModuleState, ModuleGetters, ModuleActions, ModuleMutations } from "../store/subModule"
export default {
props: {
articleId: String
},
setup(props) {
const { useState, useActions } = createNamespacedHelpers<
ModuleState,
ModuleGetters,
ModuleActions,
ModuleMutations
>('articles'); // specific module name and generics
const { fetch } = useActions(['fetch']); // no generics needed any more
const { article, comments } = useGetters(['article', 'comments']); // no generics needed any more
fetch(props.articleId); // dispatch the "fetch" action
return {
// both are computed compositions for to the store
article,
comments
}
}
}
```
### Advanced Usage Example
Consider separate the store composition file from the store usage inside the component. i.g.:
```js
// store-composition.js:
import { wrapStore } from 'vuex-composition-helpers';
import store from '@/store'; // local store file
export default wrapStore(store);
```
```js
// my-component.vue:
import { createNamespacedHelpers } from './store-composition.js';
const { useState, useActions } = createNamespacedHelpers('articles'); // specific module name
const { fetch } = useActions(['fetch']);
export default {
props: {
articleId: String
},
setup(props) {
const { article, comments } = useState(['article', 'comments']);
fetch(props.articleId); // dispatch the "fetch" action
return {
// both are computed compositions for to the store
article,
comments
}
}
}
```
### Transpiling
It depends on you project's stack, but let's say it consists of webpack, babel and ts-loader.
The rule processing `.ts` files should whitelist vuex-composition-helpers. If your project uses a raw webpack installation, it should resemble this.
```js
// webpack.config.js
module.exports = {
...
module: {
rules: [
test: /\.ts$/,
// If node_modules is excluded from the rule, vuex-composition-helpers should be an exception
exclude: /node_modules(?!\/vuex-composition-helpers)/,
use: [
{
loader: 'babel-loader',
...
},
{
loader: 'thread-loader',
options: { ... }
},
{
loader: 'ts-loader',
...
}
]
}
}
```
When using `vue-cli`, use this instead
```js
// vue.config.js
module.exports = {
...
chainWebpack: config => {
config
.rule('ts')
.include
.add(/vuex-composition-helpers/)
}
}
```
If your webpack configuration is excluding `node_modules` from the bundle, which is common for SSR, this library should be an exception.
```
// webpack.config.js
module.exports = {
...
externals: [nodeExternals({
whitelist: [/^vuex-composition-helpers/]
})],
}
```
Babel should not `exclude` or `ignore` this library. If you use `vue-cli`, you may need the following configuration.
```js
// vue.config.js
module.exports = {
...
transpileDependencies: ['vuex-composition-helpers'],
}
```
Although it's not strictly required, maybe ts-loader needs to have `allowTsInNodeModules` enabled in your project. Finally check that this library is not excluded in `tsconfig.json`, and if it was necessary, put it in the `include` list.
Enjoy!