1-Vuex是什么
專為Vue.js應(yīng)用程序開發(fā)的狀態(tài)管理模式济竹,采用集中式存儲管理應(yīng)用的所有組件的狀態(tài)瞻想,以相應(yīng)的規(guī)則保證狀態(tài)以一種可預(yù)測的方式發(fā)生變化蠕啄。
- Vuex 的狀態(tài)存儲是響應(yīng)式的丧没。當 Vue 組件從 store 中讀取狀態(tài)的時候们拙,若 store 中的狀態(tài)發(fā)生變化癞季,那么相應(yīng)的組件也會相應(yīng)地得到高效更新劫瞳。
- 你不能直接改變 store 中的狀態(tài)。改變 store 中的狀態(tài)的唯一途徑就是顯式地提交 (commit) mutation绷柒。這樣使得我們可以方便地跟蹤每一個狀態(tài)的變化志于,從而讓我們能夠?qū)崿F(xiàn)一些工具幫助我們更好地了解我們的應(yīng)用。
- 狀態(tài)
組件內(nèi)部狀態(tài) : 僅在一個組件內(nèi)使用的狀態(tài)(data字段)
應(yīng)用級別狀態(tài) : 多個組件共用的狀態(tài)
- 什么情況下使用Vuex
多個視圖依賴于同一狀態(tài)
來自不同視圖的行為需要變更同一狀態(tài)
- 使用Vuex(在src中新建store文件夾=》index.js)
- 安裝vuex模塊 : npm install vuex --save
- 作為插件使用: Vue.use(Vuex)
- 定義容器:new Vuex.Store()
- 注入根實例
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
//定義一個容器
let store = new Vuex.Store({
})
export default store
//main.js
import store from './store/'
new Vue({
el: '#app',
router,
store,//注入
components: { App },
template: '<App/>'
})
2-Vuex核心概念
- store : 類似容器废睦,包含應(yīng)用的大部分狀態(tài)
- 一個頁面只能有一個store
- 狀態(tài)存儲是響應(yīng)式的
- 不能直接改變store中的狀態(tài)伺绽,唯一途徑是顯示的提交mutations
- State:包含所有應(yīng)用級別的狀態(tài)的對象```
- Getters:在組件內(nèi)部獲取store中狀態(tài)的函數(shù)
- Mutations:唯一修改狀態(tài)的事件回調(diào)函數(shù)
- Actions:包含異步操作、提交mutation改變狀態(tài)
Action 類似于 mutation,不同在于:
- Action 提交的是 mutation奈应,而不是直接變更狀態(tài)澜掩。
- Action 可以包含任意異步操作。
mutations : {
addIncrement(state,payload){
state.count += payload.n
},
deIncrement(state,payload){
state.count -= payload.de
}
},
//異步操作杖挣、提交mutation改變狀態(tài),提交mutations
actions : {
addAction(context){
setTimeout(() => {
//改變狀態(tài)肩榕,提交mutations
context.commit('addIncrement',{
n : 5
})
}, 1000);
}
}
addHandel(){
//觸發(fā)一個action
this.$store.dispatch('addAction')
},
- Modules:將store分割成不同的模塊
- 我的總結(jié):數(shù)據(jù)統(tǒng)一放在state中,然后對于數(shù)據(jù)的處理惩妇,都統(tǒng)一在mutations中株汉,接著在組件內(nèi)部,綁定函數(shù)歌殃,觸發(fā)mutations中的函數(shù)乔妈。
//定義一個容器
let store = new Vuex.Store({
state:{
count : 100
},
//唯一修改狀態(tài)的事件回調(diào)函數(shù)
mutations : {
addIncrement(state){
state.count += 1
}
}
})
//組件內(nèi)
export default {
computed: {
num(){
//獲取狀態(tài)
return this.$store.state.count
}
},
methods: {
addHandel(){
//改變狀態(tài)氓皱,需要提交mutation : addIncrement
this.$store.commit('addIncrement')
}
}
}
3-實例分析Vuex流程
圖解 :先從拿數(shù)據(jù)開始分析路召,拿數(shù)據(jù)就牽涉到異步操作,我們把異步操作定義在action中去匀泊,在頁面中去觸發(fā)一個action优训,action里面有一個ajax請求的后端接口朵你,拿到數(shù)據(jù)后要渲染到頁面中各聘,只需要去改變狀態(tài)(state)即可,然后就會重新的渲染到頁面中去抡医,所以拿到數(shù)據(jù)之后需要提交一個mutation,因為vuex中有一個原則:想改變狀態(tài)躲因,必須要提交一個mutation,然后在調(diào)試工具中就會監(jiān)控一下提交的狀態(tài),所以我們想看上一個下一個狀態(tài)就會很方便忌傻,vuex是響應(yīng)的大脉,狀態(tài)一旦發(fā)生改變就會重新渲染組件。
基本使用
由于 store 中的狀態(tài)是響應(yīng)式的水孩,在組件中調(diào)用 store 中的狀態(tài)簡單到僅需要在計算屬性中返回即可镰矿。
computed: {
num(){
return this.$store.state.count
}
}
觸發(fā)變化也僅僅是在組件的 methods 中提交 mutation。
methods: {
addHandel(){
//改變狀態(tài)俘种,需要提交mutation : addIncrement
// this.$store.commit('addIncrement',{
// n:5
// })
//觸發(fā)一個action
this.$store.dispatch('addAction')
},
deHandel(){
//this.$store.commit('deIncrement')
this.$store.commit({
type : 'deIncrement',
de : 10
})
}
}
4-官網(wǎng)API摘要
1. 在 Vue 組件中獲得 Vuex 狀態(tài)
那么我們?nèi)绾卧?Vue 組件中展示狀態(tài)呢秤标?由于 Vuex 的狀態(tài)存儲是響應(yīng)式的,從 store 實例中讀取狀態(tài)最簡單的方法就是在計算屬性中返回某個狀態(tài)宙刘,每當 store.state.count 變化的時候, 都會重新求取計算屬性苍姜,并且觸發(fā)更新相關(guān)聯(lián)的 DOM。
// 創(chuàng)建一個 Counter 組件
const Counter = {
template: `<div>{{ count }}</div>`,
computed: {
count () {
return $store.state.count
}
}
}
2. Action
Action 類似于 mutation悬包,不同在于:
- Action 提交的是 mutation衙猪,而不是直接變更狀態(tài)。
- Action 可以包含任意異步操作。
讓我們來注冊一個簡單的 action:
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
})
Action 函數(shù)接受一個與 store 實例具有相同方法和屬性的 context 對象垫释,因此你可以調(diào)用 context.commit
提交一個 mutation丝格,或者通過 context.state
和 context.getters
來獲取 state 和 getters。當我們在之后介紹到 Modules時棵譬,你就知道 context 對象為什么不是 store 實例本身了铁追。
實踐中,我們會經(jīng)常用到 ES2015 的 參數(shù)解構(gòu) 來簡化代碼(特別是我們需要調(diào)用 commit
很多次的時候):
actions: {
increment ({ commit }) {
commit('increment')
}
}
3. Getter(類似計算屬性)
在vue中茫船,我們需要對變量進行進一步處理琅束,可以放在computed里,不建議放在模板中算谈,同樣涩禀,vuex中,state中的狀態(tài)如果需要進一步處理然眼,我們可以放入getters.
//vuex中
getters:{
filterCount(state){
return state.count >= 120 ? 120 : state.count
}
}
//組件中
computed: {
num2(){
return this.$store.getters.filterCount
}
}
4-輔助函數(shù)
- mapState
- mapGetters
- mapMutations
- mapActions
import {mapState,mapGetters,mapActions,mapMutations} from 'vuex'
以下是兩種寫法的對比
computed: {
num(){
return this.$store.state.count
},
num2(){
return this.$store.getters.filterCount
}
}
===================================
computed: {
...mapState(['count']) ,
...mapGetters({
num2:'filterCount'
})
}
addHandel(){
//改變狀態(tài)艾船,需要提交mutation : addIncrement
this.$store.commit('addIncrement',{
n:5
})
//觸發(fā)一個action
this.$store.dispatch('addAction')
},
deHandel(){
//this.$store.commit('deIncrement')
this.$store.commit({
type : 'deIncrement',
de : 10
})
}
============================
...mapActions({
deHandel :'addIncrement'
}),
...mapMutations({
addHandel:'deIncrement' //傳參在模板上即可
})