|
@@ -81,42 +81,143 @@ const moduleA = {
|
|
|
|
|
|
### Пространства имён
|
|
|
|
|
|
-Обратите внимание, что действия, мутации и геттеры, определённые внутри модулей, тем не менее регистрируются в **глобальном пространстве имён** — это позволяет нескольким модулям реагировать на один и тот же тип мутации или действия. Избежать конфликта пространства имён вы можете, указывая для них префикс или суффикс. При создании пригодных для повторного использования модулей Vuex, пожалуй, так поступать даже нужно — кто знает, в каком окружении их будут использовать? Например, предположим что мы создаём модуль `todos`:
|
|
|
+По умолчанию действия, мутации и геттеры внутри модулей регистрируются в **глобальном пространстве имён** — это позволяет нескольким модулям реагировать на тот же тип мутаций/действий.
|
|
|
+
|
|
|
+Если вы хотите сделать модули более самодостаточными и готовыми для переиспользования, вы можете создать его с собственным пространством имён, указав опцию `namespaced: true`. Когда модуль будет зарегистрирован, все его геттеры, действия и мутации будут автоматически связаны с этим пространством имён, основываясь на пути по которому зарегистрирован модуль. Например:
|
|
|
|
|
|
``` js
|
|
|
-// types.js
|
|
|
+const store = new Vuex.Store({
|
|
|
+ modules: {
|
|
|
+ account: {
|
|
|
+ namespaced: true,
|
|
|
+
|
|
|
+ // содержимое модуля
|
|
|
+ state: { ... }, // состояние модуля автоматически вложено и не зависит от опции пространства имён
|
|
|
+ getters: {
|
|
|
+ isAdmin () { ... } // -> getters['account/isAdmin']
|
|
|
+ },
|
|
|
+ actions: {
|
|
|
+ login () { ... } // -> dispatch('account/login')
|
|
|
+ },
|
|
|
+ mutations: {
|
|
|
+ login () { ... } // -> commit('account/login')
|
|
|
+ },
|
|
|
+
|
|
|
+ // вложенные модули
|
|
|
+ modules: {
|
|
|
+ // наследует пространство имён из родительского модуля
|
|
|
+ myPage: {
|
|
|
+ state: { ... },
|
|
|
+ getters: {
|
|
|
+ profile () { ... } // -> getters['account/profile']
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // большая вложенность с собственным пространством имён
|
|
|
+ posts: {
|
|
|
+ namespaced: true,
|
|
|
+
|
|
|
+ state: { ... },
|
|
|
+ getters: {
|
|
|
+ popular () { ... } // -> getters['account/posts/popular']
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+})
|
|
|
+```
|
|
|
+
|
|
|
+Геттеры и действия с собственным пространством имён будут получать свои локальные `getters`, `dispatch` и `commit`. Другими словами, вы можете использовать содержимое модуля без написания префиксов в том же модуле. Переключения между пространствами имён не влияет на код внутри модуля.
|
|
|
|
|
|
-// определим названия геттеров, действий и мутаций как константы
|
|
|
-// используя название модуля (`todos`) в качестве префикса
|
|
|
-export const DONE_COUNT = 'todos/DONE_COUNT'
|
|
|
-export const FETCH_ALL = 'todos/FETCH_ALL'
|
|
|
-export const TOGGLE_DONE = 'todos/TOGGLE_DONE'
|
|
|
+#### Доступ к глобальному содержимому в модулях с своим пространством имён
|
|
|
+
|
|
|
+Если вы хотите использовать глобальное состояние и геттеры, `rootState` и `rootGetters` передаются 3-м и 4-м аргументами в функции геттеров, а также как свойства в объекте `context`, передаваемом в функции действий.
|
|
|
+
|
|
|
+Для запуска действий или совершении мутаций в глобальном пространстве имён нужно добавить `{ root: true }` 3-м аргументом в `dispatch` и `commit`.
|
|
|
+
|
|
|
+``` js
|
|
|
+modules: {
|
|
|
+ foo: {
|
|
|
+ namespaced: true,
|
|
|
+
|
|
|
+ getters: {
|
|
|
+ // `getters` ограничены геттерами данного модуля
|
|
|
+ // вы можете использовать rootGetters из 4-го аргумента геттеров
|
|
|
+ someGetter (state, getters, rootState, rootGetters) {
|
|
|
+ getters.someOtherGetter // -> 'foo/someOtherGetter'
|
|
|
+ rootGetters.someOtherGetter // -> 'someOtherGetter'
|
|
|
+ },
|
|
|
+ someOtherGetter: state => { ... }
|
|
|
+ },
|
|
|
+
|
|
|
+ actions: {
|
|
|
+ // dispatch и commit также ограничены данным модулем
|
|
|
+ // они принимают опцию `root` для вызова в глобальном пространстве имён
|
|
|
+ someAction ({ dispatch, commit, getters, rootGetters }) {
|
|
|
+ getters.someGetter // -> 'foo/someGetter'
|
|
|
+ rootGetters.someGetter // -> 'someGetter'
|
|
|
+
|
|
|
+ dispatch('someOtherAction') // -> 'foo/someOtherAction'
|
|
|
+ dispatch('someOtherAction', null, { root: true }) // -> 'someOtherAction'
|
|
|
+
|
|
|
+ commit('someMutation') // -> 'foo/someMutation'
|
|
|
+ commit('someMutation', null, { root: true }) // -> 'someMutation'
|
|
|
+ },
|
|
|
+ someOtherAction (ctx, payload) { ... }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
```
|
|
|
|
|
|
+#### Подключение с помощью вспомогательных функций к пространству имён
|
|
|
+
|
|
|
+Подключение модуля со своим пространством имён к компонентам с помощью вспомогательных функций `mapState`, `mapGetters`, `mapActions` и `mapMutations` это может выглядеть подобным образом:
|
|
|
+
|
|
|
``` js
|
|
|
-// modules/todos.js
|
|
|
-import * as types from '../types'
|
|
|
+computed: {
|
|
|
+ ...mapState({
|
|
|
+ a: state => state.some.nested.module.a,
|
|
|
+ b: state => state.some.nested.module.b
|
|
|
+ })
|
|
|
+},
|
|
|
+methods: {
|
|
|
+ ...mapActions([
|
|
|
+ 'some/nested/module/foo',
|
|
|
+ 'some/nested/module/bar'
|
|
|
+ ])
|
|
|
+}
|
|
|
+```
|
|
|
|
|
|
-// теперь используем определённые выше константы
|
|
|
-const todosModule = {
|
|
|
- state: { todos: [] },
|
|
|
+В таких случаях вы можете передать строку с пространством имён в качестве первого аргумента к вспомогательным функциям, тогда все привязки будут выполнены в контексте этого модуля. Пример выше можно упростить до:
|
|
|
|
|
|
- getters: {
|
|
|
- [types.DONE_COUNT] (state) {
|
|
|
- // ...
|
|
|
- }
|
|
|
- },
|
|
|
+``` js
|
|
|
+computed: {
|
|
|
+ ...mapState('some/nested/module', {
|
|
|
+ a: state => state.a,
|
|
|
+ b: state => state.b
|
|
|
+ })
|
|
|
+},
|
|
|
+methods: {
|
|
|
+ ...mapActions('some/nested/module', [
|
|
|
+ 'foo',
|
|
|
+ 'bar'
|
|
|
+ ])
|
|
|
+}
|
|
|
+```
|
|
|
|
|
|
- actions: {
|
|
|
- [types.FETCH_ALL] (context, payload) {
|
|
|
- // ...
|
|
|
- }
|
|
|
- },
|
|
|
+#### Уточнение для разработчиков плагинов
|
|
|
|
|
|
- mutations: {
|
|
|
- [types.TOGGLE_DONE] (state, payload) {
|
|
|
- // ...
|
|
|
- }
|
|
|
+Вас может обеспокоить непредсказуемость пространства имён для ваших модулей, когда вы создаёте [плагин](plugins.md) с собственными модулями и возможностью пользователям добавлять их в хранилище Vuex. Ваши модули будут также помещены в пространство имён, если пользователи плагина добавляют ваши модули в модуль со своим пространством имён. Чтобы приспособиться к этой ситуации, вам может потребоваться получить значение пространства имён через настройки плагина:
|
|
|
+
|
|
|
+``` js
|
|
|
+// получение значения пространства имён через options
|
|
|
+// и возвращение функции плагина Vuex
|
|
|
+export function createPlugin (options = {}) {
|
|
|
+ return function (store) {
|
|
|
+ // добавление пространства имён к модулям плагина
|
|
|
+ const namespace = options.namespace || ''
|
|
|
+ store.dispatch(namespace + 'pluginAction')
|
|
|
}
|
|
|
}
|
|
|
```
|