vuex

作者: 5cc9c8608284 | 来源:发表于2022-03-22 14:16 被阅读0次

1.概念

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

2.何时使用?

多个组件需要共享数据时

3.搭建 vuex 环境

  1. 创建文件:src/store/index.js

    //引入Vue核心库
    import Vue from "vue";
    //引入Vuex
    import Vuex from "vuex";
    //应用Vuex插件
    Vue.use(Vuex);
    
    //准备actions对象——响应组件中用户的动作
    const actions = {};
    //准备mutations对象——修改state中的数据
    const mutations = {};
    //准备state对象——保存具体的数据
    const state = {};
    
    //创建并暴露store
    export default new Vuex.Store({
      actions,
      mutations,
      state,
    });
    
  2. main.js中创建 vm 时传入store配置项

    ......
    //引入store
    import store from './store'
    ......
    
    //创建vm
    new Vue({
     el:'#app',
     render: h => h(App),
     store
    })
    

4.基本使用

  1. 初始化数据、配置actions、配置mutations,操作文件store.js

    //引入Vue核心库
    import Vue from "vue";
    //引入Vuex
    import Vuex from "vuex";
    //引用Vuex
    Vue.use(Vuex);
    
    const actions = {
      //响应组件中加的动作
      jia(context, value) {
        // console.log('actions中的jia被调用了',miniStore,value)
        context.commit("JIA", value);
      },
    };
    
    const mutations = {
      //执行加
      JIA(state, value) {
        // console.log('mutations中的JIA被调用了',state,value)
        state.sum += value;
      },
    };
    
    //初始化数据
    const state = {
      sum: 0,
    };
    
    //创建并暴露store
    export default new Vuex.Store({
      actions,
      mutations,
      state,
    });
    
  2. 组件中读取 vuex 中的数据:$store.state.sum

  3. 组件中修改 vuex 中的数据:$store.dispatch('action中的方法名',数据)$store.commit('mutations中的方法名',数据)

    备注:若没有网络请求或其他业务逻辑,组件中也可以越过 actions,即不写dispatch,直接编写commit

5.getters 的使用

  1. 概念:当 state 中的数据需要经过加工后再使用时,可以使用 getters 加工。

  2. store.js中追加getters配置

    ......
    
    const getters = {
     bigSum(state){
         return state.sum * 10
     }
    }
    
    //创建并暴露store
    export default new Vuex.Store({
     ......
     getters
    })
    
  3. 组件中读取数据:$store.getters.bigSum

6.四个 map 方法的使用

1.mapState 方法:用于帮助我们映射state中的数据为计算属性

computed: {
    //借助mapState生成计算属性:sum、school、subject(对象写法)
     ...mapState({sum:'sum',school:'school',subject:'subject'}),

    //借助mapState生成计算属性:sum、school、subject(数组写法)
    ...mapState(['sum','school','subject']),
},
  1. mapGetters 方法:用于帮助我们映射getters中的数据为计算属性

    computed: {
        //借助mapGetters生成计算属性:bigSum(对象写法)
        ...mapGetters({bigSum:'bigSum'}),
    
        //借助mapGetters生成计算属性:bigSum(数组写法)
        ...mapGetters(['bigSum'])
    },
    

3.mapActions 方法:用于帮助我们生成与actions对话的方法,即:包含$store.dispatch(xxx)的函数

methods:{
    //靠mapActions生成:incrementOdd、incrementWait(对象形式)
    ...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'})

    //靠mapActions生成:incrementOdd、incrementWait(数组形式)
    ...mapActions(['jiaOdd','jiaWait'])
}
  1. mapMutations 方法:用于帮助我们生成与mutations对话的方法,即:包含$store.commit(xxx)的函数

    methods:{
        //靠mapActions生成:increment、decrement(对象形式)
        ...mapMutations({increment:'JIA',decrement:'JIAN'}),
    
        //靠mapMutations生成:JIA、JIAN(对象形式)
        ...mapMutations(['JIA','JIAN']),
    }
    

备注:mapActions 与 mapMutations 使用时,若需要传递参数:在模板中绑定事件时传递好参数,否则参数是事件对象。

