Zi 字媒體
2017-07-25T20:27:27+00:00
Getting Started with Vuex
Vue:2.6
Vuex:3.6.2
Vuex 是專門為 Vue.js 開發的 狀態管理模式(State Management Pattern and Library),它會集中式儲存並管理應用所有元件的狀態,並且以相對應的規則去操作狀態。再更簡單一點來說,就是建立一個單向的資料流,讓狀態變化是可預測的。
舉例來說,以電商的購物車功能為例,各個頁面都需要被共享到目前購物車的細節,這時候就可以透過 Vuex 來實作共享狀態。
另外, Vuex 跟 Event bus 差別是,Event bus 是類似全域事件的溝通,可以透過 props 和 emit 進行資料的傳遞,也就是說,這些事件是需要透過元件間的觸發才能運作;而 Vuex 比較接近是狀態的共享和管理,讓各個元件之間可以同步一些全域的狀態。
Lifecycle
(圖片來源:itread01)
在 Vuex 的 Lifecycle 裡有三個重要的機制需要知道。
State: 儲存狀態的物件,使用 單一狀態樹(Single State Tree) 的方式來存放。可以透過 Vuex Getters 取得狀態。
Mutations: Vuex 中改變狀態的唯一方法,通常都是用來實作狀態最原始的更動。
Actions:可以用來呼叫 Mutations 的方法,可以支援非同步呼叫(Asynchronous),通常用來實作商業邏輯。
Installation
透過 npm 進行安裝便可以直接使用。
npm install vuex --save
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
另外,因為 Vuex 依賴 Promise,所以 IE 瀏覽器 下是跑不動的,我們需要再安裝 es6-promise 套件並引用。
npm install es6-promise --save
import 'es6-promise/auto';
Basic Usage
Vuex 是用 Store 來當作儲存狀態的單位,因此一開始我們可以建立一個 store 的目錄開始實作。
src/store/index.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++;
}
},
actions: {
// 傳入一個 Store instance
increment (context) {
// 呼叫 mutations.increment
context.commit('increment');
}
},
});
export default store;
接著在主程式引用 store 。
src/app.js
import Vue from 'vue';
export default new Vue({
el: '#app',
router,
store
});
最後就可以在 Components 裡面取得相關資料啦。
Components
+1 by commit
+1 by dispatch
export default {
mounted() {
// 可以透過 this.$store.state 取得 state
console.log(this.$store.state.count);
},
methods: {
incrementByCommit() {
// 透過提交 Mutation 的方式更改狀態
this.$store.commit('increment');
console.log(this.$store.state.count);
},
incrementByDispatch() {
// 透過呼叫 Action 的方式更改狀態
this.$store.dispatch('increment');
console.log(this.$store.state.count);
}
}
}
Getters
Vuex 提供的 Getters 功能,類似元件中的 Computed 機制,每當狀態改變時才會進行計算。這樣一來各個元件在使用特定狀態時,就不需要每一個元件都需要寫一樣的 Computed,只要在 Store 裡實作 Getters 就好了。
比方說,我們可以透過 Getters 實作找出女性會員的資訊。
src/store/index.js
const store = new Vuex.Store({
state: {
members: [
{ id: 1, name: 'JohnsonLu', gender: 'male' },
{ id: 2, name: 'Tina', gender: 'female' },
{ id: 3, name: 'Yolanda', gender: 'female' },
]
},
getters: {
females: state => {
return state.members.filter(members => members.gender == 'female');
},
// 也可使用其他 getters 當成參數使用
memberCount: (state, getters)=> {
return getters.females.length;
}
}
});
Components
export default {
mounted() {
// [{ id: 2, name: 'Tina', gender: 'female' }, { id: 3, name: 'Yolanda', gender: 'female' }]
console.log(this.females);
},
computed: {
females () {
return this.$store.getters.females;
}
}
}
另外,可以透過 mapGetters 來取得 Getters,可以簡化程式碼。
Components
import { mapGetters } from 'vuex';
export default {
computed: {
...mapGetters([
'females',
'memberCount'
]),
}
}
Vuex 中,分別有 mapState、mapMutations、mapActions、mapGetters 可以使用。
Modules
在大型專案裡,Store 可能會變得很肥,因此 Vuex 也支援 Modules 功能,可以將 Store 拆成數個 Modules,讓程式比較好維護。
src/store/index.js
// Module A
const moduleA = {
state: {
count: 0
},
mutations: {},
actions: {},
getters: {}
}
// Module B
const moduleB = {
state: {
name: 'JohnsonLu'
},
mutations: {},
actions: {}
}
const store = new Vuex.Store({
// 引入 Modules
modules: {
a: moduleA,
b: moduleB
}
});
之後便可以透過 store.state.a.count 和 store.state.b.name 取得相對應的值。
正常狀況下,Store 裡的資訊都是屬於 global namespace 的,大家共用一樣的 Actions/Mutations。但如果想要有更高度的封裝性和結構的話,也可以開啟 Namespacing 功能,讓狀態們同時獲得 Namespace。
src/store/index.js
const store = new Vuex.Store({
// 引入 Modules
modules: {
// Person Module
person: {
// 開啟 Namespacing
namespaced: true,
state: { age: 18 }, // state.person.age
// 引入子 Modules
modules: {
company: {
state: { title: 'Engineer' } // state.person.company.title
}
},
}
}
});
關於 Modules 還有許多更細節的操作,可以再參考 Vuex Modules 的說明。
Categories: Vue
Tags: VueVuex
分類
Android
AngularJS
API Blueprint
Chrome
Database
MySQL
DataStructure
Docker
Editor
Vim
Firefox
Git
GitLab
Google API
Hadoop
HTTP
Language
Go
Java
JavaScript
jQuery
jQueryChart
Node.js
Vue
Vue-CLI
PHP
Laravel
Lumen
ZendFramework
Python
Mac
Network
Cisco
DLink
Juniper
Oauth
Server
Apache
Share
Unix
FreeBSD
Linux
WebDesign
Bootstrap
CSS
HTML
Wordpress
Search
搜尋關鍵字:
寫了
5860316篇文章,獲得
23313次喜歡