From 97fd3047ff580b63469f7e54bbec89a03fe66d7d Mon Sep 17 00:00:00 2001 From: Alex-Sokolov Date: Tue, 28 Nov 2017 22:39:35 +0300 Subject: [PATCH 01/51] =?UTF-8?q?structure.md=20=D0=B8=D1=81=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=BE=D0=BF=D0=B5=D1=87?= =?UTF-8?q?=D0=B0=D1=82=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ru/structure.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/structure.md b/docs/ru/structure.md index 05cc82a60..1574b5bb2 100644 --- a/docs/ru/structure.md +++ b/docs/ru/structure.md @@ -6,7 +6,7 @@ 2. Единственным механизмом изменения этого состояния являются **мутации**, являющиеся синхронными транзакциями; -3. Асинхронные операции инкапсулирутся в **действия**, или их комбинации. +3. Асинхронные операции инкапсулируются в **действия**, или их комбинации. Покуда вы следуете этим правилам, можно использовать любую структуру проекта. Если ваш файл хранилища становится слишком большим, просто начните выносить действия, мутации и геттеры в отдельные файлы. From be971170711363138dbc090727ee8641916a9d99 Mon Sep 17 00:00:00 2001 From: Alex-Sokolov Date: Tue, 28 Nov 2017 22:50:47 +0300 Subject: [PATCH 02/51] =?UTF-8?q?actions.md=20=D0=BC=D0=B5=D0=BB=D0=BA?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ru/actions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/actions.md b/docs/ru/actions.md index c45a3c6bd..22efc0555 100644 --- a/docs/ru/actions.md +++ b/docs/ru/actions.md @@ -81,7 +81,7 @@ actions: { const savedCartItems = [...state.cart.added] // инициируем запрос и "оптимистично" очистим корзину commit(types.CHECKOUT_REQUEST) - // предположим, что API магазина позволяет передать колбэки + // предположим, что API магазина позволяет передать коллбэки // для обработки успеха и неудачи при формировании заказа shop.buyProducts( products, From 1a7b02f4e8715a9b885585e1b4942e7cd14a8e6c Mon Sep 17 00:00:00 2001 From: Alex-Sokolov Date: Tue, 28 Nov 2017 22:51:01 +0300 Subject: [PATCH 03/51] =?UTF-8?q?api.md=20=D0=BC=D0=B5=D0=BB=D0=BA=D0=B8?= =?UTF-8?q?=D0=B5=20=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ru/api.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/ru/api.md b/docs/ru/api.md index 64e43c1b4..b7817a650 100644 --- a/docs/ru/api.md +++ b/docs/ru/api.md @@ -16,7 +16,7 @@ const store = new Vuex.Store({ ...options }) Корневой объект состояния хранилища Vuex. [Подробнее](state.md) - Если вы передаёте функцию, возвращающую объект, то возвращаемый объект будет использован в качестве корневого состояния. Это может быть полезным, если вы хотите повторно использовать объект состояния, особенно при повтоном использовании модулей. [Подробнее](modules.md#повторное-использование-модулей) + Если вы передаёте функцию, возвращающую объект, то возвращаемый объект будет использован в качестве корневого состояния. Это может быть полезным, если вы хотите повторно использовать объект состояния, особенно при повторном использовании модулей. [Подробнее](modules.md#повторное-использование-модулей) - **mutations** @@ -89,7 +89,7 @@ const store = new Vuex.Store({ ...options }) } ``` - Каждый модуль может содержать `state` и `mutations`, как и корневое хранилище. Состояние модуля будет прикреплёно к корневому, по указанному ключу. Мутации и геттеры модуля получают при вызове первым аргументом только локальное состояние, а не корневое. При вызове действий `context.state` аналогичным образом указывает на локальное состояние модуля. + Каждый модуль может содержать `state` и `mutations`, как и корневое хранилище. Состояние модуля будет прикреплено к корневому, по указанному ключу. Мутации и геттеры модуля получают при вызове первым аргументом только локальное состояние, а не корневое. При вызове действий `context.state` аналогичным образом указывает на локальное состояние модуля. [Подробнее](modules.md) @@ -142,7 +142,7 @@ const store = new Vuex.Store({ ...options }) Устанавливает наблюдение за возвращаемым значением геттера, вызывая коллбэк в случае его изменения. Геттер получает состояние хранилища первым аргументом, и геттеры вторым аргументом. Возможно указание дополнительного объекта опций, с такими же параметрами как и у метода `vm.$watch` корневой библиотеки Vue. - Для прекращения наблюдения, необходимо вызвать возвращённую функцию-хэндлер. + Для прекращения наблюдения, необходимо вызвать возвращаемую функцию обработчик. - **`subscribe(handler: Function)`** @@ -161,7 +161,7 @@ const store = new Vuex.Store({ ...options }) > Добавлено в версии 2.5.0 - Подписывается на действие хранилища. Обработчик `handler` вызывается после каждого дейсвтия и получает в качестве параметров дескриптов действия и текущее состояние хранилища: + Подписывается на действие хранилища. Обработчик `handler` вызывается после каждого действия и получает в качестве параметров дескриптов действия и текущее состояние хранилища: ``` js store.subscribeAction((action, state) => { From 921fb57bb5e79a383ded021c5b9d036fe7e503e9 Mon Sep 17 00:00:00 2001 From: Alex-Sokolov Date: Tue, 28 Nov 2017 22:51:18 +0300 Subject: [PATCH 04/51] =?UTF-8?q?intro.md=20=D0=BC=D0=B5=D0=BB=D0=BA=D0=B8?= =?UTF-8?q?=D0=B5=20=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ru/intro.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/intro.md b/docs/ru/intro.md index ad9871519..0ee425115 100644 --- a/docs/ru/intro.md +++ b/docs/ru/intro.md @@ -44,7 +44,7 @@ new Vue({ - Несколько представлений могут зависеть от одной и той же части состояния приложения - Действия из разных представлений могут оказывать влияние на одни и те же части состояния приложения -Разбираясь с первой проблемой, вам придётся передавать одни и те же данные в несколько глубоко вложенных компонентов. Это часто сложно и неприятно, а для соседних компонентов такое и вовсе не сработает. Решая вторую проблему, приходится обращаться напрямую к родителям и потомкам компонента, или синхронизовать изменения с другими местами в приложении событиями. Оба подхода хрупки и быстро приводят к появлению кода, который невозможно поддерживать. +Разбираясь с первой проблемой, вам придётся передавать одни и те же данные в несколько глубоко вложенных компонентов. Это часто сложно и неприятно, а для соседних компонентов такое и вовсе не сработает. Решая вторую проблему, приходится обращаться напрямую к родителям и потомкам компонента, или синхронизировать изменения с другими местами в приложении событиями. Оба подхода хрупки и быстро приводят к появлению кода, который невозможно поддерживать. Так почему бы не вынести всё общее состояние приложения из компонентов в глобальный синглтон? При использовании этого подхода, дерево компонентов превращается в одно большое "представление", а каждый компонент получает доступ к состоянию приложения, наряду с возможностью вызывать действия для изменения состояния, независимо от расположения этого компонента в дереве. From 9569122f32d4cc4f769556b96088e4a04da3958f Mon Sep 17 00:00:00 2001 From: Alex-Sokolov Date: Tue, 28 Nov 2017 22:51:28 +0300 Subject: [PATCH 05/51] =?UTF-8?q?state.md=20=D0=BC=D0=B5=D0=BB=D0=BA=D0=B8?= =?UTF-8?q?=D0=B5=20=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ru/state.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/state.md b/docs/ru/state.md index d2c00d196..7c2621947 100644 --- a/docs/ru/state.md +++ b/docs/ru/state.md @@ -67,7 +67,7 @@ import { mapState } from 'vuex' export default { // ... computed: mapState({ - // arrow-функции позволяют писать код очень лаконично + // стрелочные функции позволяют писать код очень лаконично count: state => state.count, // передача строки 'count' эквивалентна записи `state => state.count` From eb89908d7968f2f6d940d0ba35e9414498faa883 Mon Sep 17 00:00:00 2001 From: Alex-Sokolov Date: Tue, 28 Nov 2017 22:51:39 +0300 Subject: [PATCH 06/51] =?UTF-8?q?strict.md=20=D0=BC=D0=B5=D0=BB=D0=BA?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ru/strict.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/strict.md b/docs/ru/strict.md index 0950868da..fc2bcb9af 100644 --- a/docs/ru/strict.md +++ b/docs/ru/strict.md @@ -9,7 +9,7 @@ const store = new Vuex.Store({ }) ``` -В строгом режиме любая попытка внесения изменений в состояние Vuex кроме мутаций будет выбрасывать ошибку. Это гарантирует, что все мутации состояния будут явно отслежены через инструменты отладки. +В строгом режиме любая попытка внесения изменений в состояние Vuex кроме мутаций будет выбрасывать ошибку. Это гарантирует, что все мутации состояния будут явно отслеживаться через инструменты отладки. ### Разработка vs. production From 5db4d3fa0d0628d3a335954c86dcf910689ffe20 Mon Sep 17 00:00:00 2001 From: Alex-Sokolov Date: Tue, 28 Nov 2017 22:51:47 +0300 Subject: [PATCH 07/51] =?UTF-8?q?testing.md=20=D0=BC=D0=B5=D0=BB=D0=BA?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ru/testing.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/ru/testing.md b/docs/ru/testing.md index 52e5df3f2..98e8fe009 100644 --- a/docs/ru/testing.md +++ b/docs/ru/testing.md @@ -85,7 +85,7 @@ const actions = actionsInjector({ } }) -// вспомогательная фукнция для тестирования действия, которое должно вызывать известные мутации +// вспомогательная функция для тестирования действия, которое должно вызывать известные мутации const testAction = (action, payload, state, expectedMutations, done) => { let count = 0 @@ -181,7 +181,7 @@ describe('getters', () => { #### Запуск в Node -Используйте следующий конфиг webpack (в сочетании с соответствующим [`.babelrc`](https://babeljs.io/docs/usage/babelrc/)): +Используйте следующую конфигурацию webpack (в сочетании с соответствующим [`.babelrc`](https://babeljs.io/docs/usage/babelrc/)): ``` js // webpack.config.js From 4220dc6fe04a83f7654bd3b12bccc8040918c60e Mon Sep 17 00:00:00 2001 From: Alex-Sokolov Date: Mon, 1 Jan 2018 23:10:52 +0300 Subject: [PATCH 08/51] =?UTF-8?q?actions.md=20=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ru/actions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/actions.md b/docs/ru/actions.md index 22efc0555..680ca54e2 100644 --- a/docs/ru/actions.md +++ b/docs/ru/actions.md @@ -45,7 +45,7 @@ actions: { store.dispatch('increment') ``` -На первый взгляд может выглядеть глупо: если мы хотим инкрементировать переменную count, почему бы просто не вызвать `store.commit('increment')` напрямую? Запомните, что **мутации должны быть синхронными**. Действия же этим ограничением не скованы. Внутри действия можно выполнять **асинхронные** операции: +На первый взгляд может выглядеть глупо: если мы хотим увеличить значение count, почему бы просто не вызвать `store.commit('increment')` напрямую? Помните что **мутации должны быть синхронными**? Для действий такого ограничения нет. Внутри действий можно выполнять **асинхронные** операции: ``` js actions: { From 7ec590aa7942d5ad65433f0c87a454b12af08e1a Mon Sep 17 00:00:00 2001 From: Alex-Sokolov Date: Mon, 1 Jan 2018 23:14:05 +0300 Subject: [PATCH 09/51] =?UTF-8?q?testing.md=20=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ru/testing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/testing.md b/docs/ru/testing.md index 98e8fe009..cc7c52c50 100644 --- a/docs/ru/testing.md +++ b/docs/ru/testing.md @@ -4,7 +4,7 @@ ### Тестирование мутаций -Мутации тестировать довольно просто, так как они представляют из себя всего лишь простые функции, поведение которых полностью зависит от переданных параметров. Может пригодится возможность ES2015-модулей для самостоятельного именованного экспорта мутаций, наряду с экспортом самого хранилища из файла `store.js`: +Мутации тестировать довольно просто, так как они представляют из себя всего лишь простые функции, поведение которых полностью зависит от переданных параметров. Один трюк заключается в том, что если вы используете модули ES2015 и помещаете свои мутации в файле `store.js`, то помимо экспорта по умолчанию, вы должны экспортировать мутации с помощью именованного экспорта: ``` js const state = { ... } From 43490101b3541dc7d7daf8c9316685b52b7c3a19 Mon Sep 17 00:00:00 2001 From: Yauheni Dakuka Date: Wed, 3 Jan 2018 08:41:35 +0300 Subject: [PATCH 10/51] Fix typos. ru --- docs/ru/actions.md | 4 ++-- docs/ru/api.md | 4 ++-- docs/ru/getters.md | 4 ++-- docs/ru/getting-started.md | 4 ++-- docs/ru/hot-reload.md | 2 +- docs/ru/intro.md | 4 ++-- docs/ru/modules.md | 2 +- docs/ru/mutations.md | 2 +- docs/ru/plugins.md | 8 ++++---- docs/ru/strict.md | 6 +++--- docs/ru/structure.md | 4 ++-- docs/ru/testing.md | 2 +- 12 files changed, 23 insertions(+), 23 deletions(-) diff --git a/docs/ru/actions.md b/docs/ru/actions.md index 680ca54e2..4cec3a54d 100644 --- a/docs/ru/actions.md +++ b/docs/ru/actions.md @@ -98,7 +98,7 @@ actions: { ### Диспетчеризация действий в компонентах -Диспетчеризовать действия в компонентах можно при помощи `this.$store.dispatch('xxx')`, или используя вспомогательную функцию `mapActions`, создающую локальные псевдонимы для действий в виде методов компонента (требуется наличие корневого `$store`): +Диспетчеризировать действия в компонентах можно при помощи `this.$store.dispatch('xxx')` или используя вспомогательную функцию `mapActions`, создающую локальные псевдонимы для действий в виде методов компонента (требуется наличие корневого `$store`): ``` js import { mapActions } from 'vuex' @@ -159,7 +159,7 @@ actions: { } ``` -Наконец, если мы используем [async / await](https://tc39.github.io/ecmascript-asyncawait/), мы можем компоновать наши действия следующим образом: +Наконец, если мы используем [async / await](https://tc39.github.io/ecmascript-asyncawait/), то можем компоновать наши действия следующим образом: ``` js // предположим, что `getData()` и `getOtherData()` возвращают Promise diff --git a/docs/ru/api.md b/docs/ru/api.md index b7817a650..2cd6a7ae3 100644 --- a/docs/ru/api.md +++ b/docs/ru/api.md @@ -97,7 +97,7 @@ const store = new Vuex.Store({ ...options }) - тип: `Array` - Массив функций-плагинов, которые будут применены к хранилищу. Плагины попросту получают хранилище в качестве единственного аргумента, и могут как отслеживать мутации (для сохранения исходящих данных, логирования, или отладки) или инициировать их (для обработки входящих данных, например вебсокетов или observables). + Массив функций-плагинов, которые будут применены к хранилищу. Плагины попросту получают хранилище в качестве единственного аргумента, и могут как отслеживать мутации (для сохранения исходящих данных, логирования или отладки) или инициировать их (для обработки входящих данных, например, веб-сокетов или наблюдателей). [Подробнее](plugins.md) @@ -136,7 +136,7 @@ const store = new Vuex.Store({ ...options }) - **`replaceState(state: Object)`** - Позволяет заменить корневое состояние хранилища. Используйте только для гидрации состояния / функционала "машины времени". + Позволяет заменить корневое состояние хранилища. Используйте только для гидрации состояния / функциональности "машины времени". - **`watch(getter: Function, cb: Function, options?: Object)`** diff --git a/docs/ru/getters.md b/docs/ru/getters.md index 9918065f6..f34f637e8 100644 --- a/docs/ru/getters.md +++ b/docs/ru/getters.md @@ -10,7 +10,7 @@ computed: { } ``` -Если этот функционал требуется более чем одному компоненту, понадобится либо дублировать функцию, либо выносить её в совместно используемый хелпер и импортировать в нескольких местах. Оба эти подхода далеки от идеала. +Если эта функциональность требуется более чем одному компоненту, понадобится либо дублировать функцию, либо выносить её в совместно используемый хелпер и импортировать в нескольких местах. Оба эти подхода далеки от идеала. Vuex позволяет определять в хранилище «геттеры». Вы можете считать их вычисляемыми свойствами для хранилища. Как и вычисляемые свойства, результаты геттера кэшируются, основываясь на своих зависимостях и будут пересчитаны только тогда, когда изменится одна из его зависимостей. @@ -53,7 +53,7 @@ getters: { store.getters.doneTodosCount // -> 1 ``` -В компонентах геттеры можно использовать например таким образом: +В компонентах геттеры можно использовать, например, таким образом: ``` js computed: { diff --git a/docs/ru/getting-started.md b/docs/ru/getting-started.md index 615d081cd..66ccefbd9 100644 --- a/docs/ru/getting-started.md +++ b/docs/ru/getting-started.md @@ -4,7 +4,7 @@ 1. Хранилища Vuex реактивны. Если компоненты Vue зависят от их состояния, изменение состояния хранилища спровоцирует соответствующие изменения компонентов. -2. Непосредственное изменение состояния хранилища запрещено. Единственный способ внести изменения — явно **вызвать мутацию**. Этот подход позволяет быть уверенным, что каждое изменение оставляет в системе след, и даёт возможность использовать инструменты, позволяющие лучше понять работу приложения. +2. Непосредственное изменение состояния хранилища запрещено. Единственный способ внести изменения — явно **вызвать мутацию**. Этот подход позволяет быть уверенным, что каждое изменение оставляет в системе след и даёт возможность использовать инструменты, позволяющие лучше понять работу приложения. ### Простейшее Хранилище @@ -27,7 +27,7 @@ const store = new Vuex.Store({ }) ``` -Теперь мы можем получить доступ к объекту состояния `store.state`, или вызвать изменение состояния методом `store.commit`: +Теперь мы можем получить доступ к объекту состояния `store.state` или вызвать изменение состояния методом `store.commit`: ``` js store.commit('increment') diff --git a/docs/ru/hot-reload.md b/docs/ru/hot-reload.md index 942347131..d7591f11a 100644 --- a/docs/ru/hot-reload.md +++ b/docs/ru/hot-reload.md @@ -1,6 +1,6 @@ # Горячая замена -Vuex поддерживает горячую замену мутаций, модулей, действий и геттеров в момент разработки с помощью [webpack Hot Module Replacement API](https://webpack.js.org/guides/hot-module-replacement/). Аналогичный функционал в Browserify достижим при использовании плагина [browserify-hmr](https://github.com/AgentME/browserify-hmr/). +Vuex поддерживает горячую замену мутаций, модулей, действий и геттеров в момент разработки с помощью [webpack Hot Module Replacement API](https://webpack.js.org/guides/hot-module-replacement/). Аналогичная функциональность в Browserify достижима при использовании плагина [browserify-hmr](https://github.com/AgentME/browserify-hmr/). Для мутаций и модулей необходимо использовать метод API `store.hotUpdate()`: diff --git a/docs/ru/intro.md b/docs/ru/intro.md index 0ee425115..a266f3c44 100644 --- a/docs/ru/intro.md +++ b/docs/ru/intro.md @@ -1,6 +1,6 @@ # Что такое Vuex? -Vuex - это **паттерн управления состоянием и библиотека** для приложений на Vue.js. Он служит центральным хранилищем данных для всех компонентов приложения и обеспечивает предсказуемость изменения данных при помощи определённых правил. Кроме того, Vuex интегрируется с официальным [расширением инструментов разработчика](https://github.com/vuejs/vue-devtools) Vue, предоставляя "из коробки" такие продвинутые возможности как "машину времени" при отладке и экспорт/импорт слепков состояния данных. +Vuex - это **паттерн управления состоянием и библиотека** для приложений на Vue.js. Он служит центральным хранилищем данных для всех компонентов приложения и обеспечивает предсказуемость изменения данных при помощи определённых правил. Кроме того, Vuex интегрируется с официальным [расширением инструментов разработчика](https://github.com/vuejs/vue-devtools) Vue, предоставляя "из коробки" такие продвинутые возможности, как "машину времени" при отладке и экспорт/импорт слепков состояния данных. ### Что такое "паттерн управления состоянием"? @@ -48,7 +48,7 @@ new Vue({ Так почему бы не вынести всё общее состояние приложения из компонентов в глобальный синглтон? При использовании этого подхода, дерево компонентов превращается в одно большое "представление", а каждый компонент получает доступ к состоянию приложения, наряду с возможностью вызывать действия для изменения состояния, независимо от расположения этого компонента в дереве. -Кроме того, чётко определяя и разделяя концепции, возникающие при управлении состоянием и требуя соблюдения некоторых правил, мы улучшаем структурированность и поддерживаемость нашего кода. +Кроме того, чётко определяя и разделяя концепции, возникающие при управлении состоянием, и требуя соблюдения некоторых правил, мы улучшаем структурированность и поддерживаемость нашего кода. Такова основная идея, лежащая в основе Vuex, вдохновлённого [Flux](https://facebook.github.io/flux/docs/overview.html), [Redux](http://redux.js.org/) и [Архитектурой Elm](https://guide.elm-lang.org/architecture/). В отличие от других паттернов, Vuex реализован в виде библиотеки, специально заточенной на использование совместно с Vue.js и использующей его производительную систему реактивных обновлений. diff --git a/docs/ru/modules.md b/docs/ru/modules.md index a57b9615d..a462df996 100644 --- a/docs/ru/modules.md +++ b/docs/ru/modules.md @@ -2,7 +2,7 @@ Из-за использования единого дерева состояния, все глобальные данные приложения оказываются помещены в один большой объект. По мере роста приложения, хранилище может существенно раздуться. -Чтобы помочь в этой беде, Vuex позволяет разделять хранилище на **модули**. Каждый модуль может содержать собственное состояние, мутации, действия, геттеры, и даже встроенные подмодули — структура фрактальна: +Чтобы помочь в этой беде, Vuex позволяет разделять хранилище на **модули**. Каждый модуль может содержать собственное состояние, мутации, действия, геттеры и даже встроенные подмодули — структура фрактальна: ``` js const moduleA = { diff --git a/docs/ru/mutations.md b/docs/ru/mutations.md index 7945a7e0e..7898b648b 100644 --- a/docs/ru/mutations.md +++ b/docs/ru/mutations.md @@ -1,6 +1,6 @@ # Мутации -Единственным способом изменения состояния хранилища во Vuex являются мутации. Мутации во Vuex очень похожи на события: каждая мутация имеет строковый **тип** и **функцию-обработчик**. В этом обработчике и происходят собственно изменения состояния, переданного в функцию первым аргументом: +Единственным способом изменения состояния хранилища во Vuex являются мутации. Мутации во Vuex очень похожи на события: каждая мутация имеет строковый **тип** и **функцию-обработчик**. В этом обработчике и происходят, собственно, изменения состояния, переданного в функцию первым аргументом: ``` js const store = new Vuex.Store({ diff --git a/docs/ru/plugins.md b/docs/ru/plugins.md index c15586f77..9dc9e5a01 100644 --- a/docs/ru/plugins.md +++ b/docs/ru/plugins.md @@ -25,7 +25,7 @@ const store = new Vuex.Store({ Плагинам не разрешается напрямую изменять состояние приложения — как и компоненты, они могут только вызывать изменения опосредованно, используя мутации. -Вызывая мутации, плагин может синхронизировать источник данных с хранилищем данных в приложении. Например, для синхронизации хранилища с вебсокетом (пример намеренно упрощён, в реальной ситуации у `createPlugin` были бы дополнительные опции): +Вызывая мутации, плагин может синхронизировать источник данных с хранилищем данных в приложении. Например, для синхронизации хранилища с веб-сокетом (пример намеренно упрощён, в реальной ситуации у `createPlugin` были бы дополнительные опции): ``` js export default function createWebSocketPlugin (socket) { @@ -103,8 +103,8 @@ const store = new Vuex.Store({ const logger = createLogger({ collapsed: false, // автоматически раскрывать залогированные мутации filter (mutation, stateBefore, stateAfter) { - // возвращает `true` если мутация должна быть залогирована - // `mutation` это объект `{ type, payload }` + // возвращает `true`, если мутация должна быть залогирована + // `mutation` - это объект `{ type, payload }` return mutation.type !== "aBlacklistedMutation" }, transformer (state) { @@ -121,6 +121,6 @@ const logger = createLogger({ }) ``` -Логирующий плагин можно включить также и используя отдельный тег ` + +``` + +### NPM + +```bash +npm install vuex --save +``` + +### Yarn + +```bash +yarn add vuex +``` + +Если вы используете систему сборки, установите Vuex явным образом командой `Vue.use()`: + +```js +import Vue from "vue"; +import Vuex from "vuex"; + +Vue.use(Vuex); +``` + +При использовании глобальных тегов ` +``` + +Тогда `window.Promise` будет доступен автоматически. + +Если вы предпочитаете использовать менеджер пакетов, такой как NPM или Yarn, установите пакет с помощью следующей команды: + +```bash +npm install es6-promise --save # NPM +yarn add es6-promise # Yarn +``` + +Кроме того, добавьте строку ниже в любое место вашего кода перед использованием Vuex: + +```js +import "es6-promise/auto"; +``` + +### Версия для разработки + +Если вы хотите использовать самую новую dev-сборку `vuex`, то придётся вручную склонировать репозиторий с GitHub и запустить сборку: + +```bash +git clone https://github.com/vuejs/vuex.git node_modules/vuex +cd node_modules/vuex +npm install +npm run build +``` diff --git a/docs/ru/modules.md b/docs/ru/modules.md new file mode 100644 index 000000000..ea71eeb76 --- /dev/null +++ b/docs/ru/modules.md @@ -0,0 +1,317 @@ +# Модули + +Из-за использования единого дерева состояния, все глобальные данные приложения оказываются помещены в один большой объект. По мере роста приложения, хранилище может существенно раздуться. + +Чтобы помочь в этой беде, Vuex позволяет разделять хранилище на **модули**. Каждый модуль может содержать собственное состояние, мутации, действия, геттеры и даже встроенные подмодули — структура фрактальна: + +```js +const moduleA = { + state: { ... }, + mutations: { ... }, + actions: { ... }, + getters: { ... } +} + +const moduleB = { + state: { ... }, + mutations: { ... }, + actions: { ... } +} + +const store = new Vuex.Store({ + modules: { + a: moduleA, + b: moduleB + } +}) + +store.state.a // -> состояние модуля `moduleA` +store.state.b // -> состояние модуля `moduleB` +``` + +### Локальное состояние модулей + +Первым аргументом, который получают мутации и геттеры, будет **локальное состояние модуля**. + +```js +const moduleA = { + state: { count: 0 }, + mutations: { + increment(state) { + // `state` указывает на локальное состояние модуля + state.count++; + } + }, + + getters: { + doubleCount(state) { + return state.count * 2; + } + } +}; +``` + +Аналогично, `context.state` в действиях также указывает на локальное состояние модуля, а корневое — доступно в `context.rootState`: + +```js +const moduleA = { + // ... + actions: { + incrementIfOddOnRootSum({ state, commit, rootState }) { + if ((state.count + rootState.count) % 2 === 1) { + commit("increment"); + } + } + } +}; +``` + +Кроме того, в геттеры корневое состояние передаётся 3-м параметром: + +```js +const moduleA = { + // ... + getters: { + sumWithRootCount(state, getters, rootState) { + return state.count + rootState.count; + } + } +}; +``` + +### Пространства имён + +По умолчанию действия, мутации и геттеры внутри модулей регистрируются в **глобальном пространстве имён** — это позволяет нескольким модулям реагировать на тот же тип мутаций/действий. + +Если вы хотите сделать модули более самодостаточными и готовыми для переиспользования, вы можете создать его с собственным пространством имён, указав опцию `namespaced: true`. Когда модуль будет зарегистрирован, все его геттеры, действия и мутации будут автоматически связаны с этим пространством имён, основываясь на пути по которому зарегистрирован модуль. Например: + +```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`. Другими словами, вы можете использовать содержимое модуля без написания префиксов в том же модуле. Переключения между пространствами имён не влияет на код внутри модуля. + +#### Доступ к глобальному содержимому в модулях со своим пространством имён + +Если вы хотите использовать глобальное состояние и геттеры, `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) { ... } + } + } +} +``` + +#### Регистрация глобального действия в модуле с собственным пространством имён + +Если вы хотите зарегистрировать глобальное действие в модуле с собственным пространством имён, вы можете пометить его с помощью `root: true` и поместить определение действия в функцию `handler`. Например: + +```js +{ + actions: { + someOtherAction ({dispatch}) { + dispatch('someAction') + } + }, + modules: { + foo: { + namespaced: true, + + actions: { + someAction: { + root: true, + handler (namespacedContext, payload) { ... } // -> 'someAction' + } + } + } + } +} +``` + +#### Подключение с помощью вспомогательных функций к пространству имён + +Подключение модуля со своим пространством имён к компонентам с помощью вспомогательных функций `mapState`, `mapGetters`, `mapActions` и `mapMutations` это может выглядеть подобным образом: + +```js +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' + ]) +} +``` + +В таких случаях вы можете передать строку с пространством имён в качестве первого аргумента к вспомогательным функциям, тогда все привязки будут выполнены в контексте этого модуля. Пример выше можно упростить до: + +```js +computed: { + ...mapState('some/nested/module', { + a: state => state.a, + b: state => state.b + }) +}, +methods: { + ...mapActions('some/nested/module', [ + 'foo', + 'bar' + ]) +} +``` + +Кроме того, вы можете создать вспомогательные функции с помощью `createNamespacedHelpers`. Она возвращает объект, в котором все вспомогательные функции для связывания с компонентами будут указывать на переданное пространство имён: + +```js +import { createNamespacedHelpers } from "vuex"; + +const { mapState, mapActions } = createNamespacedHelpers("some/nested/module"); + +export default { + computed: { + // будет указывать на `some/nested/module` + ...mapState({ + a: state => state.a, + b: state => state.b + }) + }, + methods: { + // будет указывать на `some/nested/module` + ...mapActions(["foo", "bar"]) + } +}; +``` + +#### Уточнение для разработчиков плагинов + +Вас может обеспокоить непредсказуемость пространства имён для ваших модулей, когда вы создаёте [плагин](plugins.md) с собственными модулями и возможностью пользователям добавлять их в хранилище Vuex. Ваши модули будут также помещены в пространство имён, если пользователи плагина добавляют ваши модули в модуль со своим пространством имён. Чтобы приспособиться к этой ситуации, вам может потребоваться получить значение пространства имён через настройки плагина: + +```js +// получение значения пространства имён через options +// и возвращение функции плагина Vuex +export function createPlugin(options = {}) { + return function(store) { + // добавление пространства имён к модулям плагина + const namespace = options.namespace || ""; + store.dispatch(namespace + "pluginAction"); + }; +} +``` + +### Динамическая регистрация модулей + +Вы можете зарегистрировать модуль уже и **после** того, как хранилище было создано, используя метод `store.registerModule`: + +```js +// регистрация модуля `myModule` +store.registerModule("myModule", { + // ... +}); + +// регистрация вложенного модуля `nested/myModule` +store.registerModule(["nested", "myModule"], { + // ... +}); +``` + +Состояние модуля будет доступно как `store.state.myModule` и `store.state.nested.myModule`. + +Динамическая регистрация модулей позволяет другим плагинам Vue также использовать Vuex для управления своим состоянием, добавляя модуль к хранилищу данных приложения. Например, библиотека [`vuex-router-sync`](https://github.com/vuejs/vuex-router-sync) интегрирует vue-router во vuex, отражая изменение текущего пути приложения в динамически присоединённом модуле. + +Удалить динамически зарегистрированный модуль можно с помощью `store.unregisterModule(moduleName)`. Обратите внимание, что статические (определённые на момент создания хранилища) модули при помощи этого метода удалить не получится. + +Вероятно, вы хотите сохранить предыдущее состояние при регистрации нового модуля, например сохранить состояние из приложения с рендерингом на стороне сервера. Вы можете этого добиться с помощью опции `preserveState`: `store.registerModule('a', module, { preserveState: true })` + +### Повторное использование модулей + +Иногда нам может потребоваться создать несколько экземпляров модуля, например: + +* Создание нескольких хранилищ, которые используются одним модулем (например, чтобы [избегать синглтонов с сохранением состояния в SSR](https://ssr.vuejs.org/ru/structure.html#избегайте-синглтонов-с-состоянием) при использовании опции `runInNewContext` в значении `false` или `'once'`); +* Регистрация модуля несколько раз в одном хранилище. + +Если мы используем просто объект для определения состояния модуля, тогда этот объект состояния будет использоваться по ссылке и вызывать загрязнение состояния хранилища / модуля при его мутациях. + +Это фактически та же самая проблема с `data` внутри компонентов Vue. Таким образом решение будет таким же — использовать функцию для объявления состояния модуля (поддержка добавлена в версии 2.3.0+): + +```js +const MyReusableModule = { + state() { + return { + foo: "bar" + }; + } + // мутации, действия, геттеры... +}; +``` diff --git a/docs/ru/mutations.md b/docs/ru/mutations.md new file mode 100644 index 000000000..09307feba --- /dev/null +++ b/docs/ru/mutations.md @@ -0,0 +1,173 @@ +# Мутации + +Единственным способом изменения состояния хранилища во Vuex являются мутации. Мутации во Vuex очень похожи на события: каждая мутация имеет строковый **тип** и **функцию-обработчик**. В этом обработчике и происходят, собственно, изменения состояния, переданного в функцию первым аргументом: + +```js +const store = new Vuex.Store({ + state: { + count: 1 + }, + mutations: { + increment(state) { + // изменяем состояние + state.count++; + } + } +}); +``` + +Вызывать функцию-обработчик напрямую — нельзя. Это больше похоже на обработку события: "Когда мутация типа `increment` инициирована, вызывается этот обработчик". Чтобы инициировать обработку мутации, необходимо вызвать `store.commit`, указав её тип: + +```js +store.commit("increment"); +``` + +### Мутации с нагрузкой + +При вызове `store.commit` в мутацию можно также передать дополнительный параметр, называемый **нагрузкой (`payload`)**: + +```js +// ... +mutations: { + increment (state, n) { + state.count += n + } +} +``` + +```js +store.commit("increment", 10); +``` + +В большинстве случаев нагрузка будет объектом, содержащим несколько полей. Запись мутаций в таком случае становится более описательной: + +```js +// ... +mutations: { + increment (state, payload) { + state.count += payload.amount + } +} +``` + +```js +store.commit("increment", { + amount: 10 +}); +``` + +### Объектный синтаксис + +Другой способ вызвать мутацию — это передать в commit единственный параметр, в котором `type` указан напрямую: + +```js +store.commit({ + type: "increment", + amount: 10 +}); +``` + +При использовании объектной записи, объект передаётся в качестве нагрузки целиком, так что обработчик остаётся тем же самым: + +```js +mutations: { + increment (state, payload) { + state.count += payload.amount + } +} +``` + +### Мутации следуют правилам реактивности Vue + +Поскольку состояние хранилища Vuex — это реактивная переменная Vue, при возникновении мутации зависящие от этого состояния компоненты Vue обновляются автоматически. Кроме того, это значит, что мутации Vuex имеют те же самые подводные камни, что и реактивность в обычном Vue: + +1. Лучше инициализировать изначальное состояние хранилища, указав все поля в самом начале. + +2. При добавлении новых свойств объекту необходимо либо: + +* Использовать `Vue.set(obj, 'newProp', 123)`, или + +* Целиком заменить старый объект новым. Например, используя [синтаксис расширения объектов](https://github.com/sebmarkbage/ecmascript-rest-spread) из stage-3, можно написать так: + + ```js + state.obj = { ...state.obj, newProp: 123 }; + ``` + +### Использование констант для обозначения типов мутаций + +В различных вариантах реализации Flux этот подход используется весьма часто. Вынесите все константы с типами мутаций и действий в отдельный файл, чтобы было проще использовать линтеры и другие инструменты, а также чтобы дать читателям возможность с первого взгляда понять, какие мутации возможны в приложении: + +```js +// mutation-types.js +export const SOME_MUTATION = "SOME_MUTATION"; +``` + +```js +// store.js +import Vuex from 'vuex' +import { SOME_MUTATION } from './mutation-types' + +const store = new Vuex.Store({ + state: { ... }, + mutations: { + // "вычисляемые имена" из ES2015 позволяют использовать + // константу в качестве имени функции + [SOME_MUTATION] (state) { + // здесь будет изменяться состояние + } + } +}) +``` + +Тем не менее, использовать константы для указания типов мутаций совершенно необязательно, хотя это и может оказаться полезным в крупных проектах. + +### Мутации должны быть синхронными + +Нужно помнить одно важное правило: **обработчики мутаций обязаны быть синхронными**. Почему? Рассмотрим пример: + +```js +mutations: { + someMutation (state) { + api.callAsyncMethod(() => { + state.count++ + }) + } +} +``` + +Теперь представьте, что вы отлаживаете приложение и смотрите в лог мутаций в инструментах разработчика. Для каждой залогированной мутации devtools должен сохранить слепки состояния приложения "до" и "после" её наступления. Однако, асинхронный коллбэк внутри приведённой выше мутации делает это невозможным: мутация-то уже записана, и у devtools нет никакой возможности знать, что далее будет вызван коллбэк, а, значит, и инициируемые им изменения становится, по сути дела, невозможно отследить. + +### Вызов мутаций в компонентах + +Мутации можно вызывать из кода компонентов, используя `this.$store.commit('xxx')`, или применяя хелпер `mapMutations`, который проксирует вызовы `store.commit` через методы компонентов (для этого требуется наличие корневой ссылки на хранилище `$store`): + +```js +import { mapMutations } from "vuex"; + +export default { + // ... + methods: { + ...mapMutations([ + "increment", // `this.increment()` будет вызывать `this.$store.commit('increment')` + + // mapMutations также поддерживает нагрузку: + "incrementBy" // `this.incrementBy(amount)` будет вызывать `this.$store.commit('incrementBy', amount)` + ]), + ...mapMutations({ + add: "increment" // `this.add()` будет вызывать `this.$store.commit('increment')` + }) + } +}; +``` + +### О действиях + +Привнесение асинхронности в мутации могло бы изрядно затруднить понимание логики программы. Например, если вызываются два метода, оба с асинхронными коллбэками, изменяющими состояние приложения — как предсказать, какой из коллбэков будет вызван первым? Именно поэтому концепции изменений и асинхронности рассматриваются по отдельности. Во Vuex **мутации — это синхронные транзакции**: + +```js +store.commit("increment"); +// все изменения состояния, вызываемые мутацией "increment", +// к этому моменту уже должны произойти. +``` + +Для обработки асинхронных операций существуют [Действия](actions.md). diff --git a/docs/ru/plugins.md b/docs/ru/plugins.md new file mode 100644 index 000000000..103ece31e --- /dev/null +++ b/docs/ru/plugins.md @@ -0,0 +1,124 @@ +# Плагины + +Хранилища Vuex принимают опцию `plugins`, предоставляющую хуки для каждой мутации. Vuex-плагин — это просто функция, получающая хранилище в качестве единственного параметра: + +```js +const myPlugin = store => { + // вызывается после инициализации хранилища + store.subscribe((mutation, state) => { + // вызывается после каждой мутации + // мутация передаётся в формате `{ type, payload }`. + }); +}; +``` + +Используются плагины так: + +```js +const store = new Vuex.Store({ + // ... + plugins: [myPlugin] +}); +``` + +### Вызов мутаций из плагинов + +Плагинам не разрешается напрямую изменять состояние приложения — как и компоненты, они могут только вызывать изменения опосредованно, используя мутации. + +Вызывая мутации, плагин может синхронизировать источник данных с хранилищем данных в приложении. Например, для синхронизации хранилища с веб-сокетом (пример намеренно упрощён, в реальной ситуации у `createPlugin` были бы дополнительные опции): + +```js +export default function createWebSocketPlugin(socket) { + return store => { + socket.on("data", data => { + store.commit("receiveData", data); + }); + store.subscribe(mutation => { + if (mutation.type === "UPDATE_DATA") { + socket.emit("update", mutation.payload); + } + }); + }; +} +``` + +```js +const plugin = createWebSocketPlugin(socket); + +const store = new Vuex.Store({ + state, + mutations, + plugins: [plugin] +}); +``` + +### Снятие слепков состояния + +Иногда плагину может потребоваться "снять слепок" состояния приложения или сравнить состояния "до" и "после" мутации. Для этого используйте глубокое копирование объекта состояния: + +```js +const myPluginWithSnapshot = store => { + let prevState = _.cloneDeep(store.state); + store.subscribe((mutation, state) => { + let nextState = _.cloneDeep(state); + + // сравнение `prevState` и `nextState`... + + // сохранение состояния для следующей мутации + prevState = nextState; + }); +}; +``` + +**Плагины, снимающие слепки, должны использоваться только на этапе разработки.** При использовании webpack или Browserify, мы можем отдать этот момент на их откуп: + +```js +const store = new Vuex.Store({ + // ... + plugins: process.env.NODE_ENV !== "production" ? [myPluginWithSnapshot] : [] +}); +``` + +Плагин будет использоваться по умолчанию. В production-окружении вам понадобится [DefinePlugin](https://webpack.js.org/plugins/define-plugin/) для webpack, или [envify](https://github.com/hughsk/envify) для Browserify, чтобы изменить значение `process.env.NODE_ENV !== 'production'` на `false` в финальной сборке. + +### Встроенный плагин логирования + +> Если вы используете [vue-devtools](https://github.com/vuejs/vue-devtools), вам он скорее всего не понадобится + +В комплекте с Vuex идёт плагин логирования, который можно использовать при отладке: + +```js +import createLogger from "vuex/dist/logger"; + +const store = new Vuex.Store({ + plugins: [createLogger()] +}); +``` + +Функция `createLogger` принимает следующие опции: + +```js +const logger = createLogger({ + collapsed: false, // автоматически раскрывать залогированные мутации + filter(mutation, stateBefore, stateAfter) { + // возвращает `true`, если мутация должна быть залогирована + // `mutation` — это объект `{ type, payload }` + return mutation.type !== "aBlacklistedMutation"; + }, + transformer(state) { + // обработать состояние перед логированием + // например, позволяет рассматривать только конкретное поддерево + return state.subTree; + }, + mutationTransformer(mutation) { + // мутации логируются в формате `{ type, payload }`, + // но это можно изменить + return mutation.type; + }, + logger: console // реализация API `console`, по умолчанию `console` +}); +``` + +Логирующий плагин также можно включить напрямую используя отдельный тег ` ``` -Тогда `window.Promise` будет доступен автоматически. +После этого `window.Promise` будет доступен автоматически. -Если вы предпочитаете использовать менеджер пакетов, такой как NPM или Yarn, то установите пакет с помощью следующей команды: +Если используете менеджер пакетов NPM или Yarn, то установите пакет следующей командой: ```bash npm install es6-promise --save # NPM yarn add es6-promise # Yarn ``` -Кроме того, добавьте строку ниже в любое место вашего кода перед использованием Vuex: +И добавьте строку ниже с импортом в любое место вашего кода перед использованием Vuex: ```js import 'es6-promise/auto'; @@ -67,7 +67,7 @@ import 'es6-promise/auto'; ### Версия для разработки -Если вы хотите использовать самую новую dev-сборку `vuex`, то придётся вручную склонировать репозиторий с GitHub и запустить сборку: +Для использования самой новой dev-сборки `vuex` — склонируйте репозиторий с GitHub вручную и запустите сборку: ```bash git clone https://github.com/vuejs/vuex.git node_modules/vuex From b125a0adb7943921cc0677cdc18fe8855ab20e9e Mon Sep 17 00:00:00 2001 From: Alex Sokolov <4497128+Alex-Sokolov@users.noreply.github.com> Date: Sat, 27 Oct 2018 21:54:28 +0300 Subject: [PATCH 32/51] =?UTF-8?q?README.md=20=D0=BE=D0=B1=D0=BD=D0=BE?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ru/README.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/ru/README.md b/docs/ru/README.md index ebfc62f87..4b6656521 100644 --- a/docs/ru/README.md +++ b/docs/ru/README.md @@ -1,10 +1,10 @@ # Что такое Vuex? -Vuex — это **паттерн управления состоянием и библиотека** для приложений на Vue.js. Он служит центральным хранилищем данных для всех компонентов приложения и обеспечивает предсказуемость изменения данных при помощи определённых правил. Кроме того, Vuex интегрируется с официальным [расширением инструментов разработчика](https://github.com/vuejs/vue-devtools) Vue, предоставляя "из коробки" такие продвинутые возможности, как "машину времени" при отладке и экспорт/импорт слепков состояния данных. +Vuex — **паттерн управления состоянием + библиотека** для приложений на Vue.js. Он служит централизованным хранилищем данных для всех компонентов приложения с правилами, гарантирующими, что состояние может быть изменено только предсказуемым образом. Vuex интегрируется с официальным расширением [vue-devtools](https://github.com/vuejs/vue-devtools), предоставляя «из коробки» такие продвинутые возможности, как «машину времени» для отладки и экспорт/импорт слепков состояния данных. -### Что такое "паттерн управления состоянием"? +### Что такое «паттерн управления состоянием»? -Давайте начнём с простого приложения, реализующего счётчик с использованием Vue: +Давайте начнём с простого приложения Vue, реализующего счётчик: ```js new Vue({ @@ -29,35 +29,35 @@ new Vue({ Это самостоятельное приложение состоит из следующих частей: -* **Состояние** — "источник истины", управляющий приложением; -* **Представление** — декларативно заданное отображение **состояния**; +* **Состояние** — «источник истины», управляющий приложением; +* **Представление** — отображение **состояния** заданное декларативно; * **Действия** — возможные пути изменения состояния приложения в ответ на взаимодействие пользователя с **представлением**. -Вот простейшее представление концепции "однонаправленного потока данных": +Вот простейшее представление концепции «однонаправленного потока данных»:

-Простота, к сожалению, быстро исчезает при появлении **нескольких компонентов, основывающихся на одном и том же состоянии**, когда: +Однако простота быстро исчезает, когда у нас появляется **нескольких компонентов, основывающихся на одном и том же состоянии**: * Несколько представлений могут зависеть от одной и той же части состояния приложения. * Действия из разных представлений могут оказывать влияние на одни и те же части состояния приложения. -Разбираясь с первой проблемой, вам придётся передавать одни и те же данные в несколько глубоко вложенных компонентов. Это часто сложно и неприятно, а для соседних компонентов такое и вовсе не сработает. Решая вторую проблему, приходится обращаться напрямую к родителям и потомкам компонента, или синхронизировать изменения с другими местами в приложении событиями. Оба подхода хрупки и быстро приводят к появлению кода, который невозможно поддерживать. +Решая первую проблему, придётся передавать одни и те же данные входными параметрами в глубоко вложенные компоненты. Это часто сложно и утомительно, а для соседних компонентов такое и вовсе не сработает. Решая вторую проблему, можно прийти к таким решениям, как обращение по ссылкам к родительским/дочерним экземплярам или попыткам изменять и синхронизировать несколько копий состояния через события. Оба подхода хрупки и быстро приводят к появлению кода, который невозможно поддерживать. -Так почему бы не вынести всё общее состояние приложения из компонентов в глобальный синглтон? При использовании этого подхода, дерево компонентов превращается в одно большое "представление", а каждый компонент получает доступ к состоянию приложения, наряду с возможностью вызывать действия для изменения состояния, независимо от расположения этого компонента в дереве. +Так почему бы не вынести всё общее состояние приложения из компонентов и управлять им в глобальном синглтоне? При этом наше дерево компонентов становится одним большим «представлением» и любой компонент может получить доступ к состоянию приложения или вызывать действия для изменения состояния, независимо от того, где они находятся в дереве! -Кроме того, чётко определяя и разделяя концепции, возникающие при управлении состоянием, и требуя соблюдения некоторых правил, мы улучшаем структурированность и поддерживаемость нашего кода. +Кроме того, чётко определяя и разделяя концепции, возникающие при управлении состоянием, и требуя соблюдения определённых правил, мы лучше структурируем код и облегчаем его поддержку. -Такова основная идея, лежащая в основе Vuex, вдохновлённого [Flux](https://facebook.github.io/flux/docs/overview.html), [Redux](http://redux.js.org/) и [Архитектурой Elm](https://guide.elm-lang.org/architecture/). В отличие от других паттернов, Vuex реализован в виде библиотеки, специально заточенной на использование совместно с Vue.js и использующей его производительную систему реактивных обновлений. +Это основная идея Vuex, вдохновлённого [Flux](https://facebook.github.io/flux/docs/overview.html), [Redux](http://redux.js.org/) и [Архитектурой Elm](https://guide.elm-lang.org/architecture/). В отличие от других паттернов, Vuex реализован в виде библиотеки, специально предназначенной для Vue.js, чтобы использовать его систему реактивности для эффективного обновления. ![vuex](/ru/vuex.png) -### В каких случаях использовать Vuex? +### Когда следует использовать Vuex? -Vuex помогает управлять совместно используемым состоянием ценой привнесения новых концепций и вспомогательного кода. Кратковременная продуктивность страдает во благо долгосрочной. +Хотя Vuex помогает управлять совместно используемым состоянием, это реализуется ценой привнесения новых концепций и вспомогательного кода. Компромисс, когда кратковременная продуктивность страдает на благо долгосрочной. -Если вам ещё не доводилось создавать крупномасштабные одностраничные приложения, Vuex может показаться многословным и обескураживающим. Это нормально — несложные приложения вполне могут обойтись и без Vuex. Возможно, вам вполне хватит простой [глобальной шины событий](https://ru.vuejs.org/v2/guide/state-management.html#Простой-контейнер-состояния-с-нуля). Но если вы создаёте SPA среднего или крупного размера, вероятно вам уже приходилось сталкиваться с ситуациями, заставляющими задуматься о методах более эффективного управления состоянием приложения за пределами компонентов Vue, и Vuex в таком случае может оказаться вполне естественным следующим шагом. Вот неплохая цитата от Дэна Абрамова, автора Redux: +Если ещё не приходилось создавать крупные SPA и вы лишь знакомитесь с Vuex, это может показаться многословным и сложным. Всё в порядке — простые приложения могут легко обходиться и без Vuex. Возможно, будет достаточно простого паттерна [глобальной шины событий](https://ru.vuejs.org/v2/guide/state-management.html#Простой-контейнер-состояния-с-нуля). Но если вы создаёте SPA среднего или крупного размера, то, скорее всего, уже сталкивались с ситуациями, которые заставляли задуматься о том, как лучше управлять состоянием вне компонентов Vue, а Vuex в таком случае может стать вполне естественным следующим шагом. Есть хорошая цитата от Дэна Абрамова, автора Redux: -> Flux-библиотеки подобны очкам: если они вам действительно нужны, вы на этот счёт не сомневаетесь. +> Flux-библиотеки похожи на очки: вы будете точно знать, когда они вам понадобятся. From e3b7badd352fc254a00d94b4122ff9c900e5cefd Mon Sep 17 00:00:00 2001 From: Alex Sokolov <4497128+Alex-Sokolov@users.noreply.github.com> Date: Sat, 27 Oct 2018 21:57:21 +0300 Subject: [PATCH 33/51] =?UTF-8?q?getting-started.md=20=D1=83=D0=B4=D0=B0?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD,=20=D0=B4=D1=83=D0=B1=D0=BB=D1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ru/guide/getting-started.md | 44 -------------------------------- 1 file changed, 44 deletions(-) delete mode 100644 docs/ru/guide/getting-started.md diff --git a/docs/ru/guide/getting-started.md b/docs/ru/guide/getting-started.md deleted file mode 100644 index 6c1267685..000000000 --- a/docs/ru/guide/getting-started.md +++ /dev/null @@ -1,44 +0,0 @@ -# Введение - -В центре любого Vuex-приложения находится **хранилище**. "Хранилище" — это, упрощённо говоря, контейнер, который хранит **состояние** вашего приложения. Два момента отличают хранилище Vuex от простого глобального объекта: - -1. Хранилища Vuex реактивны. Если компоненты Vue зависят от их состояния, изменение состояния хранилища спровоцирует соответствующие изменения компонентов. - -2. Непосредственное изменение состояния хранилища запрещено. Единственный способ внести изменения — явно **вызвать мутацию**. Этот подход позволяет быть уверенным, что каждое изменение оставляет в системе след и даёт возможность использовать инструменты, позволяющие лучше понять работу приложения. - -### Простейшее хранилище - -> **ПРИМЕЧАНИЕ:** Мы будем использовать синтаксис ES2015 для примеров кода на всём протяжении этой документации. Если вы с ним ещё не разобрались, [сейчас самое время](https://babeljs.io/docs/learn-es2015/)! - -После [установки](../installation.md) Vuex, давайте создадим хранилище. Всё довольно просто: нужно лишь указать исходное состояние и мутации: - -```js -// Удостоверьтесь, что вызвали Vue.use(Vuex) в коде до этого, если используете модульный сборщик - -const store = new Vuex.Store({ - state: { - count: 0 - }, - mutations: { - increment(state) { - state.count++; - } - } -}); -``` - -Теперь мы можем получить доступ к объекту состояния `store.state` или вызвать изменение состояния методом `store.commit`: - -```js -store.commit('increment'); - -console.log(store.state.count); // -> 1 -``` - -Ещё раз заметим: мы вызываем мутацию, вместо того чтобы напрямую изменить `store.state.count`, потому что мы хотим явным образом отслеживать изменения. Это простое архитектурное соглашение делает намерения более очевидными и упрощает понимание изменений состояния приложения при чтении кода. Кроме того, этот подход позволяет реализовать инструменты для логирования каждой мутации, создания моментальных слепков состояния приложения и даже применения "машины времени" при отладке. - -Поскольку хранилище реактивно, для использования его состояния в компонентах достаточно просто создать вычисляемые свойства. Изменения состояния можно вызывать, инициализируя мутации в методах компонентов. - -Вот пример [простейшего приложения Vuex, реализующего счётчик](https://jsfiddle.net/n9jmu5v7/1269/). - -Далее мы подробно рассмотрим все основные понятия, начиная с [состояния](state.md) From 6ba73029a570be93bee57fffc11b455f44d43682 Mon Sep 17 00:00:00 2001 From: Alex Sokolov <4497128+Alex-Sokolov@users.noreply.github.com> Date: Sat, 27 Oct 2018 22:30:19 +0300 Subject: [PATCH 34/51] =?UTF-8?q?README.md=20=D0=BE=D0=B1=D0=BD=D0=BE?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ru/guide/README.md | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/docs/ru/guide/README.md b/docs/ru/guide/README.md index a5b2632e5..6a57cc7ee 100644 --- a/docs/ru/guide/README.md +++ b/docs/ru/guide/README.md @@ -1,19 +1,19 @@ # Введение -В центре любого Vuex-приложения находится **хранилище**. "Хранилище" — это, упрощённо говоря, контейнер, который хранит **состояние** вашего приложения. Два момента отличают хранилище Vuex от простого глобального объекта: +В центре любого Vuex-приложения находится **хранилище**. «Хранилище» — это контейнер, в котором хранится **состояние** вашего приложения. Два момента отличают хранилище Vuex от простого глобального объекта: -1. Хранилища Vuex реактивны. Если компоненты Vue зависят от их состояния, изменение состояния хранилища спровоцирует соответствующие изменения компонентов. +1. Хранилище Vuex реактивно. Когда компоненты Vue полагаются на его состояние, то они будут реактивно и эффективно обновляться, если состояние хранилища изменяется. -2. Непосредственное изменение состояния хранилища запрещено. Единственный способ внести изменения — явно **вызвать мутацию**. Этот подход позволяет быть уверенным, что каждое изменение оставляет в системе след и даёт возможность использовать инструменты, позволяющие лучше понять работу приложения. +2. Нельзя напрямую изменять состояние хранилища. Единственный способ внести изменения — явно **вызвать мутацию**. Это гарантирует, что любое изменение состояния оставляет след и позволяет использовать инструментарий, чтобы лучше понимать ход работы приложения. -### Простейшее Хранилище +### Простейшее хранилище -> **ЗАМЕЧАНИЕ:** Мы будем использовать синтаксис ES2015 для примеров кода на всём протяжении этой документации. Если вы с ним ещё не разобрались, [сейчас самое время](https://babeljs.io/docs/learn-es2015/)! +> **ЗАМЕЧАНИЕ:** В примерах кода документации используется синтаксис ES2015. Если вы с ним ещё не знакомы, [сейчас самое время изучить](https://babeljs.io/docs/learn-es2015/)! -После [установки](../installation.md) Vuex, давайте создадим хранилище. Всё довольно просто: нужно лишь указать исходное состояние и мутации: +После [установки](../installation.md) Vuex, давайте создадим хранилище. Это довольно просто — необходимо указать начальный объект состояния и некоторые мутации: ``` js -// Удостоверьтесь, что вызвали Vue.use(Vuex) в коде до этого, если используете модульный сборщик +// Убедитесь, что вызвали Vue.use(Vuex) сначала, если используете систему сборки const store = new Vuex.Store({ state: { @@ -27,7 +27,7 @@ const store = new Vuex.Store({ }) ``` -Теперь мы можем получить доступ к объекту состояния `store.state` или вызвать изменение состояния методом `store.commit`: +Теперь можно получить доступ к объекту состояния через `store.state` и вызвать изменение состояния с помощью метода `store.commit`: ``` js store.commit('increment') @@ -35,8 +35,10 @@ store.commit('increment') console.log(store.state.count) // -> 1 ``` -Ещё раз заметим: мы вызываем мутацию, вместо того чтобы напрямую изменить `store.state.count`, потому что мы хотим явным образом отслеживать изменения. Это простое архитектурное соглашение делает намерения более очевидными и упрощает понимание изменений состояния приложения при чтении кода. Кроме того, этот подход позволяет реализовать инструменты для логирования каждой мутации, создания моментальных слепков состояния приложения и даже применения "машины времени" при отладке. +Запомните, причина, по которой мы вызываем мутацию, вместо изменения `store.state.count` напрямую, в том, что мы хотим явным образом отслеживать её. Это простое соглашение делает наше намерение более явным, что упрощает понимание происходящих изменений состояния приложения при чтении кода. Кроме того, это позволяет использовать инструменты для отслеживания каждой мутации, создания снимков состояния или даже использования «машины времени» для отладки. -Using store state in a component simply involves returning the state within a computed property, because the store state is reactive. Triggering changes simply means committing mutations in component methods. +Использование состояние хранилища в компоненте предполагает просто возврат необходимой части состояния в вычисляемом свойстве, поскольку состояние хранилища реактивно. Инициирование изменений — это просто запуск мутаций в методах компонентов. Вот пример [простейшего приложения Vuex, реализующего счётчик](https://jsfiddle.net/n9jmu5v7/1269/). + +Далее мы разберём все основные понятия детальнее, начиная с состояния. From 5ce21fae185780013ee573fe1a25eb27ae0080d7 Mon Sep 17 00:00:00 2001 From: Alex Sokolov <4497128+Alex-Sokolov@users.noreply.github.com> Date: Sat, 27 Oct 2018 22:36:05 +0300 Subject: [PATCH 35/51] =?UTF-8?q?installation.md=20=D0=B8=D0=B7=D0=BC?= =?UTF-8?q?=D0=B5=D0=BD=D0=B5=D0=BD=D0=B0=20=D1=81=D1=81=D1=8B=D0=BB=D0=BA?= =?UTF-8?q?=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ru/installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/installation.md b/docs/ru/installation.md index c0645f13b..689704445 100644 --- a/docs/ru/installation.md +++ b/docs/ru/installation.md @@ -42,7 +42,7 @@ Vue.use(Vuex); ### Promise -Vuex использует в своей работе [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises). Если необходимо поддерживать старые браузеры, которые не реализуют Promise (например, IE) — добавьте полифил, например [es6-promise](https://github.com/stefanpenner/es6-promise). +Vuex использует в своей работе [Promise](https://developer.mozilla.org/ru/docs/Web/JavaScript/Guide/Ispolzovanie_promisov). Если необходимо поддерживать старые браузеры, которые не реализуют Promise (например, IE) — добавьте полифил, например [es6-promise](https://github.com/stefanpenner/es6-promise). Его можно подключить через CDN: From 99e90988d78b80822937a16e2cc96878cd2a4c1f Mon Sep 17 00:00:00 2001 From: Alex Sokolov <4497128+Alex-Sokolov@users.noreply.github.com> Date: Sat, 27 Oct 2018 22:36:12 +0300 Subject: [PATCH 36/51] =?UTF-8?q?README.md=20=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ru/guide/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/guide/README.md b/docs/ru/guide/README.md index 6a57cc7ee..68a98df75 100644 --- a/docs/ru/guide/README.md +++ b/docs/ru/guide/README.md @@ -41,4 +41,4 @@ console.log(store.state.count) // -> 1 Вот пример [простейшего приложения Vuex, реализующего счётчик](https://jsfiddle.net/n9jmu5v7/1269/). -Далее мы разберём все основные понятия детальнее, начиная с состояния. +Далее мы разберём все основные понятия детальнее и начнём с состояния. From 7a58c548b6e863ce0b371488419a2e2430a53e39 Mon Sep 17 00:00:00 2001 From: Alex Sokolov <4497128+Alex-Sokolov@users.noreply.github.com> Date: Sat, 27 Oct 2018 23:10:07 +0300 Subject: [PATCH 37/51] =?UTF-8?q?state.md=20=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ru/guide/state.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/ru/guide/state.md b/docs/ru/guide/state.md index ed0e9a211..6964110f6 100644 --- a/docs/ru/guide/state.md +++ b/docs/ru/guide/state.md @@ -2,13 +2,13 @@ ### Единое дерево состояния -Vuex использует **единое дерево состояния** — таким образом, один-единственный объект содержит всё глобальное состояние приложения и служит "единственным источником истины". Кроме того, это значит, что обычно для каждого приложения существует только одно хранилище. Благодаря единому дереву можно легко найти нужную часть состояния или делать слепки всего состояния приложения для отладки. +Vuex использует **единое дерево состояния** — когда один объект содержит всё глобальное состояние приложения и служит «единственным источником истины». Это также означает, что в приложении будет только одно такое хранилище. Единое дерево состояния позволяет легко найти нужную его часть или делать снимки текущего состояния приложения в целях отладки. -Единое дерево состояния не конфликтует с концепцией модульности — в последующих главах мы расскажем, как можно разбить хранилище на подмодули. +Единое дерево состояния не противоречит модульности — в следующих главах мы изучим, как можно разделить состояние и мутации на под-модули. -### Передача состояния Vuex в компоненты Vue +### Использование состояния Vuex в компонентах Vue -Так как же отобразить состояние хранилища в компонентах Vue? Поскольку хранилище Vuex реактивно, проще всего использовать [вычисляемые свойства](https://ru.vuejs.org/v2/guide/computed.html): +Итак, как использовать состояние хранилища в компонентах Vue? Поскольку хранилище Vuex реактивно, самый простой способ «получения» — просто вернуть часть состояния хранилища в [вычисляемом свойстве](https://ru.vuejs.org/v2/guide/computed.html): ```js // создадим компонент-счётчик: @@ -22,17 +22,17 @@ const Counter = { }; ``` -Любые изменения `store.state.count` вызовут обновление вычисляемого свойства, которые инициируют соответствующие обновления в DOM. +Любые изменения `store.state.count` вызовут перерасчёт вычисляемого свойства и запуск связанных с ним обновлений DOM. -Однако этот паттерн заставляет компонент явно полагаться на глобальный синглтон хранилища. При использовании модульной системы, это потребует импортирования хранилища в каждый компонент, использующий глобальное состояние и приведет к усложнению тестирования. +Однако этот паттерн заставляет компонент полагаться на синглтон глобального хранилища. При использовании модульной системы, это потребует импортировать хранилище в каждом компоненте, который использует его состояние, а также усложнит тестирование компонента. -Vuex предоставляет механизм "инъекции" хранилища всем потомкам компонента, у которого указана опция `store` (предварительно необходимо вызвать `Vue.use(Vuex)`): +Vuex предоставляет механизм «внедрения» хранилища во всех дочерних компонентах корневого компонента, у которого указана опция `store` (включается в `Vue.use(Vuex)`): ```js const app = new Vue({ el: '#app', - // указываем хранилище в опции "store", что обеспечит - // доступ к нему также и для всех дочерних компонентов + // указываем хранилище в опции «store», что обеспечит + // доступ к нему также и во всех дочерних компонентах store, components: { Counter }, template: ` @@ -43,7 +43,7 @@ const app = new Vue({ }); ``` -Указывая опцию `store` для корневого экземпляра, мы обеспечиваем доступ к хранилищу всем дочерним компонентам в `this.$store`. Давайте обновим наш пример со счётчиком: +Указывая опцию `store` в корневом экземпляре, мы обеспечиваем доступ к хранилищу во всех дочерних компонентах через `this.$store`. Давайте обновим реализацию `Counter`: ```js const Counter = { From e973bdb236cc5a341ec2da79c14f9bdcf0cbca0e Mon Sep 17 00:00:00 2001 From: Alex Sokolov <4497128+Alex-Sokolov@users.noreply.github.com> Date: Sat, 27 Oct 2018 23:47:17 +0300 Subject: [PATCH 38/51] =?UTF-8?q?state.md=20=D0=BF=D1=80=D0=B0=D0=B2=D0=BA?= =?UTF-8?q?=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ru/guide/state.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/docs/ru/guide/state.md b/docs/ru/guide/state.md index 6964110f6..303f97d58 100644 --- a/docs/ru/guide/state.md +++ b/docs/ru/guide/state.md @@ -58,22 +58,23 @@ const Counter = { ### Вспомогательная функция `mapState` -Если компонент использует множество свойств или геттеров хранилища, объявление доступа к ним всем вручную может заставить изрядно заскучать, да и код получится многословный. Чтобы обойти эту проблему, можно использовать хелпер `mapState`, автоматически генерирующий вычисляемые свойства, проксирующие доступ к состоянию и геттерам хранилища: +Когда компонент должен использовать множество свойств или геттеров хранилища, объявлять все эти вычисляемые свойства может быть утомительно. В таких случаях можно использовать функцию `mapState`, которая автоматически генерирует вычисляемые свойства: ```js -// с полной сборкой можно использовать как Vuex.mapState +// В полной сборке функция доступна через Vuex.mapState import { mapState } from 'vuex'; export default { // ... computed: mapState({ - // стрелочные функции позволяют писать код очень лаконично + // стрелочные функции могут сделать код очень кратким count: state => state.count, - // передача строки 'count' эквивалентна записи `state => state.count` + // передача строки 'count' аналогична записи `state => state.count` countAlias: 'count', - // если требуется доступ и к локальному состоянию, нужно использовать традиционную функцию + // для доступа к локальному состоянию через `this`, + // необходимо использовать обычную функцию countPlusLocalState(state) { return state.count + this.localCount; } @@ -81,23 +82,23 @@ export default { }; ``` -В простых случаях в `mapState` можно передать и просто массив строк: +Можно передавать массив строк в `mapState`, когда имя сопоставляемого вычисляемого свойства совпадает с именем в дереве состояний: ```js computed: mapState([ - // проксирует через this.count доступ к store.state.count + // проксирует в this.count доступ к store.state.count 'count' ]); ``` ### Оператор распространения объектов -Обратите внимание: `mapState` возвращает объект. Как же быть, если нам нужны и локальные вычисляемые свойства? Обычно в таких случаях приходилось использовать вспомогательные утилиты для слияния объектов, и передавать уже результат их работы в `computed`. Однако, применив [оператор распространения объектов](https://github.com/sebmarkbage/ecmascript-rest-spread) (находящегося в статусе stage-4 ECMAScript proposal) мы можем изрядно упростить запись: +Обратите внимание, `mapState` возвращает объект. Как же его использовать в сочетании с другими локальными вычисляемыми свойствами? Для этого обычно приходилось использовать вспомогательные утилиты для объединения нескольких объектов в один, который передавать в `computed`. Однако, с помощью [оператора распространения объектов](https://github.com/sebmarkbage/ecmascript-rest-spread) (предложение находится в статусе stage-4 ECMAScript) можно значительно упростить синтаксис: ```js computed: { localComputed () { /* ... */ }, - // результаты работы mapState будут добавлены в уже существующий объект + // смешиваем результат mapState с внешним объектом ...mapState({ // ... }) @@ -106,4 +107,4 @@ computed: { ### Компоненты всё ещё могут иметь локальное состояние -То что вы используете Vuex не значит, что нужно выносить в хранилище **всё** состояние приложения. Поместив большую часть логики во Vuex, вы сделаете мутации более красноречивыми и удобными для отладки, но это иногда может привести к излишней многословности и ненужному усложнению логики. Если состояние компонента полностью локально, выносить его во Vuex может быть бессмысленно. Конечное решение всегда остаётся на усмотрение разработчика и зависит от потребностей конкретного приложения. +Использование Vuex не означает, что необходимо выносить **всё состояние** в хранилище. Хотя перемещение большей части состояния во Vuex, сделает мутации более явными и удобными для отладки, иногда это также может привести к многословности и ненужному усложнению логики. Если часть состояния относится только к одному компоненту, оставить его в качестве локального состояния будет лучше. Вы должны взвесить все компромиссы и принять решение, соответствующее потребностям приложения и вектора его развития. From be50ee1c6a68c6e648f5e3d569623acc1548a452 Mon Sep 17 00:00:00 2001 From: Alex Sokolov <4497128+Alex-Sokolov@users.noreply.github.com> Date: Sun, 28 Oct 2018 00:23:03 +0300 Subject: [PATCH 39/51] =?UTF-8?q?getters.md=20=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ru/guide/getters.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/ru/guide/getters.md b/docs/ru/guide/getters.md index c545c46c5..9c9d1daed 100644 --- a/docs/ru/guide/getters.md +++ b/docs/ru/guide/getters.md @@ -1,6 +1,6 @@ # Геттеры -Иногда может понадобится доступ к производным данным, основывающимся на состоянии хранилища: например, к отфильтрованной версии списка или количеству элементов в нём: +Иногда может потребоваться вычислять производное состояние на основе состояния хранилища, например, отфильтровать список и затем подсчитать количество элементов: ```js computed: { @@ -10,11 +10,11 @@ computed: { } ``` -Если эта функциональность требуется более чем одному компоненту, понадобится либо дублировать функцию, либо выносить её в совместно используемый хелпер и импортировать в нескольких местах. Оба эти подхода далеки от идеала. +Если такие вычисления потребуются более чем в одном компоненте, придётся или дублировать функцию, или выносить её в общий метод, который затем импортировать во всех местах — оба подхода далеки от идеала. -Vuex позволяет определять в хранилище «геттеры». Вы можете считать их вычисляемыми свойствами для хранилища. Как и вычисляемые свойства, результаты геттера кэшируются, основываясь на своих зависимостях и будут пересчитаны только тогда, когда изменится одна из его зависимостей. +Vuex позволяет определять «геттеры» в хранилище. Можете считать их вычисляемыми свойствами хранилища. Как и вычисляемые свойства, результаты геттера кэшируются, на основе его зависимостей и пересчитываются только при изменении одной из зависимостей. -Геттеры получают первым аргументом ссылку на состояние хранилища: +Геттеры получают состояние хранилища первым аргументом: ```js const store = new Vuex.Store({ @@ -34,13 +34,13 @@ const store = new Vuex.Store({ ### Стиль обращения как к свойствам -Геттеры доступны в объекте `store.getters`, и вы можете получить доступ к значениям как для обычных свойств: +Геттеры доступны в объекте `store.getters`, и вы можете получить доступ к значениям как свойствам: ```js store.getters.doneTodos; // -> [{ id: 1, text: '...', done: true }] ``` -Вторым аргументом передаётся список всех геттеров: +Вторым аргументом передаются другие геттеры: ```js getters: { @@ -55,7 +55,7 @@ getters: { store.getters.doneTodosCount; // -> 1 ``` -Теперь мы можем легко использовать их внутри любых компонентов: +Теперь можно легко использовать его внутри любого компонента: ```js computed: { @@ -69,7 +69,7 @@ computed: { ### Стиль обращения как к методам -Вы также можете передавать аргументы геттерам возвращая функцию. Это особенно полезно, если вы хотите вернуть элемент (или часть элементов) массива по переданному критерию: +Можно также передавать аргументы геттерам, возвращая функцию. Это например пригодится, когда необходимо возвращать массив по указанному критерию: ```js getters: { @@ -88,7 +88,7 @@ store.getters.getTodoById(2); // -> { id: 2, text: '...', done: false } ### Вспомогательная функция `mapGetters` -Функция `mapGetters` попросту проксирует геттеры хранилища через локальные вычисляемые свойства компонента: +Функция `mapGetters` просто проксирует геттеры хранилища в локальные вычисляемые свойства компонента: ```js import { mapGetters } from 'vuex'; @@ -96,7 +96,7 @@ import { mapGetters } from 'vuex'; export default { // ... computed: { - // примешиваем геттеры в вычисляемые свойства оператором расширения + // смешиваем результат mapGetters с внешним объектом computed ...mapGetters([ 'doneTodosCount', 'anotherGetter' @@ -106,11 +106,11 @@ export default { }; ``` -Если вы хотите использовать при проксировании другое имя, примените объектный синтаксис: +Если необходимо указать другое имя, используйте объектный синтаксис: ```js ...mapGetters({ - // проксируем `this.doneCount` в `store.getters.doneTodosCount` + // проксирует `this.doneCount` в `store.getters.doneTodosCount` doneCount: 'doneTodosCount' }) ``` From 4017eda8bb544d5416b1daed3f9af0b668b7a8e0 Mon Sep 17 00:00:00 2001 From: Alex Sokolov <4497128+Alex-Sokolov@users.noreply.github.com> Date: Sun, 28 Oct 2018 00:25:04 +0300 Subject: [PATCH 40/51] README.md fix --- docs/ru/api/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/api/README.md b/docs/ru/api/README.md index 9da8e61fa..ac5f117dc 100644 --- a/docs/ru/api/README.md +++ b/docs/ru/api/README.md @@ -20,7 +20,7 @@ const store = new Vuex.Store({ ...options }); Корневой объект состояния хранилища Vuex. [Подробнее](../guide/state.md) - При передаче функции, возвращающей объект, возвращаемый объект будет использован в качестве корневого состояния. Это пригодится, если вы необходимо повторно использовать объект состояния, особенно при повторном использовании модулей. [Подробнее](../guide/modules.md#повторное-испоnьзование-модуnей) + При передаче функции, возвращающей объект, возвращаемый объект будет использован в качестве корневого состояния. Это пригодится, если необходимо повторно использовать объект состояния, особенно при повторном использовании модулей. [Подробнее](../guide/modules.md#повторное-испоnьзование-модуnей) ### mutations From 0a4d22616df455a119879e3ab271a4295da86f03 Mon Sep 17 00:00:00 2001 From: Alex Sokolov <4497128+Alex-Sokolov@users.noreply.github.com> Date: Sun, 28 Oct 2018 00:31:18 +0300 Subject: [PATCH 41/51] state.md fix --- docs/ru/guide/state.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/guide/state.md b/docs/ru/guide/state.md index 303f97d58..0c40c0638 100644 --- a/docs/ru/guide/state.md +++ b/docs/ru/guide/state.md @@ -107,4 +107,4 @@ computed: { ### Компоненты всё ещё могут иметь локальное состояние -Использование Vuex не означает, что необходимо выносить **всё состояние** в хранилище. Хотя перемещение большей части состояния во Vuex, сделает мутации более явными и удобными для отладки, иногда это также может привести к многословности и ненужному усложнению логики. Если часть состояния относится только к одному компоненту, оставить его в качестве локального состояния будет лучше. Вы должны взвесить все компромиссы и принять решение, соответствующее потребностям приложения и вектора его развития. +Использование Vuex **не означает, что необходимо выносить всё состояние** в хранилище. Хотя перемещение большей части состояния во Vuex, сделает мутации более явными и удобными для отладки, иногда это также может привести к многословности и ненужному усложнению логики. Если часть состояния относится только к одному компоненту, оставить его в качестве локального состояния будет лучше. Вы должны взвесить все компромиссы и принять решение, соответствующее потребностям приложения и вектора его развития. From bb69c9c9d2bf74bf0eab5914ed4792799a13f7f3 Mon Sep 17 00:00:00 2001 From: Alex Sokolov <4497128+Alex-Sokolov@users.noreply.github.com> Date: Sun, 28 Oct 2018 00:33:42 +0300 Subject: [PATCH 42/51] =?UTF-8?q?state.md=20=D0=BF=D1=80=D0=B0=D0=B2=D0=BA?= =?UTF-8?q?=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ru/guide/state.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/guide/state.md b/docs/ru/guide/state.md index 0c40c0638..274a7995d 100644 --- a/docs/ru/guide/state.md +++ b/docs/ru/guide/state.md @@ -107,4 +107,4 @@ computed: { ### Компоненты всё ещё могут иметь локальное состояние -Использование Vuex **не означает, что необходимо выносить всё состояние** в хранилище. Хотя перемещение большей части состояния во Vuex, сделает мутации более явными и удобными для отладки, иногда это также может привести к многословности и ненужному усложнению логики. Если часть состояния относится только к одному компоненту, оставить его в качестве локального состояния будет лучше. Вы должны взвесить все компромиссы и принять решение, соответствующее потребностям приложения и вектора его развития. +Использование Vuex **не означает, что нужно выносить всё состояние** в хранилище. Хотя перемещение большей части состояния во Vuex, сделает мутации более явными и удобными для отладки, это также может привести к многословности и ненужному усложнению логики. Если часть состояния относится только к одному компоненту, лучше оставить его в качестве локального состояния. Вы должны взвесить все компромиссы и принять решение, соответствующее потребностям приложения и вектора его развития. From 8efbf96f0e37364ed55fc23342578da71d51f17e Mon Sep 17 00:00:00 2001 From: Alex Sokolov <4497128+Alex-Sokolov@users.noreply.github.com> Date: Mon, 12 Nov 2018 20:33:09 +0300 Subject: [PATCH 43/51] =?UTF-8?q?hot-reload.md=20=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ru/guide/hot-reload.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/guide/hot-reload.md b/docs/ru/guide/hot-reload.md index ab4b6b10e..564d1b982 100644 --- a/docs/ru/guide/hot-reload.md +++ b/docs/ru/guide/hot-reload.md @@ -30,7 +30,7 @@ if (module.hot) { // (нужно указать .default из-за формата вывода Babel 6) const newMutations = require('./mutations').default const newModuleA = require('./modules/a').default - // заменяем старые действия и мутации новыми + // заменяем на новые модули и мутации store.hotUpdate({ mutations: newMutations, modules: { From ac086d3e32eeb80995ad7dd446ae64a44f9e4221 Mon Sep 17 00:00:00 2001 From: Alex Sokolov <4497128+Alex-Sokolov@users.noreply.github.com> Date: Mon, 12 Nov 2018 20:34:10 +0300 Subject: [PATCH 44/51] =?UTF-8?q?mutations.md=20=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ru/guide/mutations.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/ru/guide/mutations.md b/docs/ru/guide/mutations.md index a701a4ffb..7b1530a15 100644 --- a/docs/ru/guide/mutations.md +++ b/docs/ru/guide/mutations.md @@ -85,13 +85,13 @@ mutations: { 2. При добавлении новых свойств объекту необходимо либо: -* Использовать `Vue.set(obj, 'newProp', 123)`, или + * Использовать `Vue.set(obj, 'newProp', 123)`, или -* Целиком заменить старый объект новым. Например, используя [синтаксис расширения объектов](https://github.com/sebmarkbage/ecmascript-rest-spread) из stage-3, можно написать так: + * Целиком заменить старый объект новым. Например, используя [синтаксис расширения объектов](https://github.com/sebmarkbage/ecmascript-rest-spread) можно написать так: - ```js - state.obj = { ...state.obj, newProp: 123 }; - ``` + ```js + state.obj = { ...state.obj, newProp: 123 }; + ``` ### Использование констант для обозначения типов мутаций From 67983b789cf988e37695660479c8caf1e087acf1 Mon Sep 17 00:00:00 2001 From: Alex Sokolov <4497128+Alex-Sokolov@users.noreply.github.com> Date: Wed, 9 Jan 2019 23:37:27 +0300 Subject: [PATCH 45/51] README.md add video-preview component --- docs/ru/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/ru/README.md b/docs/ru/README.md index 4b6656521..cdc6b6bdf 100644 --- a/docs/ru/README.md +++ b/docs/ru/README.md @@ -1,5 +1,7 @@ # Что такое Vuex? + + Vuex — **паттерн управления состоянием + библиотека** для приложений на Vue.js. Он служит централизованным хранилищем данных для всех компонентов приложения с правилами, гарантирующими, что состояние может быть изменено только предсказуемым образом. Vuex интегрируется с официальным расширением [vue-devtools](https://github.com/vuejs/vue-devtools), предоставляя «из коробки» такие продвинутые возможности, как «машину времени» для отладки и экспорт/импорт слепков состояния данных. ### Что такое «паттерн управления состоянием»? From 92bb4eab91f17c83e0f9ce3f8ae554e307fdb51e Mon Sep 17 00:00:00 2001 From: Alex Sokolov <4497128+Alex-Sokolov@users.noreply.github.com> Date: Thu, 17 Jan 2019 22:04:32 +0300 Subject: [PATCH 46/51] api/README.md added about subscribeAction before/after --- docs/ru/api/README.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/docs/ru/api/README.md b/docs/ru/api/README.md index ac5f117dc..93256d883 100644 --- a/docs/ru/api/README.md +++ b/docs/ru/api/README.md @@ -120,7 +120,7 @@ const store = new Vuex.Store({ ...options }); * тип: `Boolean` - Интеграция в devtools конкретного экземпляра Vuex. Например, передача `false` сообщает экземпляру хранилища Vuex, что не требуется подписываться на плагин devtools. Это будет полезно если у вас несколько хранилищ на одной странице. + Интеграция в devtools конкретного экземпляра Vuex. Например, передача `false` сообщает экземпляру хранилища Vuex, что не требуется подписываться на плагин devtools. Это будет полезно если у вас несколько хранилищ на одной странице. ``` js { @@ -206,6 +206,21 @@ store.subscribeAction((action, state) => { Для прекращения отслеживания, необходимо вызвать возвращаемую методом функцию. +> Добавлено в версии 3.1.0 + +Начиная с версии 3.1.0, в `subscribeAction` также можно определять, должен ли обработчик вызываться *до* или *после* вызова действия (по умолчанию поведение *до*): + +``` js +store.subscribeAction({ + before: (action, state) => { + console.log(`before action ${action.type}`) + }, + after: (action, state) => { + console.log(`after action ${action.type}`) + } +}) +``` + Чаще всего используется в плагинах. [Подробнее](../guide/plugins.md) ### registerModule From fae9eec55f41b4d7c24a08f7da1cbad54c5b1bd8 Mon Sep 17 00:00:00 2001 From: Alex Sokolov <4497128+Alex-Sokolov@users.noreply.github.com> Date: Thu, 31 Jan 2019 16:54:23 +0300 Subject: [PATCH 47/51] modules.md update --- docs/ru/guide/modules.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/ru/guide/modules.md b/docs/ru/guide/modules.md index b4f53cd10..f080afc5a 100644 --- a/docs/ru/guide/modules.md +++ b/docs/ru/guide/modules.md @@ -292,7 +292,11 @@ store.registerModule(['nested', 'myModule'], { Удалить динамически зарегистрированный модуль можно с помощью `store.unregisterModule(moduleName)`. Обратите внимание, что статические (определённые на момент создания хранилища) модули при помощи этого метода удалить не получится. -Вероятно, вы хотите сохранить предыдущее состояние при регистрации нового модуля, например сохранить состояние из приложения с рендерингом на стороне сервера. Вы можете этого добиться с помощью опции `preserveState`: `store.registerModule('a', module, { preserveState: true })` +#### Сохранение состояния + +Вероятно, вы хотите сохранить предыдущее состояние при регистрации нового модуля, например сохранить состояние из приложения с рендерингом на стороне сервера. Вы можете этого добиться с помощью опции `preserveState`: `store.registerModule('a', module, { preserveState: true })`. + +При использовании `preserveState: true` модуль регистрируется, действия, мутации и геттеры добавляются в хранилище, а состояние нет. Предполагается, что состояние вашего хранилища уже содержит состояние для этого модуля и нет необходимости его перезаписывать. ### Повторное использование модулей From 82bf80d528397ecbd61adb572a4d1d5c232ff34d Mon Sep 17 00:00:00 2001 From: Alex Sokolov <4497128+Alex-Sokolov@users.noreply.github.com> Date: Mon, 25 Mar 2019 12:15:29 +0300 Subject: [PATCH 48/51] README.md update --- docs/ru/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/ru/README.md b/docs/ru/README.md index d8523f05b..32ab82328 100644 --- a/docs/ru/README.md +++ b/docs/ru/README.md @@ -50,7 +50,7 @@ new Vue({ Так почему бы не вынести всё общее состояние приложения из компонентов и управлять им в глобальном синглтоне? При этом наше дерево компонентов становится одним большим «представлением» и любой компонент может получить доступ к состоянию приложения или вызывать действия для изменения состояния, независимо от того, где они находятся в дереве! -Кроме того, чётко определяя и разделяя концепции, возникающие при управлении состоянием, и требуя соблюдения определённых правил, мы лучше структурируем код и облегчаем его поддержку. +Чётко определяя и разделяя концепции, возникающие при управлении состоянием, и требуя соблюдения определённых правил, которые поддерживают независимость между представлениеями и состояниями, мы лучше структурируем код и облегчаем его поддержку. Это основная идея Vuex, вдохновлённого [Flux](https://facebook.github.io/flux/docs/overview.html), [Redux](http://redux.js.org/) и [Архитектурой Elm](https://guide.elm-lang.org/architecture/). В отличие от других паттернов, Vuex реализован в виде библиотеки, специально предназначенной для Vue.js, чтобы использовать его систему реактивности для эффективного обновления. @@ -60,7 +60,7 @@ new Vue({ ### Когда следует использовать Vuex? -Хотя Vuex помогает управлять совместно используемым состоянием, это реализуется ценой привнесения новых концепций и вспомогательного кода. Компромисс, когда кратковременная продуктивность страдает на благо долгосрочной. +Vuex помогает управлять совместно используемым состоянием, ценой привнесения новых концепций и вспомогательного кода. Компромисс, когда кратковременная продуктивность страдает на благо долгосрочной. Если ещё не приходилось создавать крупные SPA и вы лишь знакомитесь с Vuex, это может показаться многословным и сложным. Всё в порядке — простые приложения могут легко обходиться и без Vuex. Возможно, будет достаточно простого паттерна [глобальной шины событий](https://ru.vuejs.org/v2/guide/state-management.html#Простой-контейнер-состояния-с-нуля). Но если вы создаёте SPA среднего или крупного размера, то, скорее всего, уже сталкивались с ситуациями, которые заставляли задуматься о том, как лучше управлять состоянием вне компонентов Vue, а Vuex в таком случае может стать вполне естественным следующим шагом. Есть хорошая цитата от Дэна Абрамова, автора Redux: From ab33fb6f41867bb63633b5d05b8a0836fc18acbf Mon Sep 17 00:00:00 2001 From: Alex Sokolov <4497128+Alex-Sokolov@users.noreply.github.com> Date: Sat, 27 Jul 2019 00:43:15 +0300 Subject: [PATCH 49/51] README.md fix --- docs/ru/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/README.md b/docs/ru/README.md index 32ab82328..25a44203a 100644 --- a/docs/ru/README.md +++ b/docs/ru/README.md @@ -50,7 +50,7 @@ new Vue({ Так почему бы не вынести всё общее состояние приложения из компонентов и управлять им в глобальном синглтоне? При этом наше дерево компонентов становится одним большим «представлением» и любой компонент может получить доступ к состоянию приложения или вызывать действия для изменения состояния, независимо от того, где они находятся в дереве! -Чётко определяя и разделяя концепции, возникающие при управлении состоянием, и требуя соблюдения определённых правил, которые поддерживают независимость между представлениеями и состояниями, мы лучше структурируем код и облегчаем его поддержку. +Чётко определяя и разделяя концепции, возникающие при управлении состоянием, и требуя соблюдения определённых правил, которые поддерживают независимость между представлениями и состояниями, мы лучше структурируем код и облегчаем его поддержку. Это основная идея Vuex, вдохновлённого [Flux](https://facebook.github.io/flux/docs/overview.html), [Redux](http://redux.js.org/) и [Архитектурой Elm](https://guide.elm-lang.org/architecture/). В отличие от других паттернов, Vuex реализован в виде библиотеки, специально предназначенной для Vue.js, чтобы использовать его систему реактивности для эффективного обновления. From f7a918df59a9dbdf22bcc29c94fd793b11982072 Mon Sep 17 00:00:00 2001 From: Alex Sokolov <4497128+Alex-Sokolov@users.noreply.github.com> Date: Tue, 13 Aug 2019 17:03:16 +0300 Subject: [PATCH 50/51] state.md update --- docs/ru/guide/state.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/ru/guide/state.md b/docs/ru/guide/state.md index 462d66457..25c064ab2 100644 --- a/docs/ru/guide/state.md +++ b/docs/ru/guide/state.md @@ -8,6 +8,8 @@ Vuex использует **единое дерево состояния** — Единое дерево состояния не противоречит модульности — в следующих главах мы изучим, как можно разделить состояние и мутации на под-модули. +Данные, которые хранятся во Vuex должны следовать тем же правилам, что и `data` в экземпляре Vue, т.е. объект состояния должен быть простым. **См. также:** [Vue#data](https://ru.vuejs.org/v2/api/#data). + ### Использование состояния Vuex в компонентах Vue Итак, как использовать состояние хранилища в компонентах Vue? Поскольку хранилище Vuex реактивно, самый простой способ «получения» — просто вернуть часть состояния хранилища в [вычисляемом свойстве](https://ru.vuejs.org/v2/guide/computed.html): From 838a687a09daa373f119cad5872895ea7d58413f Mon Sep 17 00:00:00 2001 From: Alex Sokolov <4497128+Alex-Sokolov@users.noreply.github.com> Date: Tue, 13 Aug 2019 17:05:47 +0300 Subject: [PATCH 51/51] mutations.md fix --- docs/ru/guide/mutations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/guide/mutations.md b/docs/ru/guide/mutations.md index 81033830a..cfca0198e 100644 --- a/docs/ru/guide/mutations.md +++ b/docs/ru/guide/mutations.md @@ -141,7 +141,7 @@ mutations: { ### Вызов мутаций в компонентах -Мутации можно вызывать из кода компонентов, используя `this.$store.commit('xxx')`, или применяя хелпер `mapMutations`, который проксирует вызовы `store.commit` через методы компонентов (для этого требуется наличие корневой ссылки на хранилище `$store`): +Мутации можно вызывать из кода компонентов, используя `this.$store.commit('xxx')`, или применяя вспомогательный метод `mapMutations`, который проксирует вызовы `store.commit` через методы компонентов (для этого требуется наличие корневой ссылки на хранилище `$store`): ```js import { mapMutations } from 'vuex';