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");
  },
},
相关文章
|
6月前
|
API
Vue3进阶5个小知识点 附带源码
Vue3进阶5个小知识点 附带源码
56 0
|
6月前
|
JavaScript 前端开发 算法
用vue想要拿20k,面试题要这样回答(源码版)
用vue想要拿20k,面试题要这样回答(源码版)
|
1月前
|
JavaScript 开发者
《进阶篇第9章》学习vuex知识点后练习:把求和案例改成vuex版代码
《进阶篇第9章》学习vuex知识点后练习:把求和案例改成vuex版代码
12 2
|
1月前
|
JavaScript
《进阶篇第9章》学习vuex知识点后练习:求和案例_纯vue版代码
《进阶篇第9章》学习vuex知识点后练习:求和案例_纯vue版代码
13 1
|
1月前
|
JavaScript Java
《进阶篇第9章》学习vuex知识点后练习:把求和案例改成vuex模块化编码
《进阶篇第9章》学习vuex知识点后练习:把求和案例改成vuex模块化编码
30 5
|
1月前
|
JavaScript
《进阶篇第9章》学习vuex知识点后练习:把求和案例改成getters
《进阶篇第9章》学习vuex知识点后练习:把求和案例改成getters
14 0
|
1月前
|
JavaScript
《进阶篇第9章》学习vuex知识点后练习:把求和案例改成mapState与mapGetters
《进阶篇第9章》学习vuex知识点后练习:把求和案例改成mapState与mapGetters
12 0
|
1月前
|
JavaScript
《进阶篇第9章》学习vuex知识点后练习:把求和案例改成多组件共享数据
《进阶篇第9章》学习vuex知识点后练习:把求和案例改成多组件共享数据
22 0
|
3月前
|
JavaScript 程序员 开发者
vue组件的使用与基础知识你真的完全明白吗?
【8月更文挑战第16天】vue组件的使用与基础知识你真的完全明白吗?
40 3
vue组件的使用与基础知识你真的完全明白吗?
|
6月前
|
JavaScript 前端开发 API
vue3的知识点,要点,注意事项
vue3的知识点,要点,注意事项
49 1