VueX用法快速回顾(简洁纯干货)

我正在参加「掘金·启航计划」

vuex基础结构

代码结构

vuex的完整结构长这样,其包含了state、mutations、actions、modules及getters5个部分。

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const store = new Vuex.Store({
  state: {},
  mutations: {},
  actions:{},
  modules:{},
  getters:{}
})

new Vue({
  el: '#app',
})

假设我们在上述store内补充一些方法

const store = new Vuex.Store({
  state: {
    count:0
  },
  mutations: {
    add(state){
      state.count ++
    }
  },
  actions:{},
  modules:{},
  getters:{}
})

现在,我们可以采用store.commit(‘add’) 的方式来更改count的值。

为了在其他vue组件中使用 this.$store 访问,我们可以这么做:

new Vue({
  el: '#app',
  store: store,
})

项目结构

为了使项目结构更加清晰,我们一般这么定义结构

├─ src
│  ├─ App.vue
│  ├─ main.js
│  └─ store
│     └─ index.js
//  index.js
import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    count: 0,
  },
  getters: {},
  mutations: {
    add(state) {
      state.count++;
    },
  },
  actions: {},
  modules: {},
});
// main.js
import Vue from "vue";
import App from "./App.vue";
import store from "./store";

Vue.config.productionTip = false;

new Vue({
  store,
  render: (h) => h(App),
}).$mount("#app");

如果modules比较多,我们还可以在创建一个文件夹用来存放,比如在store下创建moduleA文件夹,我们在moduleA内创建index.js,并写入一些内容:

export default {
  state: {},
  getters: {},
  mutations: {},
  actions: {},
};

然后store根目录的index.js可以改写

import Vue from "vue";
import Vuex from "vuex";
import moduleA from "./moduleA/index";
Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    count: 0,
  },
  getters: {},
  mutations: {
    add(state) {
      state.count++;
    },
  },
  actions: {},
  modules: {
    moduleA: moduleA,
  },
});

state的访问

state的方法有两种,一种是采用this.$store直接访问,另一种是借助mapState ****辅助函数。

this.$store访问

在上图中,我们可以看到this.$store上存在state属性,我们可以展开看看

VueX用法快速回顾(简洁纯干货)

很明显,通过this.$store.count可以直接访问到

mapState 辅助函数

import { mapState } from "vuex";  //引入方法
export default {
  name: "App",
  computed: {
    ...mapState(["count"]),        // 注意这里是数组
  },
};

VueX用法快速回顾(简洁纯干货)

Mutation的触发

我们知道Mutation中的函数是用来更改state中某个属性的状态的,如下面的代码

export default new Vuex.Store({
  state: {
    text: 0,
  },
  mutations: {
    // mutations函数有两个参数,第一个参数是 state ,第二个参数是传递进来的值
    changeText(state, payload) {
      state.text = payload;
    },
  },
});

它有两种调用方式:

通过this.$store触发

  methods: {
    // 在函数中直接使用  
    changeBtn1() {
      this.$store.commit("changeText", "你好,世界");
    },
  },

通过mapMutations辅助函数

// 1.引入mapMutations函数
import { mapMutations } from "vuex";
methods: {
  // 2.在methods中使用拓展运算符展开函数
  ...mapMutations(["changeText"]),
  // 3.调用阿含糊
  changeBtn2() {
    this.changeText("鱿鱼须懂个锤子vue");
  },
},

代码演示

<template>
  <div id="app">
    <div>text的内容是: {{ text }}</div>
    <button @click="changeBtn1">this.$store.commit更改</button>
    <button @click="changeBtn2">mapMutations更改</button>
  </div>
</template>

<script>
import { mapState, mapMutations } from "vuex";
export default {
  name: "App",
  computed: {
    ...mapState(["text"]),
  },
  methods: {
    ...mapMutations(["changeText"]),
    changeBtn1() {
      this.$store.commit("changeText", "你好,世界");
    },
    changeBtn2() {
      this.changeText("鱿鱼须懂个锤子vue");
    },
  },
};
</script>

