Vuex的基本用法及API的相关图解

390 阅读4分钟

1.0_ vuex的基本介绍

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式, 采用集中式存储管理应用的所有组件的状态,解决多组件数据通信。

要点:

  1. vue官方搭配,专属使用 (类似于:vue-router),有专门的调试工具
  2. 集中式管理数据状态方案 (操作更简洁)data() { return { 数据, 状态 }}
  3. 数据变化是可预测的 (响应式)

1.1_vuex基础-state定义公共数据

vuex用它来保存公共数据

state是放置所有公共状态的属性,如果你有一个公共状态数据 , 你只需要定义在 state对象中

定义state

// 初始化vuex对象
const store = new Vuex.Store({
  state() {
    // 管理数据
   return {
     count: 0
   }
})

如何在组件中获取count?

原始形式- 插值表达式,省略this

App.vue

展示页面中可以使用 this.$store 获取到vuex中的store对象实例,可通过state属性获取count, 如下

<div> state的数据:{{ $store.state.count }}</div>

在组件中 - this.$store.state.属性名访问

// 把state中数据,定义在组件内的计算属性中
  computed: {
    count () {
      return this.$store.state.count
    }
  }
 <div> state的数据:{{ count }}</div>

可通过vue-devtool调试工具查看vuex中查看数据状态

总结 : state的作用是:保存公共数据(多组件中共用的数据); state是响应式的: 如果修改了数据,相应的在视图上的值也会变化。

1.2_vuex基础-mutations修改公共数据

state数据的修改只能通过mutations,并且mutations必须是同步更新,目的是形成**数据快照**

数据快照:一次mutation的执行,立刻得到一种视图状态,因为是立刻,所以必须是同步

定义mutations

const store  = new Vuex.Store({
  state: {
    count: 0
  },
  // 定义mutations
  mutations: {
      // 每一项都是一个函数,可以声明两个形参
    mutation名1function(state [, 载荷]) {
  
    },
    mutation名2function(state [, 载荷]) {
  
    }
  }
})

格式说明

mutations是一个对象,对象中存放修改state的方法

mutations: {
    // 方法里参数 第一个参数是当前store的state属性
    // payload 载荷 运输参数 调用mutaiions的时候 可以传递参数 传递载荷
    addCount (state,payload) {
      state.count += payload
    }
  },

如何在组件中调用mutations

示例:

<template>
  <button @click="addCount">+1</button>
</template><script>
export default {
    methods: {
    //   调用方法
      addCount () {
         // 调用store中的mutations 提交给muations
        // commit('muations名称', 2)
        this.$store.commit('addCount', 10)  // 直接调用mutations
    }
  }
}
</script>

通过插件查看是否成功, state与mutations关系图解

image.png

state是存放数据的,mutations是同步更新数据,actions则负责进行异步操作

1.3_vuex基础-actions发异步请求

action 内部可以发异步请求操作

action是间接修改state的:是通过调用 mutation来修改state

定义actions

 actions: {
  //  获取异步的数据 context表示当前的store的实例 可以通过 context.state 
  //  获取状态 也可以通过context.commit 来提交mutations, 也可以 context.dispatch调用其他的action
    async getBooks(context){
      const res = await axios.get('http://www.xxx/api/getbooks')
      let data = res.data.data;
      context.commit('initBooks',data)
    }
 } 

原始调用

 addAsyncCount () {
     this.$store.dispatch('getBooks')
 }

传参调用

 addAsyncCount () {
     this.$store.dispatch('getBooks', 123)
 }

1.4_vuex基础-getters的派生状态

除了state之外,有时我们还需要从state中派生出一些状态,这些状态是依赖state的,此时会用到getters

在state中的数据的基础上,进一步对数据进行加工得到新数据。(与组件中computed一样)

语法:

new Vuex.store({
  // 省略其他...
  getters: {
    // state 就是上边定义的公共数据state
    getter的名字1: function(state) {
      return 要返回的值
    }
  }
})

例如,state中定义了list,为1-10的数组,

state: {
    list: [1,2,3,4,5,6,7,8,9,10]
}

组件中,需要显示所有大于5的数据,正常的方式,是需要list在组件中进行再一步的处理,但是getters可以帮助我们实现它

定义getters

  getters: {
    // getters函数的第一个参数是 state
    // 必须要有返回值
     filterList:  state =>  state.list.filter(item => item > 5)
  }

使用getters

原始方式

<div>{{ $store.getters.filterList }}</div>

1.5_vuex基础-modules来拆分复杂业务

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。

如果把所有的状态都放在state中,当项目变得越来越大的时候,Vuex会变得越来越难以维护

由此,又有了Vuex的模块化

export default new Vuex.Store({
  // state: 用来保存所有的公共数据
  state: {},
  getters: {},
  mutations: {},
  actions: {},
  modules: {
    模块名1: {
            // namespaced为true,则在使用mutations时,就必须要加上模块名
        namespaced: true, 
          state: {},
            getters: {},
            mutations: {},
            actions: {},
            modules: {}
    },
    模块名2: {
        // namespaced不写,默认为false,则在使用mutations时,不需要加模块名
          state: {},
            getters: {},
            mutations: {},
            actions: {},
         modules: {}
    }  
  }
})

当添加namespaced: true,时,访问模块中的数据,要加上模块名

获取数据项:  {{$store.state.模块名.数据项名}}
获取getters: {{$store.getters['模块名/getters名']}}

访问模块中的mutations/actions:

  • 如果namespaced为true,则需要额外去补充模块名
  • 如果namespaced为false,则不需要额外补充模块名
$store.commit('mutations名')        // namespaced为false
$store.commit('模块名/mutations名')  // namespaced为true$store.dispatch('actions名')        // namespaced为false
$store.dispatch('模块名/actions名')  // namespaced为true

1.6_vuex中的map函数的使用

1.在使用map函数的组件中,按需导入map函数

import { mapState,mapActions,mapGetters,mapGetters } from 'vuex'

2.在组件中展开使用

image.png

mapState与mapGetters在计算属性中展开当计算属性使用

mapMutations与mapActions在methods中展开当函数使用

3.在组件中使用

  • 全局的使用
// 1.state
computed: { 
  // 省略其他计算属性
  ...mapState(['xxx']), 
}
// 2.getters
computed: { 
  ...mapGetters(['xxx']), 
}
// 3.mutations
methods: { 
  ...mapMutations(['mutation名']), 
}
// 4.actions
methods: { 
  ...mapActions(['actions名']), 
}
  • modules中的state使用
// 1.模块中的state
computed: { 
  ...mapState('模块名', ['xxx']), 
}
// 2.模块中的getters
computed: { 
  ...mapGetters('模块名', ['xxx']), 
}
// 3.模块中的mutations
methods: { 
  ...mapMutations('模块名', ['xxx']), 
}
// 4.模块中actions
methods: { 
  ...mapActions('模块名', ['xxx']), 
}

总结:

  1. 修改state状态必须通过 mutations
  2. mutations只能执行同步代码,类似ajax,定时器之类的代码不能在mutations中执行
  3. 执行异步代码,要通过 actions,然后将数据提交给mutations才可以完成
  4. state的状态即共享数据可以在组件中引用
  5. 组件中可以调用action

图解:

图解一: actions和mutations和state的关系图

image.png

图解二:核心API小结

image.png