难受就摸头盖骨

vuex 状态管理 通俗理解

解释:集中响应式数据管理,一处修改多处使用,主要应用于大中型项目。

安装: 第一: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 相关代码分割到模块中。 组合 Action Action 通常会异步的请求,那么如何知道 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 才会执行。

  

posted @ 2019-04-26 21:26  longpanda_怪怪哉  阅读(379)  评论(0编辑  收藏  举报
下定决心了,要把写不出代码就摸后脑勺的习惯给改了! 如果可以~单身待解救~~