什么是Vue:

Vuex是一个用来管理组件之间通信的插件,它是一个专为Vue.js应用程序开发的状态管理模式,它解决了多组件之间同一状态的共享问题,它能够更好地在组件外部管理状态。

Vuex相当于是Vue的一个集中式的存储仓库

  • 它储存的数据就是状态
  • 存储仓库:本地存储cookie数据库

开发中大型应用时使用 集中式数据管理,一处修改,多处使用

安装

  • yarn

    $ yarn add vuex@next -save

手动在 src 目录下新建 store 文件夹 在该文件夹内创建 index.ts

使用

1.初始化store下index.ts中的内容

  1. // todo 1、 引入资源
  2. import { createStore } from "vuex";
  3. // todo 2、 创建一个store实例
  4. const store = createStore({
  5. modules:{ // 用于数据分块
  6. ...各种类数据块
  7. }
  8. })
  9. // todo 3、 导出store
  10. export default store

2.在mian.ts中激活挂载到当前项目到Vue实例当中去

  1. todo 1、导入store
  2. import store from './store'
  3. todo 2 使用use方法来激活store这个单例
  4. createApp(App).use(store).mount('#app')

3.在组件中使用Vuex

  1. // 在vuex中引出useStore
  2. import {useStore} from 'vuex'
  3. export default defineComponent({
  4. setup(){
  5. const store = useStore() // 在setup中通过useStore得到一个store实例
  6. console.log(store) // 此时你可以打印看看这个实例,数据块在该实例的state中
  7. 通过计算属性方法得到store中的数据
  8. const n = computed(() => store.state.数据块类名.数据)
  9. const add = () => {
  10. // 通过store实例中的dispatch方法来激活actions
  11. store.dispatch({
  12. type: '数据库名/actions中的方法名',
  13. payload:xxx
  14. })
  15. }
  16. return {
  17. n,
  18. add,
  19. }
  20. }
  21. })

Composition API

要访问setup钩子中的store,需要调用 useStore 函数,等效 this.$store与使用OptionAPI在组件内进行检索

  1. import { useStore } from 'vuex'
  2. export default {
  3. setup () {
  4. const store = useStore();
  5. }
  6. }

为了访问状态和获取方法,需要创建 computed 引用以保留反应性。

  1. const n = computed(() => store.state.count)

访问actions需要使用 dispatch

  1. store.dispatch({
  2. type: '数据库名/actions中的方法名',
  3. payload:xxx
  4. })

核心内容

State、Getters、Mutations、Actions、Modules

State 状态 数据 Getters 几乎不实用。。。 Actions 动作 mutations 修改数据 Modules 用于数据分块

vue2 中 Vuex3 的使用

Vue2 使用vuex3 vue3 使用vuex4

安装

$ yarn add vuex@3

基础搭建

  1. // 该文件用于创建vuex中最为核心的store
  2. // 引入vue
  3. import Vue from 'vue';
  4. // 引入vuex
  5. import Vuex from 'vuex';
  6. // 使用vuex插件
  7. Vue.use(Vuex);
  8. // 准备 actions 用于响应组件中的动作
  9. const actions = {}
  10. // 准备 mutations 用于操作数据(state)
  11. const mutations = {}
  12. // 准备 state 用于存储
  13. const state = {}
  14. // 创建并导出 store
  15. export default new Vuex.Store({
  16. actions,
  17. mutations,
  18. state,
  19. });
  1. import Vue from 'vue'
  2. import App from './App.vue'
  3. // 引入我们创建的store
  4. import store from './store';
  5. Vue.config.productionTip = false;
  6. new Vue({
  7. render: h => h(App),
  8. // vue配置项中添加 store 项
  9. store, // 此时vm身上会有一个 $store 属性
  10. }).$mount('#app')

简单的计数案例

vuexCount.gif

  1. // 该文件用于创建vuex中最为核心的store
  2. import Vue from 'vue';
  3. // 引入vuex
  4. import Vuex from 'vuex';
  5. // 使用vuex插件
  6. Vue.use(Vuex);
  7. // 准备 actions 用于响应组件中的动作
  8. const actions = {
  9. increment: function (context, payload) {
  10. console.log('increment', context, payload);
  11. context.commit('INCREMENT', payload);
  12. },
  13. subtract: function (context, payload) {
  14. context.commit('SUBTRACT', payload);
  15. }
  16. }
  17. // 准备 mutations 用于操作数据(state)
  18. const mutations = {
  19. INCREMENT: function (state, payload) {
  20. console.log('INCREMENT', state, payload);
  21. state.count += payload;
  22. },
  23. SUBTRACT: function (state, payload) {
  24. state.count -= payload;
  25. }
  26. }
  27. // 准备 state 用于存储
  28. const state = {
  29. count: 0,
  30. }
  31. // 创建并导出 store
  32. export default new Vuex.Store({
  33. actions,
  34. mutations,
  35. state,
  36. });
  37. // ------------------src/main.js------------------------------------
  38. // main.js 中使用 store
  39. import Vue from 'vue'
  40. import App from './App.vue'
  41. // 引入我们创建的store
  42. import store from './store';
  43. console.log(store);
  44. Vue.config.productionTip = false
  45. new Vue({
  46. render: h => h(App),
  47. // vue配置项中添加 store 项
  48. store, // 此时vm身上会有一个 $store 属性
  49. }).$mount('#app')
  1. <template>
  2. <div>
  3. <h1>{{ count }}</h1>
  4. <h1>{{ $store.state.count }}</h1>
  5. <select v-model.number="n">
  6. <option value="1">1</option>
  7. <option value="2">2</option>
  8. <option value="3">3</option>
  9. </select>
  10. <button @click="increment">加{{ n }}</button>
  11. <button @click="subtract">减{{ n }}</button>
  12. </div>
  13. </template>
  14. <script>
  15. export default {
  16. data() {
  17. return {
  18. n: 1,
  19. };
  20. },
  21. computed: {
  22. count() {
  23. return this.$store.state.count;
  24. },
  25. },
  26. methods: {
  27. increment() {
  28. this.$store.dispatch("increment", this.n);
  29. // this.$store.commit("INCREMENT", this.n);
  30. },
  31. subtract() {
  32. this.$store.dispatch("subtract", this.n);
  33. },
  34. },
  35. };
  36. </script>
  37. <style>
  38. </style>

