Vuex ステートマシンの簡単な理解とサンプルアプリケーション

Vuex ステートマシンの簡単な理解とサンプルアプリケーション

1. 概念の素早い理解:

1. コンポーネント間でデータを共有する方法:

通常、次のような方法があります。

  1. 親から子に値を渡す: v-bind 属性バインディング;
  2. 子が親に値を渡します: v-on イベント バインディング;
  3. 兄弟コンポーネント間でデータを共有する: EventBus ;

2. vuex とは何か:

  1. 公式声明によると、Vuex は Vue.js アプリケーション専用に開発された状態管理モードです。集中型ストレージを使用してアプリケーションのすべてのコンポーネントのステータスを管理し、対応するルールを使用して、ステータスが予測可能な方法で変更されるようにします。 Vuex は、Vue の公式デバッグ ツール devtools 拡張機能 (新しいウィンドウで開きます) にも統合されており、ゼロ構成のタイムトラベル デバッグ、状態スナップショットのインポートとエクスポートなどの高度なデバッグ機能を提供します。
  2. Vuex は簡単に言うと、コンポーネントのグローバルな状態 (データ) 管理を実装するための仕組みであり、コンポーネント間のデータ共有を簡単に実現できます。

3. vuex を使用する利点:

  1. vuex で共有データを集中管理できるため、開発とその後のメンテナンスが容易になります。
  2. コンポーネント間のデータ共有を効率的に実現し、開発効率を向上できます。
  3. vuex に保存されたデータは応答性が高く、データとページをリアルタイムで同期させることができます。
  4. 親子関係のないコンポーネントのメッセージ パッシングを解決します (状態にデータを保存します)。
  5. AJAX リクエストの数が削減され、一部のシナリオではメモリ内の状態から直接取得できるようになります。

一般的に言えば、コンポーネント間で共有されるデータのみを vuex に保存する必要があります。ただし、コンポーネント内のプライベート データの場合、これは必要ではなく、コンポーネント独自のデータに保存することもできます。もちろん、すべてを vuex に保存したい場合も問題ありません。

2. 基本的な使い方:

1. 依存パッケージをインストールします。

npm インストール vuex --save

2. 依存パッケージをインポートします。

'vue' から Vue をインポートします
'vuex' から Vuex をインポートします

Vue.use(Vuex)

3. ストアオブジェクトを作成します。

'vue' から Vue をインポートします
'vuex' から Vuex をインポートします

Vue.use(Vuex)

定数ストア = 新しい Vuex.Store({
//状態はグローバルに共有されるデータ状態を格納します: {
    カウント: 0
  }
})

4. ストア オブジェクトを Vue インスタンスにマウントします。

新しいVue({
  el: '#app',
  店
})

この時点で、すべてのコンポーネントはストアからデータを取得できます。

3. プロジェクトを作成します。

以下は、 vue プロジェクトを作成するプロセスであり、後ほどケースが存在します。

(1) cmdウィンドウを開き、vue uiと入力してVue視覚化パネルを開きます。

(2)新しいプロジェクトパスを選択します。

(3)命名:

(4)手動で設定を選択します。vue2バージョンが使用されることに注意してください。

(5)作成:

(6)次のステップ:

(7)作成が成功したら、対応するディレクトリに移動し、vscodeを開いてプログラミングを開始します。

(8)プロジェクトを実行する:

4.説明の前提条件:

前提条件(注意):

小さなカウンターケースを記述し、ケース概念を組み合わせることで、 vuex をより早く使い始めることができます。したがって、この小さなケースに基づいて、コアコンセプトの次のコードセクションが実証されます。目標: 共通のカウント値を持つ 2 つの子コンポーネントを作成します。親コンポーネントでは、1 つのコンポーネントはクリック後にカウント値を 1 減らし、もう 1 つのコンポーネントはクリック後にカウント値を 1 増やします。

親コンポーネント App.vue の初期コード:

<テンプレート>
  <div id="アプリ">
       <私の追加></私の追加>
       <p>--------------------</p>
       <私の削減></私の削減>
  </div>
</テンプレート>

<スクリプト>
// コンポーネントをインポートする import Add from './components/Add.vue'
'./components/Reduce.vue' から Reduce をインポートします。
エクスポートデフォルト{
  名前: 'アプリ'、
  データ() {
    戻る {
      
    }
  },
  コンポーネント:
    'my-add': 追加、
    'my-reduce': 削減
  }

}
</スクリプト>

サブコンポーネント Add.vue 初期コード:

<テンプレート>
    <div>
        <p>カウント値は次のとおりです:</p>
           <ボタン>+1</ボタン>
    </div>
 