7.模块化+命名空间

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

  2. 修改store.js

    const countAbout = {
      namespaced:true,//开启命名空间
      state:{x:1},
      mutations: { ... },
      actions: { ... },
      getters: {
        bigSum(state){
           return state.sum * 10
        }
      }
    }
    
    const personAbout = {
      namespaced:true,//开启命名空间
      state:{ ... },
      mutations: { ... },
      actions: { ... }
    }
    
    const store = new Vuex.Store({
      modules: {
        countAbout,
        personAbout
      }
    })
    
  3. 开启命名空间后,组件中读取 state 数据:

    //方式一:自己直接读取
    this.$store.state.personAbout.list
    //方式二:借助mapState读取:
    ...mapState('countAbout',['sum','school','subject']),
    
  4. 开启命名空间后,组件中读取 getters 数据:

    //方式一:自己直接读取
    this.$store.getters['personAbout/firstPersonName']
    //方式二:借助mapGetters读取:
    ...mapGetters('countAbout',['bigSum'])
    
  5. 开启命名空间后,组件中调用 dispatch

    //方式一:自己直接dispatch
    this.$store.dispatch('personAbout/addPersonWang',person)
    //方式二:借助mapActions:
    ...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
    
  6. 开启命名空间后,组件中调用 commit

    //方式一:自己直接commit
    this.$store.commit('personAbout/ADD_PERSON',person)
    //方式二:借助mapMutations:
    ...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),
    

案例
store/index.js

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

//准备actions——用于响应组件中的动作
const actions = {
    /* jia(context,value){
        console.log('actions中的jia被调用了')
        context.commit('JIA',value)
    },
    jian(context,value){
        console.log('actions中的jian被调用了')
        context.commit('JIAN',value)
    }, */
    jiaOdd(context,value){
        console.log('actions中的jiaOdd被调用了')
        if(context.state.sum % 2){
            context.commit('JIA',value)
        }
    },
    jiaWait(context,value){
        console.log('actions中的jiaWait被调用了')
        setTimeout(()=>{
            context.commit('JIA',value)
        },500)
    }
}
//准备mutations——用于操作数据(state)
const mutations = {
    JIA(state,value){
        console.log('mutations中的JIA被调用了')
        state.sum += value
    },
    JIAN(state,value){
        console.log('mutations中的JIAN被调用了')
        state.sum -= value
    }
}
//准备state——用于存储数据
const state = {
    sum:0, //当前的和
    school:'尚硅谷',
    subject:'前端'
}
//准备getters——用于将state中的数据进行加工
const getters = {
    bigSum(state){
        return state.sum*10
    }
}

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

组件Count.vue

<template>
    <div>
        <h1>当前求和为:{{sum}}</h1>
        <h3>当前求和放大10倍为:{{bigSum}}</h3>
        <h3>我在{{school}},学习{{subject}}</h3>
        <select v-model.number="n">
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
        </select>
        <button @click="increment(n)">+</button>
        <button @click="decrement(n)">-</button>
        <button @click="incrementOdd(n)">当前求和为奇数再加</button>
        <button @click="incrementWait(n)">等一等再加</button>
    </div>
</template>

<script>
    import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'
    export default {
        name:'Count',
        data() {
            return {
                n:1, //用户选择的数字
            }
        },
        computed:{
            //借助mapState生成计算属性,从state中读取数据。(对象写法)
            // ...mapState({he:'sum',xuexiao:'school',xueke:'subject'}),

            //借助mapState生成计算属性,从state中读取数据。(数组写法)
            ...mapState(['sum','school','subject']),

            /* ******************************************************************** */

            //借助mapGetters生成计算属性,从getters中读取数据。(对象写法)
            // ...mapGetters({bigSum:'bigSum'})
            
            //借助mapGetters生成计算属性,从getters中读取数据。(数组写法)
            ...mapGetters(['bigSum'])

        },
        methods: {
            //程序员亲自写方法
            /* increment(){
                this.$store.commit('JIA',this.n)
            },
            decrement(){
                this.$store.commit('JIAN',this.n)
            }, */

            //借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(对象写法)
            ...mapMutations({increment:'JIA',decrement:'JIAN'}),

            //借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(数组写法)
            // ...mapMutations(['JIA','JIAN']),

            /* ************************************************* */

            //程序员亲自写方法
            /* incrementOdd(){
                this.$store.dispatch('jiaOdd',this.n)
            },
            incrementWait(){
                this.$store.dispatch('jiaWait',this.n)
            }, */

            //借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(对象写法)
            ...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'})

            //借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(数组写法)
            // ...mapActions(['jiaOdd','jiaWait'])
        },
        mounted() {
            const x = mapState({he:'sum',xuexiao:'school',xueke:'subject'})
            console.log(x)
        },
    }
