Vue.js 2.0 についての Vuex 2.0 更新する必要があるナレッジ ベース

高洛峰
リリース: 2016-12-03 13:22:24
オリジナル
1393 人が閲覧しました

アプリケーション構造

実際、Vuex にはコード構造の編成方法に制限がありません。それどころか、次のような一連の高レベルの原則が強制されます。

1. アプリケーション レベルのステータスはストアに集中します。

2. 状態を変更する唯一の方法は、同期トランザクションであるミューテーションを送信することです。

3. 非同期ロジックは動作中にカプセル化する必要があります。

これらのルールに従っている限り、プロジェクトをどのように構成するかはあなた次第です。ストア ファイルが非常に大きい場合は、アクション ファイル、ミューテーション ファイル、ゲッター ファイルに分割してください。

もう少し複雑なアプリケーションの場合は、モジュールを使用する必要がある場合があります。以下は、単純なプロジェクト構造です:

§──index.html
§──main.js
§──api
│ └── ... # ここで API リクエストを開始します
├── コンポーネント
│ §── ─ App.Vuep│ └ ── ...
└ ─ ─ ─ ─ ─ i — ├ § § § ─ ─ ActionS.js # § ─ ─ Mutations.js # ルート変異 変異
└─ モジュール
っていつ─ cart.js └── cart.js └── products.js # products モジュール


詳細については、ショッピング カートの例をご覧ください。

モジュール

単一の状態ツリーを使用するため、アプリケーションのすべての状態が 1 つの大きなオブジェクトに含まれます。しかし、アプリケーションの規模が拡大し続けるにつれて、このストアは非常に肥大化してきました。

この問題を解決するために、Vuex ではストアをモジュールに分割することができます。各モジュールには、独自の状態、突然変異、アクション、ゲッターが含まれており、入れ子になったモジュールも含まれます。これは、次のように構成されています。モジュールのローカル状態です。

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's state
store.state.b // -> moduleB's state
ログイン後にコピー

同様に、モジュールのアクションでは、context.state はローカル状態を公開し、context.rootState はルート状態を公開します。

const moduleA = {
 state: { count: 0 },
 mutations: {
 increment: (state) {
  // state 是模块本地的状态。
  state.count++
 }
 },
 
 getters: {
 doubleCount (state) {
  return state.count * 2
 }
 }
}
ログイン後にコピー

モジュールのゲッターでは、ルート状態も 3 番目のパラメーターとして公開されます。

const moduleA = {
 // ...
 actions: {
 incrementIfOdd ({ state, commit }) {
  if (state.count % 2 === 1) {
  commit('increment')
  }
 }
 }
}
ログイン後にコピー

名前空間

モジュール内のアクション、ミューテーション、ゲッターは依然としてグローバル名前空間に登録されていることに注意してください。これにより、複数のモジュールが同じミューテーション/アクション タイプに応答できるようになります。モジュール名にプレフィックスまたはサフィックスを追加して名前空間を設定し、名前の競合を避けることができます。 Vuex モジュールが再利用可能で、実行環境が不明な場合は、これを行う必要があります。距離、todos モジュールを作成したい:

const moduleA = {
 // ...
 getters: {
 sumWithRootCount (state, getters, rootState) {
  return state.count + rootState.count
 }
 }
}
ログイン後にコピー

動的モジュールを登録する

ストアの作成後に、store.registerModule メソッドを使用してモジュールを登録できます:

// types.js
 
// 定义 getter、 action 和 mutation 的常量名称
// 并且在模块名称上加上 `todos` 前缀
export const DONE_COUNT = 'todos/DONE_COUNT'
export const FETCH_ALL = 'todos/FETCH_ALL'
export const TOGGLE_DONE = 'todos/TOGGLE_DONE'
// modules/todos.js
import * as types from '../types'
 
