Vuexがデータ共有を実現する方法

8138 ワード

vueをフロントエンドフレームワークとして開発する場合、コンポーネント間の伝達値についてはよく知られていません.単純な親子コンポーネントの伝達値であれば、Vuexでステータス管理を行うことはできないと思いますが、中大規模な単一ページアプリケーションを構築する必要がある場合は、コンポーネント間のデータ相互作用が複雑で頻繁です.コンポーネントの外部でステータスを管理する方法を考える可能性が高いので、Vuexは自然な選択になります.
Vuexって何?
VuexはVue専用です.jsアプリケーション開発のステータス管理モード.集中型ストレージ管理アプリケーションのすべてのコンポーネントのステータスを採用し、対応するルールでステータスが予測可能な方法で変化することを保証します.これは公式の言い方です.
個人的な話でまとめると、Vuexはマルチコンポーネントのデータ共有を実現するためにstoreというデータ管理ライブラリを構築し、共有する必要があるデータを中に格納し、必要な場所で初期データとして取り出すこともできるし、コンポーネント内でdispatchやcommitメソッドを提出することで元のデータ状態を変更し、dataの共有を実現することもできる.
Vuexのコア
1、 State
Vuexのデータソースは、ここに保存する必要があるデータであり、this.$store.stateページで定義したデータを取得することができます.

import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

const state = {
 number: 0
}

export default new Vuex.Store({
 state,
});

現在の値は、this.$store.state.number ページから取得できます.
2、Getter
Vuexでは、storeで「getter」を定義できます(storeの計算プロパティと考えられます).計算プロパティと同様に、getterの戻り値は依存に基づいてキャッシュされ、依存値が変更された場合にのみ再計算されます.
Getterはstateを最初のパラメータとして受け入れます.

import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

const state = {
 number: 0
}

const getters = {
 getNumber(state) {
  return state.number + 1
 }
}
export default new Vuex.Store({
 state,
 getters,
});

ページではgettersの値を2つの方法で取得できます
1、属性によるアクセス
Getterはstoreに露出します.gettersオブジェクト、これらの値にプロパティとしてアクセスできます:this.$store.getters.getNumber
Getterは、2番目のパラメータとして他のgetterを受け入れることもできます.

const state = {
 number: 1
}

const getters = {
 getNumber(state) {
  return state.number + 1 // 2
 },
 getDoubNUmber(state, getters) {
  return state.number + getters.getNumber // 3
 }
}

注意:getterは、属性アクセス時にVueの応答システムの一部としてキャッシュされます.
2、方法によるアクセス
getterに関数を返すことで、getterへのパラメータ伝達を実現することもできます.storeの配列をクエリーするときに役立ちます.

const state = {
 number: 1,
 list: [1, 2, 3, 4, 5]
}

const getters = {
 getNumber(state) {
  return state.number + 1 // 2
 },
 getDoubNumber(state, getters) {
  return state.number + getters.getNumber // 3
 },
 filterNumber:(state)=>(num)=> {
  return state.list.find(item=> item%num === 0)
 } 
}
export default new Vuex.Store({
 state,
 getters,
});

注意、getterはメソッドでアクセスするたびに、結果this.$をキャッシュすることなく呼び出されます.store.getters.filterNumber(3)
3、Mutation
Vuexのstoreの状態を変更する唯一の方法はmutationをコミットすることです.Vuexのmutationはイベントによく似ています.各mutationには文字列のイベントタイプ(type)とコールバック関数(handler)があります.このコールバック関数は、実際にステータス変更を行う場所であり、stateを最初のパラメータとして受け入れ、追加のパラメータとして荷重(payload)をコミットします.多くの場合、荷重はオブジェクトであるべきです.これにより、複数のワードセグメントを含み、記録されたmutationをより読みやすくすることができます.
次のように書くことができます.

const mutations = {
 increment(state, n) {
 state.number += n
 }
}

しかし、mutation handlerを直接呼び出すことはできません.このオプションは、イベント登録のようなものです.「incrementタイプのmutationがトリガーされると、この関数が呼び出されます.」mutation handlerを起動するには、対応するtypeでstoreを呼び出す必要があります.commitメソッド:this.$store.commit('increment', 1)
次のように書くこともできます.

const mutations = {
 increment(state, payload) {
 state.number += payload.count
 }
}

次に、this.$store.commit('increment', {count: 1})  を使用して提出し、