</テンプレート>
<スクリプト>
  エクスポートデフォルト{
      データ() {
          戻る {
              
          }
      },
  }
</スクリプト>

サブコンポーネント Reduce.vue の初期コード:

<テンプレート>
    <div>
         <p>カウント値は次のとおりです:</p>
           <ボタン>-1</ボタン>
    </div>
</テンプレート>
<スクリプト>
  エクスポートデフォルト{
      データ() {
          戻る {
              
          }
      },
  }
</スクリプト>

ストア オブジェクトの初期コードは次のとおりです。

'vue' から Vue をインポートします
'vuex' から Vuex をインポートします

Vue.use(Vuex)

デフォルトの新しいVuex.Storeをエクスポートします({
  州: {
    カウント: 0
  }
})

初期効果:

5. コアコンセプト:

1.状態:

公式の説明によれば、Vuex は単一の状態ツリーを使用します。つまり、1 つのオブジェクトにアプリケーション レベルの状態全体が含まれます。この時点から、それは「単一のデータソース (SSOT)」として存在します。これは、各アプリケーションにストア インスタンスが 1 つだけ含まれることも意味します。

簡単に言えば、State は唯一のパブリック データ ソースを提供し、共有されるすべてのデータは Store の State に保存される必要があります。

1.1 コンポーネント内の状態にアクセスする最初の方法:

コンポーネントに次のコマンドを直接入力します。

this.$store.state によって参照されるデータ名。

Add.vue サブコンポーネントで引用されているとおり:

<テンプレート>
    <div>
        <p>カウント値は: {{this.$store.state.count}}</p>
           <ボタン>+1</ボタン>
    </div> 
</テンプレート>
//次のコードは前と同じなので省略します

効果を見ると、count の値は 0 であることがわかります。

1.2 コンポーネント内の状態にアクセスする 2 番目の方法:

(1) 必要に応じてvuexからmapState関数をインポートする

'vuex' から { mapState } をインポートします。

(2)先ほどインポートしたmapState関数を通じて、現在のコンポーネントに必要なグローバルデータが現在のコンポーネントの計算されたプロパティにマッピングされます。

計算: {
   ...mapState([count])
}

ヒント: computed は、自己定義変数を監視するために使用されます。変数はデータで宣言されず、computed で直接定義されます。次に、双方向データ バインディングをページで実行して結果を表示したり、他の処理に使用したりできます。

Reduce.vue サブコンポーネントで引用されているとおり:

<テンプレート>
    <div>
         <p>カウント値は: {{count}}</p>
           <ボタン>-1</ボタン>
    </div>
</テンプレート>
<スクリプト>
'vuex' から {mapState} をインポートします。
  エクスポートデフォルト{
      データ() {
          戻る {
              
          }
      },
      計算: {
         ...mapState(['count'])
      }
  }
</スクリプト>

効果を見ると、count の値も 0 であることが示されています。

2. 突然変異:

公式声明によると、Vuex ストア内の状態を変更する唯一の方法は、ミューテーションを送信することです。 Vuex のミューテーションはイベントと非常によく似ています。各ミューテーションには、文字列イベント タイプ (type) とコールバック関数 (handler) があります。このコールバック関数は、実際に状態の変更を行う場所であり、最初の引数として状態を受け取ります。

簡単に言えば、Mutation はストア内のデータを変更するために使用されます。
① ストアデータはミューテーションを通じてのみ変更可能であり、ストア内のデータを直接操作することはできません。
②操作が​​少し複雑になりますが、すべてのデータの変化を一元的に監視することができます。

例えば、カウント値を 1 増やす操作を実装するには、まずモーション内で 1 ずつ増加する関数を定義します。その後、対応するサブコンポーネントがそれを使用したい場合は、コンポーネントは直接ミューテーションを導入し、対応する関数を呼び出すことができます。

次のように、Add.vue サブコンポーネントは自己インクリメント 1 関数を実装する必要があります。

まず、ステート マシン内の変化において自己増分を実現できる関数 add を定義します。

デフォルトの新しいVuex.Storeをエクスポートします({
  州: {
    カウント: 0
  },
  突然変異:
    // 自己増分 1 関数 add(state){
      状態.count++
    }
  }
})

2.1 突然変異を誘発する最初の方法:

Add.vue サブコンポーネントで、クリック イベントをボタンにバインドし、ミューテーションをトリガーします。

<テンプレート>
    <div>
        <p>カウント値は: {{this.$store.state.count}}</p>
           <button @click="btnAdd">+1</button>
    </div>
 
