Vuex使用总结

文章目录


一、Vuex是什么?

        引用Vuex官网原话:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

        通俗一点:它相当于一个管理数据的仓库,存放着各种需要共享的数据,所有的组件可以从中拿走数据。

        基于Vuex能够更好地在组件外部管理状态,因此赋予了前端工程师使用Vuex构建一个中大型单页应用的能力。

二、Vuex的使用

1.安装

vue2项目中安装第三版本:npm i vuex@3

vue3项目中安装第四版本:npm i vuex@4

如果使用:npm i vuex 不指定版本数将默认安装最新版本

2.实例化store

新建store(状态)文件夹,在改文件夹下新建index.js文件

// 该文件用于创建Vuex中最为核心的store

// 引入Vue
import Vue from 'vue';
// 引入Vuex
import Vuex from 'vuex';
// 应用Vuex插件
Vue.use(Vuex);

// 准备actions——用于响应组件中的动作
const actions = {}

// 准备mutations——用于操作数据
const mutations = {}

// 准备state——用于存储公共数据
const state = {}

// getters——用于将state中的数据进行加工
const getters = {}

// 使用Vuex插件
Vue.use(Vuex);

// 创建并导出store
export default new Vuex.Store({
    actions,
    mutations,
    state,
    getters
});

3.在Vue实例中注入store

//省略...
import store from "./store/index"    // 引入store
new Vue({
  //省略...
  store    // 注入Vue实例———Vue实例对象中拥有$store属性
});

三、Vuex核心

1.State

        state(译为:状态),用于存储公共数据,供组件取用

举个栗子:

// index.js

// state——用于存储数据
const state = {
    school: 'ZZULI',
    name: 'JV_32',
}
// Info组件
<template>
  <div>
    <h2>School:{{ school }}</h2>
    <h2>Name:{{ name }}</h2>
  </div>
</template>

<script>
export default {
  name: "Info",
  // 通过计算属性访问组件实例对象上的$store属性,读取state中的数据
  computed: {
    school() {
      return this.$store.state.school;
    },
    name() {
      return this.$store.state.name;
    },
  },
};
</script>

运行结果:

mapState()

        通过使用Vuex定义的工具函数mapState(),把公共数据映射到组件内部的计算属性中,就不再需要多次通过return返回从store中读取的数据了

  1. mapState()的工作结果返回的是一个对象
  2. computed配置项为对象声明格式,因此在其中使用mapState()需要使用ES6对象拓展运算符 ...ES6对象拓展运算符https://www.bookstack.cn/read/es6-3rd/spilt.6.docs-object.md
