vuex学习笔记

什么是vuex

  • Vuex 是一个专为 Vue.js 应用程序开发的 状态管理模式 。它采用 集中式 存储管理应用的 所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

数据流

state中存储数据,给view映射到视图上显示,视图触发action的方法修改state中的数据。单项循环。

  • 包含几个部分
    • state:驱动应用的数据源;
    • view:以声明方式将 state 映射到视图;
    • actions:响应在 view 上的用户输入导致的状态变化。

vuex数据流(单向数据流)

运行原理

  • 运行原理

    • Vue组件通过 dispatch方法 来触发Vuex的 actions
    • Vuex的 actions 通过 commit 触发自己内部的 mutations 的方法
    • 通过 mutations 内部的方法修改 数据源state
    • state 变化后,Vue组件重新渲染(虚拟Dom、diff),做出变化
  • dispatch的使用(在其他组件中使用)

store.dispatch('GetUserInfo').then(res => { // 拉取user_info
  ···
}).catch(() => {
  ···
});
  • commit的使用
mutations:{
   // mutations方法只接受两个变量:第一个变量固定是state,第二个变量是 actions 传进来的额外变量,多的话用对象包起来
   UPDATE_PAGE_SEARCH: (state, {pageName, search}) => {
      ···
   }
}

actions: {
   updatePageSearch ({commit}, {pageName, search}) {
      //commit接受两个变量:第一个是 mutations 中的方法名,第二个是传 mutations 中方法的额外参数
      commit('UPDATE_PAGE_SEARCH', {pageName, search});
   }
}

核心api

  • 核心api
    • modules
    • state
    • mutations (一定是同步函数)
    • actions(可以是异步函数
    • getter
state
  • 只能通过 mutations 进行修改
  • 直接获取方式

通过这种方式获取的state如果存在非 computed 中,当 store 的 state 变化时,组件中的 state 不会发生变化。需要将其放在 computed 中才能实时响应更新。

username: this.$store.state.user.name,
  • mapState 辅助函数
// 实际运用
computed: {
  name() {
    return this.$store.state.a.name
  },
  ...mapState(['count']),
},
Mutation
  • 必须是同步函数:当我们改变数据的时候,需要知道对应的数据变化,如果是异步的函数,发送请求,我们不知道什么时候请求返回,这样我们无法跟踪 state 的改变
  • 可以直接通过 this.$store.commit('xxx') 提交 mutations ,也可以通过辅助函数 mapMutations 将组件中的 methods 映射到对应的 store.commit
methods: {
  ...mapMutations(['increment']),  // this.increment() 为 this.$store.commit('increment')
  ...mapMutations({
    add: 'increment'   // 映射 this.add() 为 this.$store.commit('increment')
  })
}
Action
  • Action通过store.dispatch方法触发
  • 在组件中使用 this.$store.dispatch('xxx') 分发action,或者使用 mapActions 辅助函数将组件的 methods 映射为 store.dispatch 调用
methods: {
  ...mapActions(['increment']) //映射this.increment() 为this.$store.dispatch('increment')
  ...mapActions({
    add: 'increment' // 映射 this.add() 为 this.$store.dispatch('increment')
  })
}
getter
  • 组件中调用通过 mapGetters 获得。并且需要放在 computed 中。当 state 修改后,需要通过组件的 computed 方法实现实时的监听并重新渲染 view
computed: {
  ...mapGetters(['name', 'email'])
}
modules
  • 可以通过 namespaced: true 的方式使其成为命名空间模块,当模块被注册后,它的所有 getters 和 actions 、mutations 会收到一个 局部的 getter,dispatch,commit。
const store = new Vuex.Store({    
  modules: {
    account: {
      namespaced: true,
      state: {....},
      getters: {
        isAdmin() {...}    // => getters['account/idAdmin']
      },
      actions: {
        login: {...}  // =>dispatch('account/login')
      },
      mutations: {
        login: {...}  // => commit('account/login')
      },
      // 模块嵌套模块
      modules: {
         // 继承父模块的命名空间
        myPage: {
          state: { ... },
          getters: {
            profile () { ... } // -> getters['account/profile']
          }
        },
        // 进一步嵌套命名空间
        posts: {
          namespaced: true,
          state: { ... },
          getters: {
            popular () { ... } // -> getters['account/posts/popular']
          }
        }
      }  
    }
  }
})
  • 若需要在 全局 命名空间中分发 actions 或者提交 mutations,需要将 {root: true} 作为第三个参数传入到 dispatch 和 commit 。如:dispatch('someOtherAction', null, { root: true })

vuex实例

  • module定义
const store = {
  modules: {
    app,
    errorLog,
    user
  },
  getters
}
  • getter定义
const getters = {
  avatar: state => state.user.avatar,
  name: state => state.user.name,
  email: state => state.user.email,
  phone: state => state.user.phone
}
export default getters
  • state、mutations、actions定义
const user = {
  state: {
    avatar: '', 
    name: '', 
    email: '', 
    phone: ''
  },

  mutations: {
    SET_USER_INFO: (state, userData) => {
      let {avatar, name, email, phone} = userData;
      state.avatar= avatar
      state.name= name
      state.email= email
      state.phone= phone
    },
    UPDATE_MAIL: (state, email) => {
      state.email = email;
    },
    UPDATE_PHONE: (state, phone) => {
      state.phone = phone;
    }
  },

  actions: {
    // 拉取用户信息
    GetUserInfo ({commit, state}) {
      return new Promise((resolve, reject) => {
        loginAPI.getUserInfo().then(response => {
          const data = response.data
          commit('SET_USER_INFO', {
            avatar: data.avatar,
            name: data.name,
            email: data.email,
            phone: data.phone
          })
          resolve(data)
        }).catch(error => {
          reject(error)
        })
      })
    },
    // 清空用户信息
    ClearUserInfo ({commit, state}) {
      commit('SET_USER_INFO', {
        avatar: '',
        name: '',
        email: '',
        phone: ''
      })
    },
  }
}

参考文章

posted @ 2020-05-22 02:32  _Sleeping  阅读(184)  评论(0)    收藏  举报