</テンプレート>
<スクリプト>
  エクスポートデフォルト{
      データ() {
          戻る {
              
          }
      },
      メソッド: {
          btnAdd() {
              // 変化を導入する最初の方法は、追加関数をトリガーすることです this.$store.commit('add')
          }
      }
  }
</スクリプト>

クリックによる自己増加を実現する効果を見てみましょう。

2.2 ミューテーションをトリガーし、パラメータを渡す:

もちろん、コンポーネントがミューテーション内の関数を呼び出すときに、パラメータを渡すこともできます。

たとえば、自己増分関数がありますが、増分量は呼び出し時に渡されるパラメータによって異なります。

デフォルトの新しいVuex.Storeをエクスポートします({
  州: {
    カウント: 0
  },
  突然変異:
    // パラメータを渡します。最初のパラメータは state で、2 番目のパラメータは渡されたパラメータです // n を自身で増やす関数 addN(state,n){
      状態数 += n
    }
  }
})

対応するコンポーネントを呼び出すときは、パラメータを渡す必要があります。

  メソッド: {
          btnAdd2() {
              // ミューテーションメソッドを導入し、addN 関数をトリガーし、パラメータを渡して 6 ずつ増加します。this.$store.commit('addN',6)
          }
      }

2.1 突然変異を誘発する2番目の方法:

(1) 必要に応じてvuexからmapMutations関数をインポートする

'vuex' から { mapMutations } をインポートします。

(2)先ほどインポートしたmapMutations関数を使用して、必要なmutations関数を現在のコンポーネントのmethodsメソッドにマップします。

メソッド: {
   ...mapMutations(['add','addN'])
}

実際には、クリック時に値を 1 減らすという Reduce.vue コンポーネントの機能要件を実現します。

ステート マシンは減分関数を追加します。

デフォルトの新しいVuex.Storeをエクスポートします({
  州: {
    カウント: 0
  },
  突然変異:
    // 自己増分 1 関数 add(state){
      状態.count++
    },
    // 1 ずつ減算する関数 sub(state){
      状態.count--
    }
  }
})

Reduce.vue コンポーネントは、ボタンをクリックすると 1 ずつ減ります。

<テンプレート>
    <div>
         <p>カウント値は: {{count}}</p>
           <button @click="btnSub">-1</button>
    </div>
</テンプレート>
<スクリプト>
// 'vuex' から {mapState,mapMutations} をインポートします
  エクスポートデフォルト{
      データ() {
          戻る {
              
          }
      },
      計算: {
         ...mapState(['count'])
      },
      メソッド: {
          // 変異内のサブ関数をマップします...mapMutations(['sub']),
          // 減算するには、サブ関数 btnSub(){ を呼び出します。
             この.sub()
          }
      }
  }
</スクリプト>

効果をご覧ください:

3.アクション:

ここまでで、4 番目のポイントのケースは完了し、自己インクリメントと自己デクリメントが実装されました。次に、ケースを改善してみましょう。自己インクリメントと自己デクリメントの1 秒前にボタンをクリックする必要があります。これを実現するにはどうすればよいでしょうか。ステート マシンのミューテーション内の関数に 1 秒のタイマーを追加できますか?ミューテーションは非同期操作をサポートしていないため、これは絶対に不可能です。 では、どうすればよいでしょうか? ディンディンディン、アクションがデビューします。

アクションには任意の非同期操作を含めることができるため、非同期タスクを処理するために使用されます。
アクションは、状態を直接変更するのではなく、突然変異を送信します。状態内のデータを直接変更することはできず、変更できるのはミューテーションのみであることに注意してください。つまり、非同期操作を通じてデータを変更する場合は、Mutation ではなく Action を使用する必要があります。ただし、Action で Mutation をトリガーして間接的にデータを変更する必要があります。

まず、ステート マシンでアクションを定義します。

デフォルトの新しいVuex.Storeをエクスポートします({
  州: {
    カウント: 0
  },
  突然変異:
    // 自己増分 1 関数 add(state){
      状態.count++
    },
    // 1 ずつ減算する関数 sub(state){
      状態.count--
    }
  },
  // アクションを定義します。その中の addAsync 関数は、1 秒後のアクションで追加関数を実装します。{
    addAsync(コンテキスト) {
      タイムアウトを設定します(()=>{
      //context.commit()context.commit('add') を通じてミューテーションをトリガーする必要があります
    },1000)
  }  
 }
})

アクション関数は、ストア インスタンスと同じメソッドとプロパティを持つコンテキスト オブジェクトを受け入れるため、context.commit を呼び出して変更をコミットできます。

