diff --git a/docs/en/api.md b/docs/en/api.md index e7ac2320e..39455a000 100644 --- a/docs/en/api.md +++ b/docs/en/api.md @@ -193,3 +193,7 @@ const store = new Vuex.Store({ ...options }) Create component methods options that commit a mutation. [Details](mutations.md#commiting-mutations-in-components) The first argument can optionally be a namespace string. [Details](modules.md#binding-helpers-with-namespace) + +- **`createNamespacedHelpers(namespace: string): Object`** + + Create namespaced component binding helpers. The returned object contains `mapState`, `mapGetters`, `mapActions` and `mapMutations` that are bound with the given namespace. [Details](modules.md#binding-helpers-with-namespace) diff --git a/docs/en/modules.md b/docs/en/modules.md index 77061def2..ea8c876f6 100644 --- a/docs/en/modules.md +++ b/docs/en/modules.md @@ -206,6 +206,31 @@ methods: { } ``` +Furthermore, you can create namespaced helpers by using `createNamespacedHelpers`. It returns an object having new component binding helpers that are bound with the given namespace value: + +``` js +import { createNamespacedHelpers } from 'vuex' + +const { mapState, mapActions } = createNamespacedHelpers('some/nested/module') + +export default { + computed: { + // look up in `some/nested/module` + ...mapState({ + a: state => state.a, + b: state => state.b + }) + }, + methods: { + // look up in `some/nested/module` + ...mapActions([ + 'foo', + 'bar' + ]) + } +} +``` + #### Caveat for Plugin Developers You may care about unpredictable namespacing for your modules when you create a [plugin](plugins.md) that provides the modules and let users add them to a Vuex store. Your modules will be also namespaced if the plugin users add your modules under a namespaced module. To adapt this situation, you may need to receive a namespace value via your plugin option: diff --git a/types/helpers.d.ts b/types/helpers.d.ts index dc0fbd505..e7c791e73 100644 --- a/types/helpers.d.ts +++ b/types/helpers.d.ts @@ -1,32 +1,52 @@ import Vue = require("vue"); type Dictionary = { [key: string]: T }; +type Computed = () => any; +type MutationMethod = (...args: any[]) => void; +type ActionMethod = (...args: any[]) => Promise; -export function mapState (map: string[]): Dictionary<() => any>; -export function mapState (namespace: string, map: string[]): Dictionary<() => any>; -export function mapState (map: Dictionary): Dictionary<() => any>; -export function mapState (namespace: string, map: Dictionary): Dictionary<() => any>; -export function mapState ( - map: Dictionary<(this: typeof Vue, state: S, getters: any) => any> -): Dictionary<() => any>; -export function mapState ( - namespace: string, - map: Dictionary<(this: typeof Vue, state: S, getters: any) => any> -): Dictionary<() => any>; +interface Mapper { + (map: string[]): Dictionary; + (map: Dictionary): Dictionary; +} -type MutationMethod = (...args: any[]) => void; -export function mapMutations (map: string[]): Dictionary; -export function mapMutations (namespace: string, map: string[]): Dictionary; -export function mapMutations (map: Dictionary): Dictionary; -export function mapMutations (namespace: string, map: Dictionary): Dictionary; - -export function mapGetters (map: string[]): Dictionary<() => any>; -export function mapGetters (namespace: string, map: string[]): Dictionary<() => any>; -export function mapGetters (map: Dictionary): Dictionary<() => any>; -export function mapGetters (namespace: string, map: Dictionary): Dictionary<() => any>; - -type ActionMethod = (...args: any[]) => Promise; -export function mapActions (map: string[]): Dictionary; -export function mapActions (namespace: string, map: string[]): Dictionary; -export function mapActions (map: Dictionary): Dictionary; -export function mapActions (namespace: string, map: Dictionary): Dictionary; +interface MapperWithNamespace { + (namespace: string, map: string[]): Dictionary; + (namespace: string, map: Dictionary): Dictionary; +} + +interface MapperForState { + ( + map: Dictionary<(this: typeof Vue, state: S, getters: any) => any> + ): Dictionary; +} + +interface MapperForStateWithNamespace { + ( + namespace: string, + map: Dictionary<(this: typeof Vue, state: S, getters: any) => any> + ): Dictionary; +} + +interface NamespacedMappers { + mapState: Mapper & MapperForState; + mapMutations: Mapper; + mapGetters: Mapper; + mapActions: Mapper; +} + +export declare const mapState: Mapper + & MapperWithNamespace + & MapperForState + & MapperForStateWithNamespace; + +export declare const mapMutations: Mapper + & MapperWithNamespace; + +export declare const mapGetters: Mapper + & MapperWithNamespace; + +export declare const mapActions: Mapper + & MapperWithNamespace; + +export declare function createNamespacedHelpers(namespace: string): NamespacedMappers; diff --git a/types/test/helpers.ts b/types/test/helpers.ts index 3279be1ca..c6a3304be 100644 --- a/types/test/helpers.ts +++ b/types/test/helpers.ts @@ -4,9 +4,12 @@ import { mapState, mapGetters, mapActions, - mapMutations + mapMutations, + createNamespacedHelpers } from "../index"; +const helpers = createNamespacedHelpers('foo'); + new Vue({ computed: Object.assign({}, mapState(["a"]), @@ -33,6 +36,19 @@ new Vue({ e: "e" }), + helpers.mapState(["k"]), + helpers.mapState({ + k: "k" + }), + helpers.mapState({ + k: (state: any, getters: any) => state.k + getters.k + }), + + helpers.mapGetters(["l"]), + helpers.mapGetters({ + l: "l" + }), + { otherComputed () { return "f"; @@ -59,6 +75,16 @@ new Vue({ j: "j" }), + helpers.mapActions(["m"]), + helpers.mapActions({ + m: "m" + }), + + helpers.mapMutations(["n"]), + helpers.mapMutations({ + n: "n" + }), + { otherMethod () {} }