// 导入辅助函数mapState
import { mapState } from "vuex";
export default {
  name: "Info",
  computed: {
    // school() {
    //   return this.$store.state.school;
    // },
    // name() {
    //   return this.$store.state.name;
    // },

    // 对象写法: mapState({ 计算属性1: "state数据属性1", 计算属性2: "state数据属性2" }) 
    ...mapState({ school: "school", name: "name" }), 

    // 数组写法: mapState([ "state数据属性1", "state数据属性2" ]),当组件中的计算属性与state中的数据属性同名时
    ...mapState(["school", "name"]),
  },

2.Getter

        相当于组件中的computed计算属性,对state中的数据进行加工

举个栗子:

// index.js

// state——用于存储公共数据
const state = {
    school: 'ZZULI',
    name: 'JV_32',
    age: 20
}
// getters——用于将state中的数据进行加工
const getters = {
    AddAge(state) {    // 第一个参数为state对象
        return state.age += 2;
    }       
}
//Info组件
<template>
  <div>
    // 省略...
    <h3>Age:{{ AddAge }}</h3>
  </div>
</template>

<script>
export default {
  name: "Info",
 // 通过计算属性访问组件实例对象上的$store属性,读取getters中的数据
  computed: {
    AddAge() {
      return this.$store.getters.AddAge;
    },
    ...mapState(["school", "name"]),
  },
};
</script>

运行结果:

 mapGetters()

        同理,通过使用Vuex定义的工具函数mapGetters(),映射getters中的数据到计算属性中

// 导入辅助函数mapGetters
import { mapState, mapGetters } from "vuex";
export default {
  name: "Info",
  computed: {
    ...mapGetters(["AddAge"]),
    ...mapState(["school", "name"]),
  },
};

3.Action

        类似于组件中的methods配置项,用于响应组件中的动作,如:发送异步请求:Ajax等

举个栗子:

在组件中通过:this.$store.dispatch("请求的动作", 载荷) 来触发Action

export default {
  name: "Info",
  data() {
    return {
      n: 1,
    };
  },
  methods: {
    // 按钮的点击事件handler,负责向action请求increment动作
    handler() {
      this.$store.dispatch("increment", this.n);
    },
  },
};

在action中响应请求的动作increment

increment动作是一个函数:increment(context, params),context对象与store实例具有相同的方法和属性

  • 因此你可以通过context.state或者context.getters获取state和getters中的数据
  • 也可以通过context.commit()来触发Mutation,从而对state或getter中的数据进行操作
// 准备actions——用于响应组件中的动作
const actions = {
   increment(context, param) {
        // 通过commit("mutation名",载荷)触发Mutation,对state或getter中的数据进行操作
        context.commit("Add",param);    
   }
}
// 准备mutations——用于操作数据
const mutations = {
    Add(state,param) {    // 第一个参数为state对象
        state.age += param;
    }
}
// state——用于存储公共数据
const state = {
    age: 20
}

运行结果:

 mapActions()

        同理,通过使用Vuex定义的工具函数mapActions(),方法中会调用dispatch方法去联系Actions

// 导入辅助函数mapActions
import { mapActions } from "vuex";
export default {
  name: "Info",
  data() {
    return {
      n: 1,
    };
  },
  methods: {
    // handler() {
    //   this.$store.dispatch("increment", this.n);
    // },
    ...mapActions({
      handler: "increment",
    }),
  },
};

4.Mutation

        使用它来对state或getter中的数据进行操作,从而对页面进行实时更新

  1. 组件可以通过dispatch触发Action,再在Action中通过commit触发Mutation,进而对state或getter中的数据进行操作
  2. 组件也可以直接通过commit触发Mutation,进而对state或getter中的数据进行操作

        第一条线上文已经验证过了,现在验证第二条线

举个栗子:

// 组件Info
export default {
  name: "Info",
  data() {
    return {
      n: 1,
    };
  },
  methods: {
    // 按钮的点击事件handler,通过commit触发Mutation,对state或getters中数据进行操作
    handler() {
      this.$store.commit("Add", this.n);
    },
  },
};
// 准备mutations——用于操作数据
const mutations = {
    Add(state,param) {    // 第一个参数为state对象
        state.age += param;
    }
}
// 准备state——用于存储数据
const state = {
    age: 20
}

运行结果:同上↑

          同理,通过使用Vuex定义的工具函数mapMutations(),方法中会调用commit方法去联系mutations

import { mapMutations } from "vuex";
export default {
  name: "Info",
  data() {
    return {
      n: 1,
    };
  },
  methods: {
    // handler() {
    //   this.$store.commit("Add", this.n);
    // },
    ...mapMutations({
      handler: "Add",
    }),
  },
};

四、Vuex组件间通信

举个栗子:

组件一:Count.vue负责求和

组件二:Person.vue添加人物信息

需求:Count组件动态变更统计人物总数,Person组件动态变更求和信息

Count.vue

<template>
  <div>
    <h2>当前求和为:{{ sum }}</h2>
    <h3>当前求和放大十倍为:{{ bigNum }}</h3>
    <h3 style="color: red">下方组件的总人数为:{{ personList.length }}</h3>
    <button @click="increment(n)">+</button>
    <button @click="decrement(n)">-</button>
    <button @click="incrementWait(n)">等500ms加</button>
  </div>
</template>

<script>
// 引入vuex辅助函数
import { mapState, mapGetters, mapMutations, mapActions } from "vuex";
export default {
  name: "Count",
  data() {
    return {
      n: 1,
    };
  },
  computed: {
    ...mapState({    // 借助mapState从state中读取数据
      sum: "sum",
      personList: "personList",   // 获取Person组件中的数据
    }),
    ...mapGetters(["bigNum"]),    // 借助mapGetters从getters中读取数据
  },
  methods: {
    ...mapActions({
      incrementWait: "incrementWait",    // 借助mapActions生成对应方法,方法中会调用dispatch方法去联系Actions
    }),
    ...mapMutations({    // 借助mapMutations生成对应方法,方法中会调用commit方法去联系mutations
      increment: "Increment",
      decrement: "Decrement",
    }),
  },
};
</script>

Person.vue

<template>
  <div>
    <h2>Person List</h2>
    <h3 style="color: red">上方组件的求和为:{{ sum }}</h3>
    <input type="text" placeholder="请输入人员信息" v-model="name" />
    <button @click="AddPerson">添加</button>
    <ul>
      <li v-for="p in personList" :key="p.id">{{ p.name }}</li>
    </ul>
  </div>
</template>

<script>
import { nanoid } from "nanoid";
import { mapState } from "vuex";
export default {
  name: "Person",
  data() {
    return {
      name: "",
    };
  },
  computed: {
    ...mapState({
      personList: "personList",
      sum: "sum",   // 获取Count组件中的数据
    }),
  },
  methods: {
    AddPerson() {
      const personObj = { id: nanoid(), name: this.name };
      this.$store.commit("ADD_PERSON", personObj);    // 使用原生方法触发Mutation
      this.name = "";    
    },
  },
};
</script>

index.js

// 该文件用于创建Vuex中最为核心的store
// 引入Vue
import Vue from 'vue';
// 引入Vuex
import Vuex from 'vuex';
// 应用Vuex插件
Vue.use(Vuex);

// 准备actions——用于响应组件中的动作
const actions = {
    incrementWait(context,value) {
        setTimeout(() => {
            context.commit('Increment',value);
        },500)
    }
}
// 准备mutations——用于操作数据
const mutations = {
    Increment(state,value) {
        state.sum += value;
    },
    Decrement(state,value) {
        state.sum -= value;
    },
    ADD_PERSON(state,value) {
        state.personList.unshift(value);
    }
}
// 准备state——用于存储公共数据
const state = {
    sum: 9,
    personList:[
        {id:'001',name:'张三'},
        {id:'002',name:'李四'}
    ]
}
// getters——用于将state中的数据进行加工
const getters = {
    bigNum(state) {
        return state.sum * 10
    }       
}

Vue.use(Vuex);    // Vue中使用Vuex插件

// 创建并导出store
export default new Vuex.Store({
    actions,
    mutations,
    state,
    getters
});

 运行结果:

        可通过对该例进行阅读从而总结前文


总结

        结合官方文档给的Vuex图示:对以上内容进行进一步总结:

        

        总结不全,日后补充!有误望批评指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JV_32

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值