vuex 狀態管理 通俗理解
阿新 • • 發佈:2019-04-27
ted 我們 reac 響應式 load 發的 types.h fin 沒有
解釋:集中響應式數據管理,一處修改多處使用,主要應用於大中型項目。
安裝: 第一:index.js:(註冊store倉庫) npm install vuex -D // 下載vuex import Vue from ‘vue‘; import vuex from ‘vuex‘ // 全局引入 Vue.use(vuex) // 全局註冊 import actions from ‘./actions.js‘; import mutations from ‘./mutations.js‘; import getters from ‘./getters.js‘; import state from ‘./state.js‘; export default new Vuex.Store({ // 創建狀態管理(大寫) actions,mutations,getters,state }) 第二: main.js:(在根組件內掛載store) import store from ‘./store/index.js‘ // 根組件 new Vue({ el: ‘#app‘, render: h => h(App), router, // 路由掛載 store, // 狀態管理掛載 }) 原理: 用戶提交請求到Actions(如:this.$store.dispatch{type:‘showNav‘})===> Actions將類型和數據提交給mutations ===> mutations修改state的值 ===> 用戶通過getters拿到結果。 流程: 第1步:types.js: (使用 ES2015 風格的計算屬性命名功能來使用一個常量作為函數名) export const SHOW_NAV = ‘SHOW_NAV‘; export const HIDE_NAV = ‘HIDE_NAV‘; export const SHOW_FOOT = ‘SHOW_FOOT‘; export const HIDE_FOOT = ‘HIDE_FOOT‘; 第2步: Actions:(處理邏輯,將處理的結果給mutations) (通過commit返回給mutations,state是倉庫的容器,payload是@click=" addItem(items) "傳遞過來的數據) // 引入types文件,並遍歷 import {SHOW_NAV,HIDE_NAV,SHOW_FOOT,HIDE_FOOT} from ‘./types.js‘ // 第1種遍歷的方法 import * as types from ‘./types.js‘ // 第2種遍歷的方法,類似遍歷types文件所有的對象 export default { showNav:({commit,state} ,payload )=>{ commit(types.SHOW_NAV) }, hideNav:({commit,state},payload)=>{ commit(types.HIDE_NAV) // console.log(payload) // 拿到數據 }, showFoot:({commit,state})=>{ commit(types.SHOW_FOOT) }, hideFoot:({commit,state})=>{ commit(types.HIDE_FOOT) }, addItem:({commit,state},payload)=>{ // 加入購物車 let find = false; state.buycar.forEach((item,index)=>{ if(item.id == payload.id){ //有商品即數量累加 item.number++; find = true; } }); commit(types.ADD_ITEM,state.buycar) // 傳遞載荷(參數)給mutations } } 第3步: mutations: (做數據突變,用action傳遞過來的參數,直接修改state的鍵值) export default { [types.SHOW_NAV]:(state)=>{state.bNav = true}, // state為第3步的狀態對象 [types.HIDE_NAV]:(state)=>{state.bNav = false}, [types.SHOW_FOOT]:(state)=>{state.bFoot = true}, [types.HIDE_FOOT]:(state)=>{state.bFoot = false}, [types.SHOW_LOADING]:(state)=>{state.bLoading = true}, [types.HIDE_LOADING]:(state)=>{state.bLoading = false}, [types.ADD_ITEM]:(state,payload)=>{ state.buycar = payload; // payload就是action傳遞過來的參數 }, } 第3步: state: (接收mutations修改過後的狀態) export default { bNav:true, bFoot:true, bLoading:false, buycar:[], } 第4步: getters: (獲取state對象裏面的鍵值) export default { getNav:(state)=>{return state.bNav}, // 返回state狀態到vuex身上 getFoot:(state)=>{return state.bFoot}, getLoading:(state)=>{return state.bLoading}, getBuycar:(state)=>{return state.buycar}, } 第5步: 使用狀態管理: <!--使用狀態管理--> <template> <navbar v-show="getNav"></navbar> (5)結果的使用 <span @click="addItem(items)">訂閱</span> (4)通過點擊事件觸發actions方法(也可以通過鉤子函數觸發this.$store.dispatch( { type:‘show_nav‘,payload:‘2‘} ))或者this.$store.dispatch(‘show_nav,{payload:2}‘) </template> (1)解構狀態管理,從vuex身上結構mapGetters、mapActions,得到getters、actions身上全部的方法集合 import { mapActions, mapGetters } from ‘vuex‘; export default { methods: { (2) mapActions接管===》方法methods // 使用延展操作,解決自定義與mapgetters的並存 ...mapActions( [‘addItem‘, ‘changeItem‘, ‘emptyItem‘, ‘deleItem‘] ) }, computed: { (3) mapGetters接管===》計算屬性computed // 使用延展操作解決自定義與mapgetters的並存 ...mapGetters( [ ‘ getNav ‘ , ‘ getFoot ‘ ,‘getBuycar‘] ) }, } 觸發狀態管理的方法: 第一種:已經解構mapActions的情況下,通過點擊事件決定時機觸發actions裏的方法,案例如上:; 第二種:沒有解構mapActions時,通過鉤子函數決定時機,然後this.$store.dispatch( { type:‘show_nac‘,payload: } ) 狀態管理的應用:(導航欄的顯示隱藏) 在根組件下,監聽路由變化,來決定是否隱藏顯示 watch:{ // 狀態監聽 $route(to,from){ console.log(to,from) // to去向的路由 from來自哪個的路由 let path = to.path; // 拿到路由 ,如:/home if(/user|login/){ this.$store.dispatch({type:‘show_nav‘,payload:‘xxoo‘}) } } } 總結 Vuex 並不限制你的代碼結構。但是,它規定了一些需要遵守的規則: 應用層級的狀態應該集中到單個 store 對象中。 提交 mutation 是更改狀態的唯一方法,並且這個過程是同步的。 異步邏輯都應該封裝到 action 裏面。 只要你遵守以上規則,如何組織代碼隨你便。如果你的 store 文件太大,只需將 action、mutation 和 getter 分割到單獨的文件。 對於大型應用,我們會希望把 Vuex 相關代碼分割到模塊中。 組合 ActionAction 通常會異步的請求,那麽如何知道 action 什麽時候結束呢?更重要的是,我們如何才能組合多個 action,以處理更加復雜的異步流程? 首先,你需要明白 store.dispatch 可以處理被觸發的 action 的處理函數返回的 Promise,並且 store.dispatch 仍舊返回 Promise: (通俗的講,如果action內執行的是ajax請求,那返回的是promise,也就是可以通過then接收) actions: { actionA ({ commit }) { return new Promise((resolve, reject) => { setTimeout(() => { commit(‘someMutation‘) resolve() }, 1000) }) } } 現在你可以: store.dispatch(‘actionA‘).then(() => { // ... }) 在另外一個 action 中也可以: actions: { // ... actionB ({ dispatch, commit }) { return dispatch(‘actionA‘).then(() => { commit(‘someOtherMutation‘) }) } } 最後,如果我們利用 async / await,我們可以如下組合 action: // 假設 getData() 和 getOtherData() 都是ajax請求返回的是 Promise actions: { async actionA ({ commit }) { commit(‘gotData‘, await getData()) }, async actionB ({ dispatch, commit }) { await dispatch(‘actionA‘) // 等待 actionA 完成 commit(‘gotOtherData‘, await getOtherData()) } } 一個 store.dispatch 在不同模塊中可以觸發多個 action 函數。在這種情況下,只有當所有觸發函數完成後,返回的 Promise 才會執行。
vuex 狀態管理 通俗理解