Vuex是甚麼?甚麼時候需要它?
其實我曾經教過大家父子元件的溝通可以透過props、emit,那如果不是父子關係的元件怎麼溝通?還不是太複雜的專案,其實是可以透過Event Bus 發起全域的事件送出事件或資料,元件可以用on來監聽Event Bus發出的事件或資料。
那當然如果專案結構比較複雜,就可以適用Vuex來做整個網站的全域狀態管理,將狀態集中在Store管理。
整個Vuex我們稱它為Store,工作流程如右圖示:
整體工作流程是:在Component需要更動狀態時使用dispath來觸發Action發出Commit去呼叫定義好的Mutations修改State,當狀態被改變時,會觸發Render渲染元件。我們可以透過Vue.js devtools來觀察其變化
顧名思義,它的作用在於定義應用程式的行為,主要用在非同步的行為,如: call API。也就是說只能透過Action處理非同步,不能使用Mutation來處理。
Action 透過 Commit 向 Mutations告知使用哪個 mutation
接收到Action發起的訊息,或單使用Commit呼叫mutation,執行其邏輯運算,來改變state狀態,也就是說只能由Mutation來修改狀態。
在強調一次:Action、Mutations實質相似,都可以處理業務邏輯,但在主要工作上有區分Action就是處理非同步,Mutations 就是負責改變狀態。
Vuex是管理狀態的機制,當然State及是負責記錄應用程式所有的狀態。
當我們的狀態全部集中到同一個State就會變得臃腫複雜,所以Vuex提供了分割模組,讓每個模組有屬於自己的state、mutation、action、getter。
// define moduleA、moduleB here
...
// define Vuex
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> moduleA State
store.state.b // -> moduleB State
一言以蔽之,你可以把它認為是 store 的計算屬性。
就跟計算屬性一樣,getter 的返回值會根據它的依賴被cache起來,且只有當它的依賴值發生了改變才會被重新計算。
Getter 接受 state 作為其第一個參數,也可以接受其他getter 作為第二個參數。
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)
},
doneTodosCount: (state, getters) => {
return getters.doneTodos.length
}
}
})
1.定義Vuexstate
要先定義該狀態isLoading
,mutations在接受到commit才能發出變異mutate觸使狀態state改變。很重要在說一次,state
要先定義狀態。
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
// 定義狀態
isLoading: false,
},
mutations: {
// 這邊寫好每次變異都把布林值轉換
changeLoadingState (state) {
state.isLoading = !state.isLoading
}
},
actions: {
},
modules: {
}
})
2.import到根實例
import Vue from 'vue'
import App from './App.vue'
import store from './store'
new Vue({
store,
render: h => h(App)
}).$mount('#app')
3.在component使用
<template>
<div>
<span v-if="isLoading"><i class="pi pi-refresh pi-spin"></i></span>
<button @click="onChangeState()">Reverse</button>
</div>
</template>
<script>
export default {
name: "app",
computed: {
isloading() {
// 透過$store取得狀態裡的isLoading
return this.$store.state.isLoading;
}
},
methods: {
onChangeState() {
// 透過$store commit 已經寫好的mutation
this.$store.commit("changeLoadingState");
}
}
};
</script>
有任何問題歡迎下方留言,如果喜歡我的文章別忘了按讚、訂閱追蹤加分享唷!!
---我是分隔線-----------------------------------------------------------
PollyPO技術-前端設計轉前端工程師-JS踩坑雜記 30 天
喬依司-實作經典 JavaScript 30
五百億-Vue CLI + Firebase 雲端資料庫 30天打造簡易部落格及後臺管理
eien_zheng-前端小嘍嘍的Golang學習旅程_The journey of learning Golang