// 用带前缀的名称来定义 getters, actions and mutations
const todosModule = {
 state: { todos: [] },
 
 getters: {
 [types.DONE_COUNT] (state) {
  // ...
 }
 },
 
 actions: {
 [types.FETCH_ALL] (context, payload) {
  // ...
 }
 },
 
 mutations: {
 [types.TOGGLE_DONE] (state, payload) {
  // ...
 }
 }
}
ログイン後にコピー

モジュールのストア.state.myModule はモジュールの状態として公開されます。

他の Vue プラグインは、モジュールをアプリケーション ストアにアタッチし、動的登録を通じて Vuex の状態管理機能を使用できます。たとえば、vuex-router-sync ライブラリは、動的に登録されたモジュールでアプリケーションのルーティング状態を管理することにより、vue-router と vuex を統合します。

store.unregisterModule(moduleName) を使用して、動的に登録されたモジュールを削除することもできます。ただし、このメソッドを使用して静的モジュール (つまり、ストアの作成時に宣言されたモジュール) を削除することはできません。

プラグイン

Vuex のストアは、各ミューテーションのフックを公開するプラグイン オプションを受け取ります。 Vuex プラグインは、sotre を唯一のパラメーターとして受け入れる単純なメソッドです:

store.registerModule('myModule', {
 // ...
})
ログイン後にコピー

次に、次のように使用します:

const myPlugin = store => {
 // 当 store 在被初始化完成时被调用
 store.subscribe((mutation, state) => {
 // mutation 之后被调用
 // mutation 的格式为 {type, payload}。
 })
}
ログイン後にコピー

プラグイン内でミューテーションを送信

プラグインはできません状態を直接変更します。これは、コンポーネントと同様に、突然変異によってのみ変更できます。

ミューテーションを送信すると、プラグインを使用してデータ ソースをストアに同期できます。たとえば、WebSocket データ ソースをストアに同期するために (これは使用法を説明するための単なる例であり、実際には、複雑なタスクを完了するためのより多くのオプションが createPlugin メソッドに追加されます)。

const store = new Vuex.Store({
 // ...
 plugins: [myPlugin]
})
ログイン後にコピー

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)
  }
 })
 }
}
ログイン後にコピー

ステータススナップショットの生成

プラグインはステータスの「スナップショット」とステータスの変更前後の変更を取得したい場合があります。これらの関数を実装するには、状態オブジェクトのディープ コピーが必要です。

const plugin = createWebSocketPlugin(socket)
 
const store = new Vuex.Store({
 state,
 mutations,
 plugins: [plugin]
})
ログイン後にコピー

** 状態スナップショットを生成するプラグインは、開発段階でのみ使用できます。Webpack または Browserify を使用してください。ビルド ツールがそれを処理します:

const myPluginWithSnapshot = store => {
 let prevState = _.cloneDeep(store.state)
 store.subscribe((mutation, state) => {
 let nextState = _.cloneDeep(state)
 
 // 对比 prevState 和 nextState...
 
 // 保存状态,用于下一次 mutation
 prevState = nextState
 })
}
ログイン後にコピー

プラグインはデフォルトで有効になります。本番環境に出荷するには、Webpack の DefinePlugin または Browserify の envify を使用して process.env.NODE_ENV !== 'production' を false に変換する必要があります。

組み込みロガープラグイン

如果你正在使用 vue-devtools,你可能不需要。

Vuex 带来一个日志插件用于一般的调试:

import createLogger from 'vuex/dist/logger'
 
const store = new Vuex.Store({
 plugins: [createLogger()]
})
ログイン後にコピー

createLogger 方法有几个配置项:

const logger = createLogger({
 collapsed: false, // 自动展开记录 mutation
 transformer (state) {
 // 在记录之前前进行转换
 // 例如,只返回指定的子树
 return state.subTree
 },
 mutationTransformer (mutation) {
 // mutation 格式 { type, payload }
 // 我们可以按照想要的方式进行格式化
 return mutation.type
 }
})
ログイン後にコピー

日志插件还可以直接通过

人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート