关于vue.js:vuex-store-进阶

背景:vuex store的进阶版 实用于大型简单的单页利用
用处:数据管理

state 相似于 data
存储全局状态值,当扭转值会触发dom更新, 应用时挂载在子组件的computed计算属性上(这样的目标是为了实时更新)

mapState

getters
getters 能够返回一个值(属性),也可返回一个办法函数
拜访办法时 每次进行调用 不会缓存后果
拜访属性时 作为vue响应式零碎的一部分缓存起来
mapGetters –辅助函数
将store中的getter映射到部分计算属性,即 定义getter后 在总的vuex去注入这个getter 从而在全局进行应用

mutations
用于更改store中的状态值 蕴含一个事件类型和一个回调函数 不反对异步

mutations: {
  increment (state, n) {
    state.count += n
  }
}
store.commit('increment', 10)

// 以对象模式传参
mutations: {
  increment (state, payload) {
    state.count += payload.amount
  }
}
// amount相当于传入参数
store.commit('increment', {
  amount: 10
})

actions
相似于mutations 反对异步 通过 store.dispatch 触发

actions: {
  incrementAsync ({ commit }) {
    setTimeout(() => {
      commit('increment')
    }, 1000)
  }
}
// 两种模式散发调用
store.dispatch('incrementAsync', {
  amount: 10
})

store.dispatch({
  type: 'incrementAsync',
  amount: 10
})

mapActions
在组件中应用 this.$store.dispatch(‘xxx’) 散发 action,或者应用 mapActions 辅助函数将组件的 methods 映射为 store.dispatch 调用(须要先在根节点注入 store)

import { mapActions } from 'vuex'

export default {
  // ...
  methods: {
    ...mapActions([
      'increment', // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')`

      // `mapActions` 也反对载荷:
      'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.dispatch('incrementBy', amount)`
    ]),
    ...mapActions({
      add: 'increment' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
    })
  }
}

actions 异步🌰

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
actions: {
  async actionA ({ commit }) {
    commit('gotData', await getData())
  },
  async actionB ({ dispatch, commit }) {
    await dispatch('actionA') // 期待 actionA 实现
    commit('gotOtherData', await getOtherData())
  }
} // 假如 getData() 和 getOtherData() 返回的是 Promise

modules
作用:将store宰割成模块,每个模块领有本人的 state、mutation、action、getter

const moduleA = {
  state: () => ({ ... }),
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}

const moduleB = {
  state: () => ({ ... }),
  mutations: { ... },
  actions: { ... }
}

const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})

store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态
const moduleA = {
  state: () => ({
    count: 0
  }),
  mutations: {
    increment (state) {
      // 这里的 `state` 对象是模块的部分状态
      state.count++
    }
  },

  getters: {
    doubleCount (state) {
      return state.count * 2
    }
  }
}
const moduleA = {
  state: () => ({
    count: 0
  }),
  mutations: {
    increment (state) {
      // 这里的 `state` 对象是模块的部分状态
      state.count++
    }
  },

  getters: {
    doubleCount (state) {
      return state.count * 2
    }
  },

  actions: {
    incrementIfOddOnRootSum ({ state, commit, rootState }) {
      if ((state.count + rootState.count) % 2 === 1) {
        commit('increment')
      }
    }
  },

  getters: {
    sumWithRootCount (state, getters, rootState) {
      return state.count + rootState.count
    }
  },
}

还有模块命名 模块继承 和更多简单用法 详见:
https://vuex.vuejs.org/zh/gui…

总结
1.利用层级的状态应该集中到单个 store 对象中。
2.提交 mutation 是更改状态的惟一办法,并且这个过程是同步的。
3.异步逻辑都应该封装到 action 外面。
如果 store 文件太大,需将 action、mutation 和 getter 宰割到独自的文件

我的项目架构

├── index.html
├── main.js
├── api
│   └── ... # 抽取出API申请
├── components
│   ├── App.vue
│   └── ...
└── store
    ├── index.js          # 咱们组装模块并导出 store 的中央
    ├── actions.js        # 根级别的 action
    ├── mutations.js      # 根级别的 mutation
    └── modules
        ├── cart.js       # 购物车模块
        └── products.js   # 产品模块

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理