【JavaWeb学习】Vuex

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

  • 适用情况:共享
    多个组件依赖于同一状态;
    来自不同组件的行为需要变更同一状态。

1. 工作原理

举例: sum += 2
在这里插入图片描述

2. 环境搭建

  • 安装npm i vuex
    Vue2 中要用 Vuex 的 3 版本npm i vuex@3,Vue3 中要用 Vuex 的4版本(默认);
  • 在 src 文件夹中新建 store 文件夹,在 store 文件夹中新建 index.js 文件,然后进行配置:
// 该文件用于创建 Vuex 中最核心的 store
// 引入 Vue 和 Vuex
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
// 1. 准备 actions, 用于响应组件中的动作
const actions = {
	yytFunction(context,value){
		// context.state.yytData 巴拉巴拉
		context.commit('YYTFUNCTION', value);
	}
};
// 2. 准备 mutations, 用于操作数据(state)
const mutations = {
	YYTFUNCTION(state, value){
		// state.yytData 巴拉巴拉 value 巴拉巴拉
	}
};
// 3. 准备 state, 用于存储数据(state)
const state = {
	yytData: 0
};

// 创建并暴露 store
export default new Vuex.Store({
    actions,
    mutations,
    state
});
  • 引入和使用(main.js)
    进行了import Vuex from 'vuex'Vue.use(Vuex)这两步后,才能在下一步创建Vue实例对象时,传入store配置项;
// 引入 vue
import Vue from 'vue';
// 引入 App组件, 它是所有组件的父组件
import App from './App.vue';
// 引入自己创建的 store
import store from './store/index';

// 关闭 Vue 的生产提示
Vue.config.productionTip = false;

new Vue({
  el:'#app',
  // 将 App 组件放入容器中
  render: h => h(App),
  store,
  beforeCreate(){
    Vue.prototype.$bus = this; // 安装全局事件总线
  }
})
  • 组件中读取vuex中的数据:this.$store.state.sum(js脚本里)或$store.state.sum<template>里)
  • 组件中修改vuex中的数据:this.$store.dispatch('action中的方法名', 数据)this.$store.commit('mutation中的方法名', 数据)
    若没有网络请求或其他业务逻辑,组件中也可以越过actions,即不写dispatch,直接编写commit

2.1. getters配置项

当 state 中的数据需要加工后再使用时,可以用 getters 进行加工。

  • 在 index.js 中追加 getters 配置项
// 4. 准备 getters,用于将 state 中的数据进行加工
const getters = {
    calData(state){
        return state.yytData * 10;
    }
}
// 创建并暴露 store
export default new Vuex.Store({
    actions,
    mutations,
    state,
    getters
});
  • 组件中读取数据$store.getters.calData

2.2. map方法

  • mapState()映射state中的数据为计算属性
computed:{
	// 借助 mapState 生成计算属性sum、name,从 state 中读取数据(对象写法)
	... mapState({sum:'sum', name:'name'}),
	// 借助 mapState 生成计算属性,从 state 中读取数据(数组写法)
	... mapState(['sum', 'name'])
}
  • mapGetters()映射getters中的数据为计算属性
computed:{
	// 借助 mapGetters 生成计算属性bigSum,从 getters 中读取数据(对象写法)
	... mapGetters({bigSum:'bigSum'}),
	// 借助 mapGetters 生成计算属性bigSum,从 getters 中读取数据(数组写法)
	... mapGetters(['bigSum'])
}
  • mapActions()生成与 actions 对话的方法,即包含$store.dispatch(xxx)的函数
methods:{
	// 借助 mapMutations 生成对应的方法,方法中会调用 commit 去联系 mutations (对象写法)
	...mapMutations({increment:'ADD', decrement:'SUBTRACT'})
}
  • mapMutations()生成与 mutations 对话的方法,即包含$store.commit(xxx)的函数
methods:{
	// 借助 mapActions 生成对应的方法,方法中会调用 dispatch 去联系 actions (对象写法)
	...mapActions({incrementOdd:'addOdd', incrementWait:'addWait'})
}

使用mapActionsmapMutations时如果需要传参,那么在模板中绑定事件时就要传递,否则参数是事件对象。

<button @click="increment(n)">+</button>
<button @click="decrement(n)">-</button>
<button @click="incrementOdd(n)">当前求和为奇数时加</button>
<button @click="incrementWait(n)">等一会儿再加</button>

2.3. 多组件共享数据 - 模块化 & 命名空间

  • 目的:让代码更好维护,让多种数据分类更加明确;
  • 修改index.js,将完成每个功能的配置拆分出来,并开启命名空间
// index.js
import Vue from 'vue';
import Vuex from 'vuex';
import countOptions from './countOptions';
import personOptions from './personOptions';

Vue.use(Vuex);

// 创建并暴露 store
export default new Vuex.Store({
    modules:{
        c:countOptions,
        p:personOptions
    }
});
// countOptions.js
export default {
    namespaced:true,
    actions:{
        addOdd(context,value){
            if(context.state.sum % 2){
                context.commit('ADD', value);
            }
        },
        addWait(context,value){
            setTimeout(()=>{
                context.commit('ADD', value);
            }, 500);
        }
    },
    mutations:{
        ADD(state, value){
            state.sum += value;
        },
        SUBTRACT(state, value){
            state.sum -= value;
        }
    },
    state:{
        sum:0,  // 当前的和
        name:'kirlant'
    },
    getters:{
        bigSum(state){
            return state.sum * 10;
        }
    }
};
// personOptions.js
import axios from 'axios'
import { nanoid } from 'nanoid';
// 人员列表相关配置
export default {
    namespaced:true,
    actions:{
        addPersonL(context,value){
            if(value.name.indexOf('l') === 0){
                context.commit('ADD_PERSON', value);
            }else{
                alert('添加的人要姓l嗷');
            }
        },
        addPersonServer(context){
            axios.get('https://api.uixsj.cn/hitokoto/get?type=social').then(
                response=>{
                    context.commit('ADD_PERSON', {id:nanoid(), name:response.data})
                },error=>{
                    console.log('出错了嗷. ',error);
                }
            )
        }
    },
    mutations: {
        ADD_PERSON(state, value){
            state.personList.unshift(value);
        }
    },
    state:{
        personList:[
            {id:'001', name:'yyt'},
            {id:'002', name:'lyl'}
        ]
    },
    getters:{
        firstPersonName(state){
            return state.personList[0].name;
        }
    }
};
  • 开启命名空间后,组件中读取state数据:
// 直接读
this.$store.state.c.sum
// 借助 mapState 读
...mapState('c',['sum'])
  • 开启命名空间后,组件中读取getters数据:
// 直接读
this.$store.getters['p/firstPersonName'];
// 借助 mapGetters读
...mapGetters('p',['firstPersonName'])
  • 开启命名空间后,组件中调用dispatch
// 直接读
this.$store.dispatch('c/addOdd', value);
// 借助 mapActions读
...mapActions('c', {incrementOdd:'addOdd', incrementWait:'addWait'})
  • 开启命名空间后,组件中调用commit
// 直接读
this.$store.commit('p/ADD_PERSON', pObj);
// 借助 mapMutations读
...mapMutations('c', {increment:'ADD', decrement:'SUBTRACT'})
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值