Vuex:Vue 的全局数据管理模式
store:仓库
Vuex 就是一个 Vue 项目所有数据的仓库,包括数据本身和对这些数据的处理,对外提供接口,外部只能调用接口,不能直接对仓库中的数据进行操作。
全局状态管理(全局数据管理)的好处:

  1. 解耦:将所有数据相关的逻辑放入 store(也就是 MVC 中的 Model)
  2. 数据读写更方便:任何组件不管在哪里,都可以直接读写数据
  3. 控制力更强:组件对数据的读写只能使用 store 提供的 API 进行,但无法阻止队友直接对数据进行操作

    使用

    在文件 store/index.ts 中 ```typescript import Vue from ‘vue’ import Vuex from ‘vuex’

Vue.use(Vuex)

const store = new Vuex.Store({ state: { count: 0 }, mutations: { increment (state) { state.count++ } } })

  1. Vue 实例中注入 store
  2. ```typescript
  3. new Vue({
  4. store, // 等同于 store: store
  5. render: h => h(App)
  6. }).$mount('#app')

可以在 Vue 项目中任意地方使用 this.$store 访问

  1. this.$store.commit('increment')
  2. console.log(this.$store.state.count) // -> 1

State

就是 Vue 里的 data 选项
为了使得数据是响应试的,获取 store 中的数据时应使用计算属性

  1. computed: {
  2. count () {
  3. return this.$store.state.count;
  4. }
  5. }
  6. // TS 中使用get
  7. get count() {
  8. return this.$store.state.count;
  9. }

Getter

就是 Vue 里的 computed 选项

  1. const store = new Vuex.Store({
  2. state: {
  3. todos: [
  4. { id: 1, text: '...', done: true },
  5. { id: 2, text: '...', done: false }
  6. ]
  7. },
  8. getters: {
  9. doneTodos: state => {
  10. return state.todos.filter(todo => todo.done);
  11. },
  12. doneTodosCount: (state, getters) => {
  13. return getters.doneTodos.length;
  14. },
  15. getTodoById: (state) => (id) => {
  16. return state.todos.find(todo => todo.id === id);
  17. }
  18. }
  19. })

访问

  1. // 通过属性访问
  2. this.$store.getters.doneTodos;
  3. this.$store.getters.doneTodosCount;
  4. // 通过方法访问
  5. this.$store.getters.getTodoById(2);

Mutations

就是 Vue 里的 method 选项
没有返回值
只能接收两个参数,第二个可以为对象,可以传入多个值

  1. mutations: {
  2. increment (state, payload:{a:number, b:number}) {
  3. state.count += payload.a;
  4. }
  5. }

使用:

  1. this.$store.commit('increment', {
  2. amount: 10
  3. })

Actions

Action 类似于 mutation,不同在于:

  • Action 提交的是 mutation,而不是直接变更状态(就是回调)。
  • Action 可以包含任意异步操作,mutation 必须同步执行。
    1. const store = new Vuex.Store({
    2. state: {
    3. count: 0
    4. },
    5. mutations: {
    6. increment (state) {
    7. state.count++
    8. }
    9. },
    10. actions: {
    11. increment1 (context) {
    12. context.commit('increment');
    13. },
    14. // 可使用参数解构
    15. increment2 ({ commit }) {
    16. commit('increment');
    17. },
    18. // 可以在 action 内部执行异步操作
    19. incrementAsync ({ commit }) {
    20. setTimeout(() => {
    21. commit('increment');
    22. }, 1000)
    23. }
    24. }
    25. })
    使用:
    1. this.$store.dispatch('increment1');

    Modules

    当应用变得非常复杂时,store 对象就有可能变得相当臃肿
    Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割 ```typescript 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 的状态 ``` 默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的——这样使得多个模块能够对同一 mutation 或 action 作出响应。若要使用局部命名请看命名空间