vuex (仓库)

vuex(状态管理模式)

  • 核心: store(仓库)

    • state: 状态
    • getters: 对 state 的派生,可以理解为 store 的计算属性
    • mutaions: 修改 state 的唯一操作就是提交 mutaion 。
    • actions: 类似于 mutaion , 用来处理异步。
    • modules: 对仓库 分割成 模块
  • mapState(): sate的辅助函数是写在computed里面

  • mapGetters(): getters的辅助函数也是写在computed里面

  • mapMutations(): mutations的辅助函数是写在methods里面

  • mapActions(): actions的辅助函数也是写在methods里面

vuex的操作流程

  1. 先要有仓库,将我们项目中组件上需要共享的数据放置到我们 仓库中 state 的位置。
  2. 组件要使用 仓库 中 state 的数据,就从仓库里面拿出来用。
  3. 要修改仓库中 state 的数据
    3.1 . commit(提交) mutation
    3.2 . dispath(派发) action -> commit mutation
  4. 然后仓库中 state 数据发生变化,组件就会得到更新

只有mutation才能修改厂库中的数据

vuex 的使用

  1. 安装 vuex (也可以在创建项目的时候选择vuex)
npm install --save vuex 
  1. 项目中 src/store/index.js 文件中创建仓库的实例对象
// 1、引入 vue
import Vue from 'vue';
// 2、引入 vuex
import Vuex from 'vuex';
// 3、调用 Vuex
Vue.use(Vuex);
// 4.创建仓库的实例对象
const store = new Vuex.Store({
  // 仓库的选项对象
})
// 5、暴露 store
export default store;
  1. 要 main.js new Vue 的地方配置一个 store 的选项。选项的值就是 2 中 仓库实例对象

如何将仓库中的数据拿到组件中去使用

使用vuex,就会在vue原型上添加router,store 就是仓库的实例对象

  1. 直接使用 this.$store 的方式在组件 template 模板中使用 (不推荐)
  2. 组件中使用 计算属性 去拿 仓库的数据
     computed: {
       title () {
         return this.$store.state.title
       }
     }
    
  3. 借助 vuex 提供的辅助函数 mapState
    mapState([]) - 组件的computed 的 key 必须要跟仓库中 state 里面某个key 相同
computed: mapState(['title'])

mapState({ }) - 组件的computed 的 key 可以自定义。

computed: mapState({
    // 箭头函数可使代码更简练
    // page1Title: state => state.title

    // 传字符串参数 'count' 等同于 `state => state.count`
    // page1Title: 'title'

    // 为了能够使用 `this` 获取局部状态,必须使用常规函数
    page1Title (state) {
      return state.title
    }
 })
  1. 将 mapState 与 组件自身的 computed 结合 (推荐); ...运算符是展开运算符,可以把对象或者数组内的数据展开(就是去掉括号的意思)
computed: {
  ...mapState(['title']),
  firstName () {
    return this.name.split('')[0]
  }
},

如何修改仓库中的数据

  1. 先需要在仓库中定义我们的mutation
  2. 在组件中提交这个mutaion
    2.1. this.store.commit({
    type: mutaion的名字,
    其余的参数
    })
    2.3. mapMutations 辅助函数
  3. mutation必须是同步函数,任何在回调函数中进行的状态的改变都是不可追踪的。

如何写异步代码在仓库中 actions

  1. 每一个action里面都可以写异步代码,但是action并不能修改state中的数据,真正修改数据的还是 mutaction
  2. 在组件中如何派发这个action
    1- this.$store.dispatch('action的名字')
    2- mapActions 辅助函数

命名空间

如果希望你的模块具有更高的封装度和复用性,你可以通过添加 namespaced: true 的方式使其成为带命名空间的模块。当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名

操作方便

  1. mapState(['todos']) 根仓库上拿toods
  2. mapState('todo', ['todos']) // 相当于this.$store.state.todo.todos
  3. mapGetters('todo', ['todos']) // 相当于this.$store.getters.todo.todos

如果 不带命名空间会造成什么影响

  1. getters 是全局的, 如果在多个模块中有重名的 getter 会报错
  2. mutations, actions 有重名的话,会都被执行
在带命名空间的模块内访问全局内容

1、rootState 和 rootGetters 可以拿到根上所有的state和getters。
2、若需要在全局命名空间内分发 action 或提交 mutation,将 { root: true } 作为第三参数传给 dispatch 或 commit 即可。dispatch和commit只能子模块提交或派发给根,不能提交给兄弟模块。

actions: {
    fn2 ({ state, rootState, getters, rootGetters, commit, dispatch  }) {
      // console.log(state.name)   // 获取自身的name
      // console.log(rootState.b.name) // 获取b上的name
      // console.log(getters.firstName) // 获取自身的firstName
      // console.log(rootGetters['b/firstName']) // 获取b上的firstName
      // commit('fn3')  // 提交给自身mutations的fn3
      // commit('fn3', '123', { root: true }) // 提交给根上mutations的fn3
      dispatch('fn4', null, { root: true }) // 派发给根上mutations的fn3
    }
}

你可能感兴趣的:(vuex (仓库))