ホームページ  >  記事  >  ウェブフロントエンド  >  Vue.js 2.0 についての Vuex 2.0 更新する必要があるナレッジ ベース

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

高洛峰
高洛峰オリジナル
2016-12-03 13:22:241359ブラウズ

アプリケーション構造

実際、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
 }
})

   

日志插件还可以直接通过 3f1c4e4b6b16bbbd69b2ee476dc4f83a 标签, 然后它会提供全局方法 createVuexLogger 。

要注意,logger 插件会生成状态快照,所以仅在开发环境使用。

严格模式

要启用严格模式,只需在创建 Vuex store 的时候简单地传入 strict: true。

const store = new Vuex.Store({
 // ...
 strict: true
})

   

在严格模式下,只要 Vuex 状态在 mutation 方法外被修改就会抛出错误。这确保了所有状态修改都会明确的被调试工具跟踪。

开发阶段 vs. 发布阶段

不要在发布阶段开启严格模式! 严格模式会对状态树进行深度监测来检测不合适的修改 —— 确保在发布阶段关闭它避免性能损耗。
跟处理插件的情况类似,我们可以让构建工具来处理:

const store = new Vuex.Store({
 // ...
 strict: process.env.NODE_ENV !== 'production'
})

   


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。