頁面應用需要Vuex管理全局/模塊的狀態,大型單頁面組件如果靠事件(events)/屬性(props)通訊傳值會把各個組件耦合在一起。因此需要Vuex管理屬性之間都狀態 ...
頁面應用需要Vuex管理全局/模塊的狀態,大型單頁面組件如果靠事件(events)/屬性(props)通訊傳值會把各個組件耦合在一起。因 此需要Vuex統一管理,當然如是小型單頁面應用,引用Vuex反而會增加複雜度。因此需要衡量引用Vuex增加的收益是否大於成本。
快速入門
1. 安裝vuex庫
cnpm install -S vuex
2. 創建Vuex.Store
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex); const store = new Vuex.Store({ //組件數據源,單一的state屬性 state: { clickCount: 0 }, //相當於屬性,封裝獲取state getters: { getClickCount: state => { return state.clickCount; } }, //封裝引起狀態變化的方法 mutations: { increment(state) { state.clickCount++; } }, //類似於 mutation,不同在於actions支持非同步,不是直接變更狀態,而是提交到mutation actions: { increment(context) { context.commit('increment') }, async incrementAsync({ commit }) { return new Promise((resolve, reject) => { setTimeout(() => { try { commit('increment'); resolve(new Date().getTime() + ' 成功執行'); } catch (e) { reject(e); } }, 1000) }); } } }); export default store;
3. Vue實例加入store
new Vue({ router: router, store: store, render: h => h(App), }).$mount('#app')
4. 組件獲取store值
<script> import { mapGetters } from "vuex"; export default { computed: mapGetters({ count: ["getClickCount"] }), }; </script>
5. 組件觸發更新
<script> export default { data() { return { times: 0 }; }, methods: { increment() { this.times++; //分發到action this.$store.dispatch("incrementAsync"); //提交到mutations this.$store.commit("increment"); }, }, }; </script>
解析
Vuex 是什麼?
Vuex 是一個專為 Vue.js 應用程式開發的狀態管理模式。它採用集中式存儲管理應用的所有組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。Vuex 也集成到 Vue 的官方調試工具devtools extension,提供了諸如零配置的 time-travel 調試、狀態快照導入導出等高級調試功能。
State - 數據源
Vuex 使用單一狀態樹——是的,用一個對象就包含了全部的應用層級狀態。
Vue通過store選項,調用Vue.use(Vuex)註入到每一個子組件中(類似路由)
組件獲取State
computed: { count () { return this.$store.state.count } }
或者使用輔助函數mapState
computed: mapState({ // 箭頭函數可使代碼更簡練 count: state => state.count })
Getter - 數據封裝讀取(類似屬性)
Getter 接受 state 作為其第一個參數
getters: { doneTodos: state => { return state.todos.filter(todo => todo.done) }, getTodoById: (state) => (id) => { return state.todos.find(todo => todo.id === id) } }
通過屬性訪問
store.getters.doneTodos
通過方法訪問
store.getters.getTodoById(2)
Getters 也提供了一個輔助函數方便訪問(mapGetters )
Mutation - 進行狀態更改的地方
定義Mutation
mutations: { increment (state, n) { state.count += n } }
組件觸發變更
store.commit('increment', 1)
Mutations也提供輔助函數(mapMutations)
import { mapMutations } from 'vuex' export default { // ... methods: { ...mapMutations([ 'increment', // 將 `this.increment()` 映射為 `this.$store.commit('increment')` // `mapMutations` 也支持載荷: 'incrementBy' // 將 `this.incrementBy(amount)` 映射為 `this.$store.commit('incrementBy', amount)` ]), ...mapMutations({ add: 'increment' // 將 `this.add()` 映射為 `this.$store.commit('increment')` }) } }
註意事項
- Mutation 必須是同步函數
- 最好提前在你的 store 中初始化好所有所需屬性。
- 需要在對象上添加新屬性時使用 Vue.set 或 替換舊對象
Action - 對Mutation封裝
Action 類似於 mutation,不同在於:
- Action 提交的是 mutation,而不是直接變更狀態。
- Action 可以包含任意非同步操作。
定義Action
actions: { increment ({ commit }) { commit('increment') } }
組件分發Action
store.dispatch('increment')
支持非同步方式分發
actions: { async incrementAsync({ commit }) { return new Promise((resolve, reject) => { setTimeout(() => { try { commit('increment'); resolve(new Date().getTime() + ' 成功執行'); } catch (e) { reject(e); } }, 1000) }); } }
組件調用非同步分發
this.$store.dispatch("incrementAsync").then( (data) => { console.log(data); }, (err) => { console.log(err); } );
參考文章
轉發請標明出處:https://www.cnblogs.com/WilsonPan/p/12773090.html