10分鐘學會vuex

Vuex全局的狀態統一管理,解決組件之間狀態共享和數據通訊的問題。vue

第一步

store.jsvuex

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex) // 使用插件
// 導出store實例
export default new Vuex.Store({
  state: {

  },
  mutations: {

  },
  actions: {

  }
})
複製代碼

第二步

main.js緩存

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

Vue.config.productionTip = false

new Vue({
  router,
  store, // 增長store屬性,值是導出store的實例
  render: h => h(App)
}).$mount('#app')

複製代碼

經過上面兩個步驟,每一個組件中都有了$store屬性,就是咱們建立的容器。裏面有commit,dispatch,state,getters,actions,mutations,在每一個組件中能夠經過this.$store打印出來看看。app

開始使用

定義狀態異步

export default new Vuex.Store({
  state: {
	count: 1 // state中定義響應式的數據
  }
})
複製代碼

使用狀態:在store的state中定義的狀態count,在組件中能夠使用this.$store.state.count獲取。async


定義mutations函數

在store的mutations中添加對應的方法this

export default new Vuex.Store({
  state: {
	count: 1 // state中定義響應式的數據
  },
  mutations: {
	addTen (state, num) {
		state.count = state.count + num
	}
  },
  actions: {

  }
})
複製代碼

提交mutations 組件中經過commit提交mutations去修改state中的狀態spa

this.$store.commit('addTen', 10)
複製代碼

定義actions 在store的actions中添加對應的方法插件

export default new Vuex.Store({
  state: {
	count: 1
  },
  mutations: {
	addTen (state, num) {
		// 第一個參數是狀態,第二個是傳入的參數
		state.count = state.count + num
	}
  },
  actions: {
	minusTen ({commit}, num) {
		// 第一個參數是store實例,第二個是傳入的參數
		setTimeout(() => {
			commit('addTen', num)
		}, 1000)
	}
  }
})
複製代碼

派發動做 組件中能夠使用dispatch派發一個動做,來觸發actions中的方法,actions能夠異步的提交mutations去修改state中的狀態

this.$store.dispatch('minusTen', 10)
複製代碼

actions主要是複用,封裝代碼,處理異步,請求接口等等,真正修改狀態放到了mutations中處理


定義getters 在store的getters中添加對應的方法

export default new Vuex.Store({
  state: {
	count: 1,
	person: {
		name: '張三'
	}
  },
  getters: {
	getName (state) {
		// getters是同步的
		return state.person.name
	}
  }
})
複製代碼

使用getters

this.$store.getters.getName
複製代碼

getters定義的方法至關於計算屬性,至關於定義在computed同樣,有緩存,依賴改變會從新計算。

組件代碼演示

<template>
  <div class="hello">
    <h1>{{ this.$store.state.count }}</h1>
    <h1>{{ this.$store.getters.getName }}</h1>
    <button @click="syncAdd">同步加10</button>
    <button @click="asyncAdd">異步加10</button>
  </div>
</template>

<script>
export default {
  methods: {
    syncAdd () {
      this.$store.commit('addTen', 10)
    },
    asyncAdd () {
      this.$store.dispatch('minusTen', 10)
    }
  }
}
</script>
複製代碼

簡寫

上面的寫法都是在this.$store中獲取屬性或方法進行操做。

this.$store.state.count
this.$store.getters.getName
this.$store.commit('addTen', 10)
this.$store.dispatch('minusTen', 10)
複製代碼

可是這些操做寫起來比較繁瑣,每次都要寫this.$store,爲了簡寫,因此vuex提供了一些映射的方法,直接導入到組件中就能夠使用了。

<template>
  <div class="hello">
    <h1>{{ count }}</h1>
    <h1>{{ getName }}</h1>
    <button @click="syncAdd">同步加10</button>
    <button @click="asyncAdd">異步加10</button>
  </div>
</template>

<script>
import {mapActions, mapState, mapMutations, mapGetters} from 'vuex'
export default {
  computed: {
    ...mapState(['count']),
    ...mapGetters(['getName'])
  },
  methods: {
    syncAdd () {
      this.addTen(10)
    },
    asyncAdd () {
      this.minusTen(10)
    },
    ...mapActions(['minusTen']),
    ...mapMutations(['addTen'])
  }
}
</script>
複製代碼

有一點須要說明的是,使用擴展運算符,表示這些方法返回的都是對象,mapStatemapGetters須要定義在計算屬性中,由於他們定義的數據是響應式的。而mapActionsmapMutations須要定義在methods中。

拆分模塊

狀態是能夠分層的,當一個項目維護的狀態太多,能夠拆分紅單獨的模塊,在定義store中有個modules屬性,裏面能夠定義單獨的模塊。

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  modules: {
    'page1': {
      namespaced: true,
      state: {
        count: 1,
        person: {
          name: '張三'
        }
      },
      mutations: {
        addTen (state, num) {
          state.count = state.count + num
        }
      },
      actions: {
        minusTen ({commit}) {
          setTimeout(() => {
            commit('addTen', 10)
          }, 1000)
        }
      },
      getters: {
        getName (state) {
          return state.person.name
        }
      }
    }
  }
})
複製代碼

在組件中這樣用

<template>
  <div class="hello">
    <h1>{{ count }}</h1>
    <h1>{{ getName }}</h1>
    <button @click="syncAdd">同步加10</button>
    <button @click="asyncAdd">異步加10</button>
  </div>
</template>

<script>
import {mapActions, mapState, mapMutations, mapGetters} from 'vuex'
export default {
  computed: {
    ...mapState('page1', ['count']),
    ...mapGetters('page1', ['getName'])
  },
  methods: {
    syncAdd () {
      this.addTen(10)
    },
    asyncAdd () {
      this.minusTen(10)
    },
    ...mapActions('page1', ['minusTen']),
    ...mapMutations('page1', ['addTen'])
  }
}
</script>
複製代碼

每一個方法都傳了兩個參數,第一個參數指定命名空間,第二個參數是對應的屬性,爲了進一步簡寫,能夠經過幫助函數指定命名空間,指定當前組件在使用的模塊。

<template>
  <div class="hello">
    <h1>{{ count }}</h1>
    <h1>{{ getName }}</h1>
    <button @click="syncAdd">同步加10</button>
    <button @click="asyncAdd">異步加10</button>
  </div>
</template>

<script>
import { createNamespacedHelpers } from 'vuex'
// 建立幫助函數指定命令空間
let { mapActions, mapState, mapMutations, mapGetters } = createNamespacedHelpers('page1')

export default {
  computed: {
    ...mapState(['count']),
    ...mapGetters(['getName'])
  },
  methods: {
    syncAdd () {
      this.addTen(10)
    },
    asyncAdd () {
      this.minusTen(10)
    },
    ...mapActions(['minusTen']),
    ...mapMutations(['addTen'])
  }
}
</script>
複製代碼

不使用簡寫

this.$store.getters['page1/getName']
this.$store.state.page1.count
this.$store.commit('page1/addTen', 10)
this.$store.dispatch('page1/minusTen', 10)
複製代碼
相關文章
相關標籤/搜索