vuex的知识梳理

目录

一、概念

二、使用步骤

三、四个map方法的使用 ---------多组件共享数据

3.1、mapState 方法 

3.2、mapGetters 方法

3.3、mapMutations方法

3.4、mapActions方法

四、模块化加命名空间 


一、概念

vuex的知识梳理

什么是vuex:专门在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信

什么时候使用Vuex:

  1. 多个组件依赖于同一个状态
  2. 来自不同组件的行为需要变更同一状态
  3. 总的来说就是共享的情况下

二、使用步骤

第一步:安装vuex

 npm i vuex

第二步:创建store文件夹,新建一个index.js文件 ,该文件用于创建vuex中最为核心的store

//引入vue
import Vue from 'vue'
// 引入Vuex
import Vuex from "vuex"
// 使用Vuex
Vue.use(Vuex)

//准备actions--用于响应式组件中的动作,业务逻辑写在这儿
const actions = {....}

//准备mutation--用于操作数据(state)只能是操作
const mutations = {....}

//准备state--用于存储数据
const state ={....}

//准备getters--用于将state中的数据进行加工
const getters = {....}

//创建并暴露store
export default new Vuex.Store({

    actions,
    mutations,
    state,
    getters
})

第三步:在入口函数中传入store配置项

import Vue from "vue";
import App from './App.vue'
// 引入store
import store from './store/index'
Vue.config.productionTip = false

//创建vue
new Vue({
    el: '#app',
    render: h => h(App),
    store: store, //可以简写成store
})

组件中读取vuex中的数据:【多组件数据共享也是一样,通过下面的方法可以拿到数据】

$store.state.xx 

$store.getters.xx

组件中修改vuex的数据:

方法一:$store.dispatch('action中的方法名',数据)

方法二:$store.commit('mutations中的方法名',数据) 注意:方法名需要大些

三、四个map方法的使用 ---------多组件共享数据

组件中导入:

import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'

⚠️  注意 :以下数组写法的条件是:当计算出来的属性和读取数据名是一样的,一个属性有两个用法   

3.1、mapState 方法 

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

对象写法:

...mapState({he:'sum',xuexiao:'school',xueke:'subject'})

数组写法:

...mapState(['sum','school','subject'])

3.2、mapGetters 方法

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

对象写法:

...mapGetters({bigSum:'bigSum'})

数组写法:

...mapGetters(['bigSum'])

⚠️  注意 :以下数组写法的条件是:当方法名和提交的方法名是一样的,一个方法有两个用法   

3.3、mapMutations方法

作用:用于帮助我们生成与Mutations对话的方法,即写在$store.dispatch(xxx)的函数, 写在methods里面, 方法中会调用commit去联系mutations

对象写法:<button @click="increament(n)">+</button> 点击事件函数需要携带参数的哟

...mapMutations({ increament:'JIA',decreament:'JIAN'})

数组写法:

...mapMutations(['JIA','JIAN'])

3.4、mapActions方法

作用:用于帮助我们生成与actions对话的方法,即$store.dispatch(xxx)的函数,方法中会调用dispatch去联系actions

对象方法:

...mapActions({inceamentOdd:'jiaOdd',increamentWait:'Waitjia'})

数组写法:

...mapActions(['jiaOdd','Waitjia'])

四、模块化加命名空间 

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

命名空间

引入命名空间解决不同模块内名称冲突的问题

在设置namespaced: true后的模块无论进行什么操作都会去查找自身模块中的方法,在commit提交product/setName事件,而导出时的setName事件正好变为product/setName这样完美的进行了事件在本模块的抛发并且不会影响其他模块


请看实例:

store/index.js 

引入store文件下的 person.js 和count.js

并配置:modules:{

   countAbout:countOption,

   personAbout:personOption,

}

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

//引入vue
import Vue from 'vue'
// 引入Vuex
import Vuex from "vuex"
// 使用Vuex
Vue.use(Vuex)
import personOption from './person'
import countOption from './count'
//创建并暴露store
export default new Vuex.Store({
    modules: {
        countAbout: countOption,
        personAbout: personOption,
    }
})

store/person.js

关于人员相关的配置写到这个文件里面

const personOption = {

       namespaced:true, //命名空间
       actions: {....}
       mutations : {....}
       state : {....}
       getters : {....}
}

export default personOption

import axios from "axios";
import { nanoid } from "nanoid";