组件中读取vuex中的数据:$store.state.count
组件中修改vuex中的数据:$store.dispatch('actions中的方法名', 数据) 或者 $store.commit('mutations中的方法名', 数据)

tips:若没有网络请求或者其他业务逻辑,组件中也可以直接越过actions,即不写 dispatch,直接使用 commit

核心 - getters(冷门)

  1. 概念:当state中的数据需要经过加工后再使用时,可以使用getters加工。
  2. store.js 中追加 getters 配置项 ```javascript … const getters = { tenfoldCount(state) {
    1. return state.count * 10;
    } }

export default new Vuex.Store({ actions, mutations, state,

  1. getters, // 配置我们创建的getters

});

  1. 3. 组件中读取数据:`$store.getters.tenfoldCount`
  2. <a name="zyseV"></a>
  3. ### vuex中的四个map方法的使用
  4. 使用时都需要在组件中导入
  5. ```javascript
  6. import { mapState, mapGetters, mapActions, mapMutations } from "vuex";

mapState

用于帮助我们映射 state 中的数据为计数属性

  1. computed:{
  2. // 借助 mapState 生成计算属性:count、info(对象写法,使用时直接使用key值)
  3. ...mapState({ count: "count", info: "info" }),
  4. // 借助 mapState 生成计算属性:count、info(数组写法)
  5. ...mapState(['count', 'info']),
  6. }

mapGetters

用于帮助我们映射 getters 中的数据为计算属性

  1. computed: {
  2. // 借助 mapGetters 生成计算属性:tenfoldCount(对象写法)
  3. ..mapGetters([tenfoldCount: "tenfoldCount"]),
  4. // 借助 mapGetters 生成计算属性:tenfoldCount(数组写法)
  5. ...mapGetters(["tenfoldCount"]),
  6. },

mapActions

用于帮助我们生产与 actions 对话的方法,即:包含 $store.dispatch(xxx) 的函数

  1. methods: {
  2. // 生成 increment、subtract(对象写法)
  3. ...mapActions({ increment: "increment", subtract: "subtract" }),
  4. // 生成 increment、subtract(数组写法)
  5. ...mapActions(["increment", "subtract"]),
  6. },
  7. // 在模板中使用时候进行传递参数,否则默认传递Event事件对象。
  8. <button @click="increment(n)">加{{ n }}</button>
  9. <button @click="subtract(n)">减{{ n }}</button>

mapMutations

用于帮助我们生成与 mutations 对话的方法,即:包含 $store.commit(xxx) 的函数

  1. methods: {
  2. // 生成 INCREMENT、SUBTRACT(对象写法)
  3. ...mapMutations({ INCREMENT: "INCREMENT", SUBTRACT: "SUBTRACT" }),
  4. // 生成 INCREMENT、SUBTRACT(数组写法)
  5. ...mapMutations(["INCREMENT", "SUBTRACT"]),
  6. },
  7. // 在模板中使用时候进行传递参数,否则默认传递Event事件对象。
  8. <button @click="INCREMENT(n)">加{{ n }}</button>
  9. <button @click="SUBTRACT(n)">减{{ n }}</button>

tips:mapActions 与 mapMutations 使用时,若需要传递参数,需要在模板绑定事件时传递好参数,否则默认参数为 Event事件对象。

模块化+命名空间

目的:让代码更好维护,让多种数据分类更加明确。

  1. const moduleA = {
  2. state: () => ({ ... }),
  3. mutations: { ... },
  4. actions: { ... },
  5. getters: { ... }
  6. }
  7. const moduleB = {
  8. state: () => ({ ... }),
  9. mutations: { ... },
  10. actions: { ... }
  11. }
  12. const store = new Vuex.Store({
  13. modules: {
  14. moduleA,
  15. moduleB
  16. }
  17. })

开启命名空间后,组件中读取 state 数据:

  1. // 方法一:自己直接读取
  2. this.$store.state.moduleA.stateName;
  3. // 方法二:借助mapState读取
  4. ...mapState('moduleA', ['stateName1', 'stateName2']);

开启命名空间后,组件中读取 getters 数据:

  1. // 方法一:自己直接读取
  2. this.$store.getters['moduleA/stateName1'];
  3. // 方法二:借用mapGetters读取
  4. ...mapGetters('moduleA', ['getterName1', 'getterName2']);

开启命名空间后,组件中调用 dispatch :

  1. // 方法一:自己直接调用
  2. this.$store.dispatch('moduleA/dispatchName', data);
  3. // 方法二:借助mapActions调用
  4. ...mapActions('moudleA', ['dispatchName1', 'dispatchName2']);

开启命名空间后,组件中调用 commit :

  1. // 方法一:自己直接调用
  2. this.$store.commit('moduleA/MutationsName', data);
  3. // 方法二:借助mapMutations调用
  4. ...mapMutations('moduleA', ['MutationsName1', 'MutationsName2'])