3.1 アクションをトリガーする最初の方法:

コンポーネントの Add.vue コードを変更し、Action を導入して、非同期の自己インクリメント操作を実装します。

<テンプレート>
    <div>
        <p>カウント値は: {{this.$store.state.count}}</p>
           <button @click="btnAdd">+1</button>
    </div>
 
</テンプレート>
<スクリプト>
  エクスポートデフォルト{
      データ() {
          戻る {
              
          }
      },
      メソッド: {
          btnAdd() {
              // Action を導入する最初の方法は、addAsync 関数をトリガーすることです // ここでのディスパッチは、特にアクション関数を呼び出すために使用されます this.$store.dispatch('addAsync')
          }
      }
  }
</スクリプト>

効果を確認し、1 秒後に自己増加を実現します。

3.2 アクション非同期タスクをトリガーし、パラメータを渡します。

もちろん、コンポーネントがアクション内の関数を呼び出すときに、パラメータを渡すこともできます。

たとえば、クリック後 1 秒後に実行される自己増分関数がありますが、増分量は呼び出し時に渡されるパラメータによって異なります。

意味:

デフォルトの新しいVuex.Storeをエクスポートします({
  州: {
    カウント: 0
  },
  突然変異:
   // パラメータを渡します。最初のパラメータは state で、2 番目のパラメータは渡されたパラメータです // n を自身で増やす関数 addN(state,n){
      状態.count+= n
    }
  },
   アクション: {
    // パラメータ n があり、これは変異の addN 関数に渡されます。addNAsync(context,n) {
      タイムアウトを設定します(()=>{
         コンテキスト.commit('addN',n)
    },1000)
  }  
 }
})

対応するコンポーネントを呼び出すときは、パラメータを渡す必要があります。

  メソッド: {
          btnAdd2() {
              //ディスパッチ関数を呼び出す //アクションをトリガーするときにパラメータ(6)を渡す(6の増加を示す)
              this.$store.dispatch('addNAsync',6)
          }
      }

3.3 アクションをトリガーする2番目の方法:

(1) 必要に応じてvuexからmapActions関数をインポートする

'vuex' から { mapActions } をインポートします。

(2)先ほどインポートしたmapActions関数を使用して、必要なアクション関数を現在のコンポーネントのmethodsメソッドにマップします。

メソッド: {
   ...mapActions(['add','addN'])
}

実際には、クリックしてから 1 秒後に 1 ずつ減らすという Reduce.vue コンポーネントの機能要件を実現します。

アクション内の subAsync を、1 秒後に自己減少する関数として定義します。

デフォルトの新しいVuex.Storeをエクスポートします({
  州: {
    カウント: 0
  },
  突然変異:
    // 自己増分 1 関数 add(state){
      状態.count++
    },
    // 1 ずつ減算する関数 sub(state){
      状態.count--
    }
  },
   アクション: {
    addAsync(コンテキスト) {
      タイムアウトを設定します(()=>{
         コンテキスト.commit('追加')
    },1000)
  },
   サブ非同期(コンテキスト) {
      タイムアウトを設定します(()=>{
         コンテキスト.commit('sub')
    },1000)
  }    
 }
})

Reduce.vue コードを変更して関数を実装します。

<テンプレート>
    <div>
         <p>カウント値は: {{count}}</p>
           <button @click="btnSub">-1</button>
    </div>
</テンプレート>
<スクリプト>
// 'vuex' から {mapState,mapActions} をインポートします
  エクスポートデフォルト{
      データ() {
          戻る {
              
          }
      },
      計算: {
         ...mapState(['count'])
      },
      メソッド: {
          // Action 内の関数をマップします...mapActions(['subAsync']),
          // 減算するには、subAsync関数btnSub(){を呼び出します
             this.subAsync()
          }
      }
  }
</スクリプト>

効果をご覧ください:

4. ゲッター:

Getter は、ストア内のデータを処理して新しいデータを作成するために使用されます。また、状態内のデータは変更されないことに注意してください。
①Getterは、Vueの計算プロパティと同様に、Store内の既存のデータを処理して新しいデータを形成できます。
②Store内のデータが変更されると、Getter内のデータも変更されます。

たとえば、現在の count+1 を返す getter 関数があります。

デフォルトの新しいVuex.Storeをエクスポートします({
  州: {
    カウント: 0
  },
 ゲッター: {
    showNum(状態){
      戻り値 `現在のカウント値に 1 を加えた値は: ${state.count+1}`
    }
  }
})

4.1 ゲッターをトリガーする最初の方法:

this.$store.getters.name

App.vue コンポーネントに表示:

