VueX用法快速回顾(适用于有基础的同学)

简介: 【8月更文挑战第20天】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属性,我们可以展开看看
GIF 2023-2-9 10-59-56.gif
很明显,通过this.$store.count可以直接访问到

mapState 辅助函数

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

image.png

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>

GIF 2023-2-9 11-35-03.gif

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>

GIF 2023-2-9 11-48-30.gif

actions函数的context参数

context有若干参数,如下
image.png

  • 通过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");
  },
},
相关文章
|
29天前
|
JavaScript 前端开发 开发者
Vue v-for 进阶指南:in 与 of 的区别及应用场景 | 笔记
Vue.js 中的 v-for 是强大的遍历指令,但其中的 in 和 of 关键字往往被开发者忽视。尽管它们的用法相似,但适用的场景和数据结构却各有不同。本文将详细探讨 v-for 中 in 和 of 的区别、适用场景以及在实际开发中的最佳使用时机。通过理解它们的差异,你将能够编写更加高效、简洁的 Vue.js 代码,灵活应对各种数据结构的遍历需求。
86 6
|
29天前
|
JavaScript 开发者
《进阶篇第9章》学习vuex知识点后练习:把求和案例改成vuex版代码
《进阶篇第9章》学习vuex知识点后练习:把求和案例改成vuex版代码
12 2
|
29天前
|
JavaScript
《进阶篇第9章》学习vuex知识点后练习:求和案例_纯vue版代码
《进阶篇第9章》学习vuex知识点后练习:求和案例_纯vue版代码
13 1
|
1月前
|
JavaScript Java
《进阶篇第9章》学习vuex知识点后练习:把求和案例改成vuex模块化编码
《进阶篇第9章》学习vuex知识点后练习:把求和案例改成vuex模块化编码
30 5
|
1月前
|
JavaScript 开发者
vue指令的开发看这篇文章就够了!超详细,赶快收藏!
【10月更文挑战第8天】vue指令的开发看这篇文章就够了!超详细,赶快收藏!
vue指令的开发看这篇文章就够了!超详细,赶快收藏!
|
1月前
|
JavaScript
《进阶篇第9章》学习vuex知识点后练习:把求和案例改成mapState与mapGetters
《进阶篇第9章》学习vuex知识点后练习:把求和案例改成mapState与mapGetters
12 0
|
6月前
|
移动开发 缓存 JavaScript
30 道 Vue 面试题,内含详细讲解(涵盖入门到精通,自测 Vue 掌握程度
30 道 Vue 面试题,内含详细讲解(涵盖入门到精通,自测 Vue 掌握程度
99 6
|
6月前
|
JavaScript 前端开发 API
vue3的知识点,要点,注意事项
vue3的知识点,要点,注意事项
48 1
|
资源调度 JavaScript 前端开发
Vue3框架的创建的两种种方案(第十二课)
Vue3框架的创建的两种种方案(第十二课)
65 0
|
缓存 JavaScript 前端开发
web前端面试高频考点——Vue的基本使用(一文掌握Vue最基础的知识点)
web前端面试高频考点——Vue的基本使用(一文掌握Vue最基础的知识点)