VueX用法快速回顾(简洁纯干货)

Action的触发

Action的触发方式同Mutation,它可以用来执行异步函数

export default new Vuex.Store({
  state: {
    text: 0,
  },
  mutations: {
    // mutations函数有两个参数,第一个参数是 state ,第二个参数是传递进来的值
    changeText(state, payload) {
      state.text = payload;
    },
  },
  actions: {
    laterChange(context, value) {
      setTimeout(() => {
        context.commit("changeText", value);
      }, 1000);
    },
  },
});

通过this.$store触发

  methods: {
    // 在函数中直接使用  
    changeBtn1() {
      this.$store.dispatch("laterChange", "你好,世界");
    },
  },

通过mapActions辅助函数

// 1.引入mapActions函数
import {mapActions } from "vuex";
methods: {
  // 2.在methods中使用拓展运算符展开函数
  ...mapMutations(["laterChange"]),
  // 3.调用阿含糊
  changeBtn2() {
    this.laterChange("鱿鱼须懂个锤子vue");
  },
},

代码演示

<template>
  <div id="app">
    <div>text的内容是: {{ text }}</div>
    <button @click="changeBtn1">this.$store.dispatch更改</button>
    <button @click="changeBtn2">mapActions更改</button>
  </div>
</template>

<script>
import { mapState, mapActions, } from "vuex";
export default {
  name: "App",
  computed: {
    ...mapState(["text"]),
  },
  methods: {
    ...mapActions(["laterChange"]),
    changeBtn1() {
      this.$store.dispatch("laterChange", "你好,世界");
    },
    changeBtn2() {
      this.laterChange("鱿鱼须懂个锤子vue");
    },
  },
};
</script>

VueX用法快速回顾(简洁纯干货)

actions函数的context参数

context有若干参数,如下

VueX用法快速回顾(简洁纯干货)

  • 通过dispatch可以直接调用action平级内的函数
  • 通过commit可以调用mutations内的函数
  • 通过getters可以直接访问当前模块内的getters属性值
  • 通过state可以访问当前模块内的state属性值
  • 通过rootState可以访问根节点内的state属性值
  • 通过rootGetters可以访问根节点内的getters属性值

实际开发中,利用解构赋值可以优化代码:

  actions: {
    laterChange({ dispatch, commit }, value) {
      setTimeout(() => {
        commit("changeText", value);
      }, 1000);
    },
  },

Module

当应用变得非常复杂时,store 对象就有可能变得相当臃肿。

为了解决以上问题,Vuex 允许我们将 store 分割成模块(module) 。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块。

export default new Vuex.Store({
  state: {},
  mutations: {},
  actions: {},
  getters: {},
  modules: {
    moduleA: {
      // 是否开启命名空间
      namespaced: true,                
      state: { count: 0 },
      getters: {},
      mutations: {
        add(state, payload) {
          state.count += payload;
        },
      },
      actions: {
        sub({ state, commit }, payload) {
          commit("add", payload);
        },
      },
    },
  },
});

state数据访问

// 方法一
this.$store.state.moduleA.count
// 方法二 需要模块开启命名空间,不开启会报错
computed: {
  ...mapState("moduleA", ["count"]),
},

不开启命名空间的时候,只能使用方式一,开启后两种方式都可以使用

Mutation的调用

// 方法一
this.$store.commit("moduleA/add", "自定义value");
// 方法二 需要模块开启命名空间,不开启会报错
methods: {
  ...mapMutations("moduleA", ["add"]),
  changeBtn1() {
    this.add("自定义value");
  },
},

Action的调用

// 方法一
this.$store.dispatch("moduleA/sub", "自定义value");
// 方法二 需要模块开启命名空间,不开启会报错
methods: {
  ...mapActions("moduleA", ["sub"]),
  changeBtn1() {
    this.sub("自定义value");
  },
},

原文链接:https://juejin.cn/post/7249033891809329212 作者:石小石Orz

(0)
上一篇 2023年6月25日 上午11:14
下一篇 2023年6月27日 上午10:06

相关推荐

发表回复

登录后才能评论