<テンプレート>
  <div id="アプリ">
       <私の追加></私の追加>
       <p>--------------------</p>
       <私の削減></私の削減>
       <p>--------------------</p>
       <h3>{{this.$store.getters.showNum}}</h3>
  </div>
</テンプレート>

効果:

4.2 ゲッターをトリガーする2番目の方法:

(1) 必要に応じてvuexからmapGetters関数をインポートする

'vuex' から { mapGetters } をインポートします。

(2)インポートしたmapGetters関数を使用して、現在のコンポーネントに必要なグローバルデータを現在のコンポーネントの計算されたプロパティにマップします。

計算: {
   ...mapGetters(['showNum'])
}

または、App.vue で使用します:

<テンプレート>
  <div id="アプリ">
       <私の追加></私の追加>
       <p>--------------------</p>
       <私の削減></私の削減>
       <p>--------------------</p>
       <h3>{{表示数}}</h3>
  </div>
</テンプレート>

<スクリプト>
// コンポーネントをインポートする import Add from './components/Add.vue'
'./components/Reduce.vue' から Reduce をインポートします。
// mapGetters 関数をインポートする import {mapGetters} from 'vuex'
エクスポートデフォルト{
  名前: 'アプリ'、
  データ() {
    戻る {
      
    }
  },
  コンポーネント:
    'my-add': 追加、
    'my-reduce': 削減
  },
  //ゲッターを導入する
  計算: {
    ...mapGetters(['showNum'])
  }

}
</スクリプト>

同じ効果をご覧ください:

6. 要約:

これで、Vuex ステート マシンの簡単な理解とサンプル アプリケーションに関するこの記事は終了です。Vuex ステート マシン アプリケーションに関するより関連性の高いコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Vuex管理ログインステータスの詳細な説明
  • Vueにおける状態管理Vuexの詳細な説明
  • vuex アイドル状態リセットソリューションについての簡単な説明
  • 状態管理に Vuex を使用する方法についての説明 (要約)
  • Vue の Flux フレームワークの Vuex 状態マネージャー

<<:  「@INC で ExtUtils/MakeMaker.pm が見つかりません」というエラーを解決する

>>:  CentOS 8 仮想マシンから Windows 10 ホスト フォルダーにアクセスする方法の簡単な分析

推薦する

Nginx ベースの HTTPS ウェブサイトを設定する手順

目次序文:暗号化アルゴリズム: 1. HTTPS の概要2. NginxはHTTPSウェブサイト設定...

axios でリクエストをキャンセルし、重複リクエストを防ぐ方法について簡単に説明します。

目次序文コア - キャンセルトークン実用的なアプリケーションとパッケージングいくつかの小さな詳細序文...

MySql ストアド プロシージャ パラメータの初歩的な使用法の詳細な説明

パラメータでのストアドプロシージャの使用IN パラメータは、プロシージャに情報を渡すためにのみ使用さ...

MySQL で単一のフィールド内の複数の値を分割および結合する方法

複数の値を組み合わせて表示これで、図1から図2に示す要件が揃いました。 どうやってやるんですか?次の...

いくつかの CSS3 タグの短縮形 (推奨)

border-radius: CSS3 丸い角構文: border-radius: 25px;楕円...

MySQL 8.0 をインストールした後、初めてログインするときにパスワードを変更する問題を解決する

MySQL 8.0.16で初回ログイン時のパスワードを変更する方法を紹介します。 MySQLデータベ...

node-media-serverを使用してシンプルなストリーミングメディアサーバーを構築する

node-media-server を使用するプロセスの一部を記録します。この記事の環境はWindo...

mysqlは内部コマンドエラーの解決策ではありません

「mysqlは内部コマンドではありません」というエラーは、mysqlのbinディレクトリパスが環境変...

JS配列インデックス検出におけるデータ型の問題の詳細な説明

WeChat アプレット プロジェクトを書いていたとき、その中に「都市選択」機能がありました。作者は...

Vue.jsはシンプルな折りたたみパネルを実装します

この記事では、Vue.jsの具体的なコードを共有して、シンプルな折りたたみパネルを実装する例を紹介し...

Elimination の JavaScript ソースコード

ゲームのソースコードのダウンロードアドレスを取得するためのJavaScript:クリックしてソースコ...

WeChat アプレットカスタムタブバーステップ記録

目次1. はじめに2. タブバーのスタイルをカスタマイズする3. カスタムタブバーと関連設定を導入す...

優れたHTML印刷コードがページめくりをサポート

ylbtech_html_print HTML 印刷コード、ページめくりをサポートコードをコピーコー...