//                type          :
this.$store.commit({
 type: 'increment',
 count: 1
})

特に、Vuexでは、mutationは同期タスクです.非同期操作を処理するために、Actionを見てみましょう.
4、 Action
Actionはmutationと似ていますが、次のような違いがあります.
1、Actionは、ステータスを直接変更するのではなく、mutationをコミットします.
2、Actionは任意の非同期動作を含むことができる.
ページでcommitをコミットすることでstoreのステータス値を変更する目的が達成されますが、公式では推奨されていません.actionをコミットし、actionでmutationをコミットしてステータス値を変更しましょう.

const mutations = {
 increment(state) {
 state.number += 1
 }
}
const actions = {
 addNumber(context){
  context.commit('increment')
 }
}

Action関数はstoreインスタンスと同じメソッドと属性を持つcontextオブジェクトを受け入れるのでcontextを呼び出すことができます.commitはmutationをコミットするかcontextを通過する.stateとcontext.gettersはstateとgettersを取得します

addNumber( {commit} ){
 commit('increment')
}

以上のような書き方は、

addNumber(context){
 context.commit('increment')
}

アクションはstoreを通ります.dispatchメソッドトリガ:this.$store.dispatch('addNumber')
mutationと同様にactionでパラメータを渡すこともできます

const mutations = {
 increment(state, number) {
 state.number += number
 }
}
const actions = {
 addNumber(context, number){
  context.commit('increment', number)
 }
   :
 addNumber( {commit}, number){
  commit('increment', number)
 }
}

トリガ方法:this.$store.dispatch('addNumber', 10)actionでの非同期処理については、次の例を参照してください.

const actions = {
 getData({commit}) {
  return new Promise((resolve, reject)=> {
   setTimeout(()=>{
   commit('getList')
   resolve()
   }, 1000)
  })
 }
}

そしてまた

this.$store.dispatch('getData').then(() => {
 // ...
})

完全なインスタンス:

import Vue from "vue";
import Vuex from "vuex";
import { resolve, reject } from "any-promise";
Vue.use(Vuex);
const state = {
 number: 1,
 list: [1, 2, 3, 4, 5]
}
const getters = {
 getNumber(state) {
  return state.number + 1 // 2
 },
 getDoubNumber(state, getters) {
  return state.number + getters.getNumber // 3
 },
 filterNumber:(state)=>(num)=> {
  return state.list.find(item=> item%num === 0)
 } 
}
const mutations = {
 increment(state, n) {
 state.number += n
 },
 getList(state) {
 state.list = state.list.forEach((item)=> item*2)
 }
}
const actions = {
 addNumber( {commit} , n){
  commit('increment', n)
 },
 getData({commit}) {
  return new Promise((resolve, reject)=> {
   setTimeout(()=>{
   commit('getList')
   resolve()
   }, 1000)
  })
 }
}
export default new Vuex.Store({
 state,
 getters,
 mutations,
 actions
});

VuexにおけるmapState、mapGetters、mapMutations、mapActionsの使い方について
最初に導入するには、次の手順に従います.

import { mapState, mapGetters, mapMutations, mapActions } from 'vuex';

これはVuexに内蔵された補助関数で、storeのデータと方法を取得するのに便利です.

computed: {
 ...mapState([
 'number'
 ])
}
//            getter    computed    
computed: {
 ...mapGetters([
  'getNumber',
  'getDoubNumber',
  // ...
 ])
} 
methods: {
 ...mapMutations([
  'increment', //   `this.increment()`     `this.$store.commit('increment')`
 ...mapMutations({
  add: 'increment' //   `this.add()`     `this.$store.commit('increment')`
 })
} 
methods: {
 ...mapActions([
  'addNumber', //   `this.addNumber()`     `this.$store.dispatch('addNumber')`
  // `mapActions`      :
  'addNumber' //   `this.addNumber(amount)`     `this.$store.dispatch('addNumber', amount)`
 ]),
 ...mapActions({
  requestData: 'getData' //   `this.requestData()`     `this.$store.dispatch('getData')`
 })
 }

以上はVuexの状态管理を実现する1つの全体の过程に対する理解で、公式のドキュメントを参考にして、それから自分で书いて、比较的にその中の道理を理解しやすくて、后でReactの中でReduxの状态管理を実现する1つの过程について书きたい时間があって、その中で、実は彼らの思想の差は多くなくて、ただreduxの実现の过程はもっと多くて、期待してください!