</script>

<style lang="css">
    button{
        margin-left: 5px;
    }
</style>

模块化以后的案例:
store/person.js

import axios from 'axios'
axios.get('https://api.uixsj.cn/hitokoto/get?type=social').then(res => {
    console.log(res, 'res');
});
export const personOption = {
    namespaced: true,
    state: {
        persons: [{
                id: 0,
                name: '年好呀'
            },
            {
                id: 1,
                name: 'apple'
            },
            {
                id: 2,
                name: 'lemon'
            },
            {
                id: 2,
                name: 'orange'
            },
        ]
    },
    getters: {
        firstPersonName(state) {
            return state.persons[0].name
        },
        lastPersonName(state) {
            let len = state.persons.length;
            return state.persons[len - 1].name
        },
    },
    mutations: {
        addPerson(state, person) {
            console.log(person);
            state.persons.push(person)
        },
        addPersonBefore(state, person) {
            state.persons.unshift(person)
        }
    },
    actions: {
        addPersonWang(context, value) {
            if (value.name.indexOf('王') != -1) {
                context.commit('addPerson', value)
            }
        },
        addPersonBefore(context, value) {
            context.commit('addPersonBefore', value)
        },
        addPersonServer(context) {
            axios.get('https://api.uixsj.cn/hitokoto/get?type=social').then(res => {
                console.log(res, 'res');
                let name = res.data;
                let person = {
                    id: Math.random(),
                    name
                }
                context.commit('addPerson', person)
            }).catch(err => {
                alert(err)
            });

        }
    },
}

store/count.js

export const countOption = {
    namespaced: true,

    state: {
        sum: 0,
        sum1: 1,
        school: '尚硅谷',
        subject: '前端',
    },
    getters: {
        bigSum(state) {
            return state.sum * 10 //这里得写返回值
        }
    },
    mutations: {
        addSum(state, num) {
            state.sum += num
        },
        desc(state, num) {
            state.sum -= num
        },
    },
    actions: {},
}

store/index.js

import Vue from 'vue'
import Vuex from 'vuex'
import {
  countOption
} from './count'
import {
  personOption
} from './person'
Vue.use(Vuex)



export default new Vuex.Store({
  state: {},
  getters: {

  },
  mutations: {



  },
  actions: {

  },
  modules: {
    a: countOption,
    b: personOption
  }
})

Person.vue

<template>
  <div>
    <h2>人员列表</h2>
    <ul>
      <li v-for="item in persons" :key="item.name">{{ item.name }}</li>
    </ul>
    <h3>当前何为:{{ bigSum }}</h3>
    <el-input
      style="width: 145px"
      v-model="name"
      placeholder="请输入名字"
    ></el-input>

    <el-button @click="addPerson">添加</el-button>
    <el-button @click="addPersonWang1">添加王姓同志</el-button>
    <el-button @click="addPersonBefore">在前面添加人员</el-button>
    <el-button @click="addPersonServer">添加服务端请求过来的数据</el-button>

    <hr />
    <h2>{{ firstPersonName }}</h2>
    <h2>{{ lastPersonName }}</h2>
  </div>
</template>

<script>
import { mapState, mapGetters } from "vuex";
export default {
  name: "",
  mounted() {
    console.log(this.$store); //打印一下你就知道了
  },
  data() {
    return {
      name: "",
    };
  },
  computed: {
    ...mapState("b", ["persons"]),
    ...mapGetters("a", ["bigSum"]),
    ...mapGetters("b", ["firstPersonName"]),
    lastPersonName() {
      return this.$store.getters["b/lastPersonName"];
    },
  },
  methods: {
    addPersonServer() {
      this.$store.dispatch("b/addPersonServer");
    },
    addPerson() {
      console.log("添加");
      let person = {
        id: Math.random(),
        name: this.name,
      };
      this.$store.commit("b/addPerson", person);
    },
    addPersonWang1() {
      let person = {
        id: Math.random(),
        name: this.name,
      };
      this.$store.dispatch("b/addPersonWang", person);
    },
    addPersonBefore() {
      let person = {
        id: Math.random(),
        name: this.name,
      };
      this.$store.dispatch("b/addPersonBefore", person);
    },
  },
};
</script>

