iT邦幫忙

2021 iThome 鐵人賽

DAY 24
0
Modern Web

別再說我不會框架,網頁 Vue 起來!系列 第 24

中央狀態指揮中心- Vuex [續]

Vuex 結構分為 state getters mutations actions 四個部分

State

Vuex 使用 single state tree 單一狀態樹,一個包含應用程式狀態的物件。使用 computed 屬性來向 store 取得資料

ex:

// let's create a Counter component
const Counter = {
  template: `<div>{{ count }}</div>`,
  computed: {
    count () {
      return store.state.count
    }
  }
}

store.state.count 改變,會讓 computed 屬性重新被計算,並觸發相關的 DOM 更新。

這樣的模式會讓元件依賴於屬於全域的 store,當使用模組化系統來管理時,必須要在每一個有使用到 store state 的元件中去載入 store

於是,vuex 提供一個機制,注入(inject) store 到所有的子元件中

const app = new Vue({
  el: '#app',
  store, // 加入這個 store option,store 就會被注入到所有子元件中
  components: { Counter },
  template: `
    <div class="app">
      <counter></counter>
    </div>
  `
})
const Counter = {
  template: `<div>{{ count }}</div>`,
  computed: {
    count () {
      return this.$store.state.count  // 可以使用 this.$store
    }
  }
}

Getters

store 的 computed

例如: 取得狀態後還要去過濾資料

computed: {
  doneTodosCount () {
    return this.$store.state.todos.filter(todo => todo.done).length
  }
}

如果有多個元件都需要這個過濾後的值,除了把這樣 filter function 邏輯重複寫在要使用的元件外,還可以使用 getters ,將結果先算好,元件直接來拿值就好
ex:

const store = new Vuex.Store({
  state: {
    todos: [
      { id: 1, text: '...', done: true },
      { id: 2, text: '...', done: false }
    ]
  },
  getters: {
    doneTodos: state => {
      return state.todos.filter(todo => todo.done)
    }
  }
})

元件中取用 getters 結果

computed: {
  doneTodosCount () {
    return this.$store.getters.doneTodosCount 
  }
}

Mutations

變更 state 唯一的方法! 類似 event 的作用

每一個 mutation 都有一個 type 和 handler function

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

要執行 mutation 的 handler,就得呼叫 store.commit

store.commit('increment')

也可以傳入額外的物件 (payload) 給 store.commit

// ...
mutations: {
  increment (state, payload) {
    state.count += payload.amount
  }
}
store.commit('increment', {
  amount: 10
})

Actions

類似 mutations,但 actions 不能用來改

變 state,actions 是用來發出 commit 去呼叫 mutations

註冊一個 action
ex:

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

傳入 action 的 context 物件具有和 store 一樣的方法/屬性,所以可以使用 context.commit 來 commit mutation。也可以用 context.state context.getters 來取得 state 和 getters。

使用 store.dispatch 來觸發 actions
ex:

store.dispatch('increment')

未完待續..... Vuex


下篇預告

  • 來個番外實作

每日一句:
趁能走能動時,去做任何想做的事 /images/emoticon/emoticon10.gif


上一篇
中央狀態指揮中心- Vuex [序]
下一篇
[番外] 一步一步實現購物車功能 [序]
系列文
別再說我不會框架,網頁 Vue 起來!30

尚未有邦友留言

立即登入留言