簡單理解 vuex

Vuex

狀態(tài)管理模式

集中式存儲管理應(yīng)用的所有組件的狀態(tài),以相應(yīng)的規(guī)則保證狀態(tài)以一種可以預(yù)測的方式發(fā)生變化。

容器 store

倉庫包含應(yīng)用中大部分狀態(tài)。

  1. 響應(yīng)式存儲,組件從 store 中讀取狀態(tài)時,若store 中的狀態(tài)發(fā)生變化,相應(yīng)組件也會相應(yīng)得到高效刷新;
  2. 不能直接改變 store 中的狀態(tài)。唯一途徑就是顯示提交 mutation -> 可以方便跟蹤每一個狀態(tài)的變化。

創(chuàng)建 store,僅需提供初始 state 對象和一些 mutation:

// 如果在模塊化構(gòu)建系統(tǒng)中,請確保在開頭調(diào)用了 Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  }
})

通過 store.state 來獲取狀態(tài)對象,通過 store.commit 方法觸發(fā)狀態(tài)變更:

store.commit('increment')

console.log(store.state.count) // -> 1

核心概念

  • State
    單一狀態(tài)樹。Store 倉庫中的 數(shù)據(jù) 狀態(tài) state。
// module1.js
const state = {
    count: 0,
    firstName: 'Kofe',
    lastName: 'Chen'
}
  • Getter
    Store 的 計算屬性,其返回值會根據(jù)它的依賴被緩存起來,只有依賴值發(fā)生改變才會重新計算。
// module1.js
const getters = {
    // 直接拋出其值
    count: state => state.count,  
    // 根據(jù)依賴
    fullName: state => state.firstName + ' ' + state.lastName  
}
  • Mutation
    更改 Vuex 的 store 中狀態(tài)的唯一 方法 是提交 mutation (類似事件),每個 mutation 都有一個字符串的事件類型(type)和一個回調(diào)函數(shù)(handler)。
    回調(diào)函數(shù)就是實際進行狀態(tài)更改的地方,且會接受 state 作為第一個參數(shù)。
// module1.js
const mutations = {
    increment(state) {
        state.count ++
    },
    modifyFirstName(state, newName) {
        state.firstName = newName
    },
    modifyLastName(state, newName) {
        state.lastName = newName
    }
}
  • Action
    類似 mutation,Action 提交的是 mutation,但不是直接變更狀態(tài)。Action 可以包含任意 異步操作。
// module1.js
const actions = {
    // 第一個參數(shù)是默認(rèn)的 { commit }
    changeFullName({ commit }, { firstName, lastName }) {
        // 假定 getName 方法返回 promise 對象
        // 并且提交 firstName 和 lastName ,如果修改成功則提交 mutation
        return getName({ firstName, lastName }).then(res => {
            commit('modifyFirstName', res.firstName)
            commit('modifyLastName', res.lastName)
        })
    },

    // 與上面的寫法相同,返回的仍然是 promise 對象
    async changeFullName({ commit }, { firstName, lastName }) {
        let res = await getName({ firstName, lastName })
        commit('modifyFirstName', res.firstName)
        commit('modifyLastName', res.lastName)
        // 這里返回調(diào)用的時候想得到 then 里面的數(shù)據(jù)
        return res
    }
}
  • Module
    Vuex 允許將 store 分割成 module,每個模塊擁有自己的 state、mutation、action、getter或甚至是嵌套子模塊。數(shù)據(jù)量大復(fù)雜可以拆分成不同模塊。
// index.js
import module1 from './modules/module1'
import module2 from './modules/module2'
// 如果在模塊化構(gòu)建系統(tǒng)中,請確保在開頭調(diào)用了 Vue.use(Vuex)
Vue.use(Vuex)
export default new Vuex.Store({
    modules: {
        module1,
        module2
    }
})

示例代碼文件格式

| -- store
    index.js
    | -- modules
        | -- module1.js
        | -- module2.js

module1.js 補充代碼

export default {
    state,
    getters,
    mutations,
    actions
}

使用

main.js 中引入 store:

// ...省略
import store from './store'

Vue.config.productionTip = false

new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>'
})

組件中使用:

<template>
    <div>{{fullName}}</div>
    <input v-model="firstName" placeholder="firstName">
    <input v-model="lastName" placeholder="lastName" >
    <a href="#" @click="onChange">改變?nèi)?lt;/a>
</template>

<script>
import { mapGetters, mapActions } from 'vuex'

export default {
    data() {
        return {
            firstName: '',
            lastName: ''
        }
    },

    computed: {
        ...mapGetters([
            'count',
            'fullName'
        ])
    },

    methods: {
        ...mapActions([
            'changeFullName'
        ]),

        onChange() {
            this.changeFullName({ firstName: this.firstName, lastName: this.lastName })
                .then(() => { 
                    // ...
                })
        }
    }
}
</script>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容