Vue2学习之第五章——vuex

理解vuex

vuex 是什么

  1. 专门在 Vue 中实现集中式状态(数据)管理的一个 Vue 插件,对 vue 应
    用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方
    式,且适用于任意组件间通信。
  2. Github 地址:https://github.com/vuejs/vuex

什么时候使用 Vuex

  1. 多个组件依赖于同一状态
  2. 来自不同组件的行为需要变更同一状态

Vuex 工作原理图

Vue2学习之第五章——vuex_第1张图片

安装vuex

终端输入npm i vuex@3
注意:vuex3在vue2中使用,vuex4在vue3中使用

搭建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
    })
    

基本使用

  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

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

四个map方法的使用

首先通过import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'引入

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

    computed: {
        //借助mapState生成计算属性:sum、school、subject(对象写法)
         ...mapState({sum:'sum',school:'school',subject:'subject'}),
             
        //借助mapState生成计算属性:sum、school、subject(数组写法)
        ...mapState(['sum','school','subject']),
    },
    
  2. 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生成:jiaOdd、jiaWait(数组形式)
        ...mapActions(['jiaOdd','jiaWait'])
    }
    
  4. mapMutations方法:用于帮助我们生成与mutations对话的方法,即:包含$store.commit(xxx)的函数

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

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

模块化+命名空间

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

  2. 修改store.js

     // 该文件用于创建Vuex中最为核心的store
     
     // 引入vuex
     import Vue from 'vue'
     // 引入Vuex
     import Vuex from 'vuex'
     // 引入求和相关的配置
     import countOptions from './count'
     // 引入人员管理相关的配置
     import personOptions from './person'
     import axios from 'axios'
     import {nanoid} from 'nanoid'
     // 使用Vuex插件
     Vue.use(Vuex)
     
     // 求和相关的配置
     const countAbout = {
         namespaced:true,//开启命名空间
         actions:{
             jiaOdd(context,value){
                 console.log('jiaOdd被调用了');
                 if(context.state.sum % 2){
                     context.commit('JIA',value)
                 }
             },
             jiaWait(context,value){
                 console.log('jiaWait被调用了');
                 setTimeout(()=>{
                     context.commit('JIA',value)
                 },500)
             },
         },
         mutations:{
             JIA(state,value){
                 state.sum += value
             },
             JIAN(state,value){
                 state.sum -= value
             },
         },
         state:{
             sum:0,
             school:'bilibili',
             subject:'前端',
         },
         getters:{
             bigSum(state){
                 return state.sum * 10;
             }
         }
     }
     
     // 人员管理相关的配置
     export default {
         namespaced:true,//开启命名空间
         actions:{
             addPersonWang(context,value){
                 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.message)
                     }
                 )
             }
         },
         mutations:{
             ADD_PERSON(state,value){
                 state.personList.unshift(value)
             },
         },
         state:{
             personList:
             [
                 {id:'1',name:'张三'}
             ]
         },
         getters:{
             firstPersonName(state){
                 return state.personList[0].name
             }
         }
     }
     
     // 创建并暴露store
     export default new Vuex.Store({
         modules:{
             countAbout:countOptions,
             personAbout:personOptions,
         }
     })
    

注意:每个模块都需要开启命名空间,添加namespaced:true开启,默认为false。

  1. 开启命名空间后,组件中读取state数据:

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

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

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

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

modules的使用(配合模块化)

  1. 包含多个 module
  2. 一个 module 是一个 store 的配置对象
  3. 与一个组件(包含有共享数据)对应
// 该文件用于创建Vuex中最为核心的store

// 引入vuex
import Vue from 'vue'
// 引入Vuex
import Vuex from 'vuex'
// 引入求和(countAbout)相关的配置
import countOptions from './count'
// 引入人员管理(personAbout)相关的配置
import personOptions from './person'
// 使用Vuex插件
Vue.use(Vuex)
// 创建并暴露store
export default new Vuex.Store({
    modules:{
        countAbout:countOptions,
        personAbout:personOptions,
    }
})

你可能感兴趣的:(学习,vue.js,javascript)