Count.vue

<template>
  <div>
    <h2>{{ $store.getters.bigSum }}</h2>
    <button @click="addSu">+</button>
    <button @click="descSum">-</button>
    <button @click="oddSum">当前求和为奇数再加</button>
    <button @click="waitSum">等一等再加</button>
    <h3>当前的求和结果为:{{ this.$store.state.a.sum }}</h3>
    <h3>当前求和放大10倍wei:{{ this.$store.state.a.sum * 10 }}</h3>
    <h3>当前求和放大10倍wei:{{ tenNum }}</h3>
    <h2>我在{{ $store.state.a.school }},学习{{ $store.state.a.subject }}</h2>
    {{ num }}
    <select v-model="num" @change="handleChange">
      <option :value="1">1</option>
      <option :value="2">2</option>
      <option :value="3">3</option>
    </select>

    <hr />

    <ul>
      <li v-for="item in persons" :key="item.name">{{ item.name }}</li>
    </ul>
  </div>
</template>

<script>
import { mapState } from "vuex";
export default {
  name: "",

  data() {
    return {
      num: 0,
      // sum: undefined,
    };
  },
  computed: {
    tenNum() {
      return this.$store.state.a.sum * 10;
    },
    // 借助mapState生成计算属性,从state中读取数据(对象写法)
    // ...mapState({
    //   xuexiao: "school",
    //   kemu: "subject",
    // }),

    ...mapState("a", ["school", "subject", "sum1", "sum"]),
    persons() {
      return this.$store.state.b.persons;
    },
  },
  mounted() {
    const x = mapState({
      he: "sum",
    });
    console.log(x);
  },
  methods: {
    oddSum() {
      if (this.$store.state.sum % 2 != 0) {
        this.$store.commit("a/addSum", this.num);
      }
    },
    waitSum() {
      setTimeout(() => {
        this.$store.commit("a/addSum", this.num);
      }, 1000);
    },
    addSu() {
      console.log("加1");
      this.$store.commit("a/addSum", this.num);
    },
    descSum() {
      console.log("减1");
      this.$store.commit("a/desc", this.num);
    },
    handleChange(val, a) {
      console.log(val, a);
    },
  },
};
</script>

相关文章

  • VUEX基本介绍,包含实战示例及代码(基于Vue2.X)

    VUEX 1 VUEX基本介绍 1.1 官方API 1.2 什么是vuex 1.3 Vuex使用场景 1、Vuex...

  • 【文档笔记】-Vuex

    什么是vuex? vuex文档: https://vuex.vuejs.org/zh/[https://vuex....

  • vuex配置

    vuex配置 目录 vuex的五个核心 配置vuex vuex持久化 一、vuex五个核心概念 State 定义状...

  • Vuex

    安装Vuex cnpm install vuex --save-dev Vuex是什么? 这是[Vuex的官网](...

  • Vuex

    1.Vuex概述 2.Vuex基本使用 3.使用Vuex完成todo案例 1.Vuex概述 Vuex是实现组件全局...

  • vuex

    Vuex介绍: Vuex官网:http://vuex.vuejs.org/ Vuex是实现数据状态管理的技...

  • vuex+axios 的开发流程记录

    相关文档 vuex: https://vuex.vuejs.org/zh/ 是否有必要使用vuex vuex是vu...

  • 2019-06-07

    import Vue from 'vue'import Vuex from 'vuex'Vue.use(Vuex)...

  • 配置 vuex 和 vuex 本地持久化

    配置 vuex 和 vuex 本地持久化 目录 vuex是什么 vuex 的五个核心概念State 定义状态(变量...

  • vuex

    配置 vuex 和 vuex 本地持久化 目录 vuex是什么 vuex 的五个核心概念State 定义状态(变量...

网友评论

      本文标题:vuex

      本文链接:https://www.haomeiwen.com/subject/xyqqjrtx.html