//人员管理相关的配置
const personOption = {
    namespaced: true,
    actions: {
        addPersonWang(context, value) {
            console.log(1);
            if (value.name.indexOf('王') === 0) {
                context.commit('ADD_PERSON', value)
            } else {
                alert('请输入以王开头的名字')
            }
        },
        addPersonServer(context) {
            axios.get('https://api.uixsj.cn/hitokoto/get?type=social').then(
                response => {
                    context.commit('ADD_PERSON',{id:nanoid(),name:response.data})
                },
                error => {
                    alert(error.massage)
                }
            )
        }
    },
    mutations: {
        ADD_PERSON(state, value) {
            state.Person.unshift(value)
        }
    },
    state: {
        Person: [
            { id: '001', name: '张三' }
        ]
    },
    getters: {
        firstName(state) {
            return state.Person[0].name
        }
    }
}
export default personOption

 store/count.js

关于求和相关的配置写到这个文件里面

const  countOption = {

       namespaced:true, //命名空间
       actions: {....}
       mutations : {....}
       state : {....}
       getters : {....}
}

export default countOption

//求和相关的配置
const countOption = {
    namespaced: true,
    actions: {
        jiaOdd(context, value) {
            if (context.state.sum % 2) {
                context.commit('JIA', value)
            }
        },
        Waitjia(context, value) {
            setTimeout(() => {
                context.commit("JIA", value)
            }, 500);
        }
    },
    mutations: {
        JIA(state, value) {
            state.sum += value
        },
        JIAN(state, value) {
            state.sum -= value
        },
    },
    state: {
        sum: 0, //当前求和
        school: '尚硅谷',
        subject: '计算机',
    },
    getters: {
        bigSum(state) {
            return state.sum * 10
        }
    }
}
export default countOption

Count.vue 组件:

 用map提供的方法:

...mapState('countAbout',['sum','school','subject'])

开启命名空间后: 最终查找的是 /countAbout/sum

<template>
    <div>
       <h2>求和的结果为:{{ sum }}</h2>
        <h4>求和的结果放大10倍:{{ bigSum }}</h4>
        <h5>我在{{ school }},学习{{ subject }}</h5>
        <h3 style="color: red">下方人数的总数为:{{ Person.length }}</h3>
        <select v-model.number="n">
          <option value="1">1</option>
          <option value="2">2</option>
          <option value="3">3</option>
        </select>
        <button @click="increament(n)">+</button>
        <button @click="decrement(n)">-</button>
        <button @click="increamentOdd(n)">当前求和为奇数再加</button>
        <button @click="increamentWait(n)">等一等再加</button>
    </div>
</template>

<script>
import { mapState, mapGetters, mapMutations, mapActions } from "vuex";
export default {
  name: "Count",
  data() {
    return {
      n: 1, //用户选择的数字
    };
  },
  computed: {
    ...mapState("countAbout", ["sum", "school", "subject"]),
    ...mapState("personAbout", ["Person"]),
    ...mapGetters("countAbout", ["bigSum"]),
  },
  methods: {
    ...mapMutations("countAbout", { increament: "JIA", decrement: "JIAN" }),
    ...mapActions("countAbout", {
      increamentOdd: "jiaOdd",
      increamentWait: "Waitjia",
    }),
  },
}
</script>

Person.vue组件

自己写的计算属性:注意两者的区别

this.$store.state.personAbout.Person

this.$store.getters['personAbout/firstName']


自己写的方法

this.$store.commit("personAbout/ADD_PERSON", personObj);

<template>
  <div>
    <h3>人员列表</h3>
    <h3>第一个人的名字为:{{ firstName }}</h3>
    <input type="text" v-model="name" />
    <button @click="add">添加</button>
    <button @click="addWang">添加一个姓王的人</button>
    <button @click="addPersonServer">随机添加一个人名</button>
    <ul>
      <li v-for="p in Person" :key="p.id">{{ p.name }}</li>
    </ul>
    <h3 style="color: red">上方组件的sum为:{{ sum }}</h3>
  </div>
</template>

<script>
import { nanoid } from "nanoid";
export default {
  name: "Person",
  data() {
    return {
      name: "",
    };
  },
  computed: {
    Person() {
      return this.$store.state.personAbout.Person;
    },
    sum() {
      return this.$store.state.countAbout.sum;
    },
    firstName() {
      return this.$store.getters["personAbout/firstName"];
    },
  },
  methods: {
    add() {
      const personObj = { id: nanoid(), name: this.name };
      this.$store.commit("personAbout/ADD_PERSON", personObj);
      this.name = "";
    },
    addWang() {
      const personObj = { id: nanoid(), name: this.name };
      this.$store.dispatch("personAbout/addPersonWang", personObj);
      this.name = "";
    },
    addPersonServer() {
      //因为是随机添加的一个人名,所有不用带数据,是请求服务器得到的数据
      this.$store.dispatch('personAbout/addPersonServer')
    },
  },
}
</script>

上一篇:uView——全局变量配置


下一篇:关于vue中vuex的思考,在其它js文件里想要使用vuex中的数据