Vuex、Redux状态管理库

目录

状态管理库

单一事实来源:存储更新所有组件状态

Vuex

安装

配置

src->store

index:拆分模块modules

vue2

vue3

main

index【以Conversation模块为例】【拆分state等属性】

store state() { return state; }类似于

vue中data() return{数据对象}:多个组件实例时,新建(return{})/引用同一个(:{})

this.$store=store(工具文件中,如Util.ts)

state:原生读this.$store.state.XXX

Getter:修饰读this.$store.getters.XXX

getter 的参数化

mutations :同步修改

this.$store.commit('set_num');

this.$store.commit('模块名/set_num');

this.$store.commit('set_num',参数...);

函数起名

set_stateNm(局部)

SET_stateNm(全局)

参数类型起名

map

value

payload传递对象

actions:处理异步 -await this.$store.dispatch('模块名/set_num')

内部commit

【官方建议】

读/修饰状态放在computed

mapState 辅助函数映射 Vuex 的状态到Vue实例上,可通过this.直接访问

单模块

多模块

mapGetters

mapMutations:methods

mapActions

状态持久化:vuex-persistedstate插件

将Vuex的状态持久化到本地存储中,解决页面刷新或重新打开应用时状态丢失的问题

Redux

组件

与Vuex区别

使用


状态管理库

// 创建全局变量
window.globalVariable = '这是一个全局变量';

单一事实来源:存储更新所有组件状态

Vuex

图来自What is Vuex? | Vuex

安装

npm install vuex --save

配置

src->store

index:拆分模块modules
vue2
import Vue from 'vue';
import Vuex from 'vuex';
import Conversation from './Conversation';
import App from './App';

//通过 Vue 插件安装 Vuex,并且在全局注册 this.$store,使得在所有组件中都可以访问到 Vuex 的功能
Vue.use(Vuex);

export default new Vuex.Store({
//modules:是一个配置项,用于定义各个模块。
//拆分成多个模块,每个模块可以包含自己的 state、mutations、actions 和 getters
	modules:  {
		Conversation,
		App,
	},
});
vue3
import { createApp } from 'vue';
import { createStore } from 'vuex';

const store = createStore({
  // 配置
});

const app = createApp(App);
app.use(store);
app.mount('#app');

main

import Vue from 'vue';
import App from './App';
import router from './router';
import store from './store'; // 引入我们前面导出的store对象

Vue.config.productionTip = false;

new Vue({
  el: '#app',
  router,
  store, // 把store对象添加到vue实例上
  components: { App },
  template: '<App/>',
});

index【以Conversation模块为例】【拆分state等属性】

store state() { return state; }类似于

vue中data() return{数据对象}:多个组件实例时,新建(return{})/引用同一个(:{})

this.$store=store(工具文件中,如Util.ts)

import state from './state';
import actions from './actions';
import getters from './getters';
import mutations from './mutations';

const store = {
//namespaced: true 可以帮助区分不同模块中的 actions、mutations 和 getters,避免了命名冲突
	namespaced: true,
	state() {
		return state;
	},
	getters,
	mutations,
	actions,
};

export default store;

state:原生读this.$store.state.XXX

this.$store.state.Conversation.moveConversationList

import LRU from 'lru-cache';
import IMGlobalUtil from '@/util/appconfig';

});
// 缓存用户相关的群组基本信息,每条大约640个字符,最多缓存1000条
const groupsCache = new LRU({
	max: IMGlobalUtil.groupsCacheNumber * 640,
});

const state = {
	summaryMsgMap:{},
    groups: groupsCache,
};

export default state;

Getter:修饰读this.$store.getters.XXX

如果模块名称包含特殊字符或者动态获取 getter 名称时,就需要使用数组语法

this.$store.getters['Conversation/searchGroup'](this.search_value);

getter 的参数化

第一个箭头函数作为 Vuex getter 的定义部分,它可以访问到 state 和 getters,并且将参数传递给第二个箭头函数。

  • 第二个箭头函数则形成了一个闭包,可以访问外部函数(第一个箭头函数)的作用域中的 state 和 getters
const getters = {
	//消息未读数
	totalUnReadNum: (state: any, getters: any) => {
		return state.totalUnReadNum;
	},
	//模糊搜索群组
	searchGroup: (state: any, getters: any) => (str: any) => {
		let reg = /^[0-9a-zA-Z\-]+$/;
		str = str.trim();
		let newArr: any = [];
		if (str !== '') {
			state.groups.keys().forEach((key: any) => {
				let item = state.groups.get(key);
				if (item.name.indexOf(str) !== -1) {
					newArr.push(item);
				}
			});
		}
		return newArr;
	},
	//获取群组中某个成员
	getGroupMember: (state: any, getters: any) => (groupId: any, memberId: any) => {
		let group = state.groups.get(groupId);
		if (group && group.memberMap) {
			return group.memberMap[memberId];
		}
	},
};

export default getters;

mutations :同步修改

this.$store.commit('set_num');

this.$store.commit('模块名/set_num');

this.$store.commit('set_num',参数...);

函数起名

  • set_stateNm(局部)
  • SET_stateNm(全局)

参数类型起名

  • map
  • value
  • payload传递对象
const mutations = {
  set_transforMap(state:any,map:any){
		let length = Object.keys(state.transforMap).length;
		//最多存100条
		if(length > 100){
			state.transforMap = {...map}
		}else{
			state.transforMap = { ...state.transforMap, ...map };
		}
	},
	set_lastMsgAi(state: any, value: any) {
		state.lastMsgAi = value;
	},
	set_urgencyList(state: any, payload: any) {
		state.urgencyList = payload;
	},
	//更新网络状态
	UPDATE_NET_STATUS(state: any, value: any) {
		state.netStatus = value;
	},
};

export default mutations;

actions:处理异步 -await this.$store.dispatch('模块名/set_num')

内部commit

方法的形参可以直接将commit解构出来

import * as sessionGroupServer from '@/server/sessionGroup';
const actions = {
	update_sessionGroupList({ state, commit }: any) {
		sessionGroupServer.getGrouping().then((res: any) => {
			if (res && res.length) {
				commit('set_sessionGroupList', res);
				if (
					!res.find((item: any) => {
						return item.groupingKey == state.curSessionGroupKey;
					})
				) {
					commit('set_curSessionGroupKey', 'MIS_grouping_all');
				}
			}
		});
	},
    set_bpm_number({commit}:any){
        bpmNumber().then((res:any)=>{
            if(res){
                commit("set_bpm_number",res)
            }
        }) 
    },
    async set_app_info({commit}:any){
        let res = await  getAppList(1,100);
        if(res){
            commit("set_app_info",res)
        }
        // getAppList(1,100).then((res:any)=>{
        //     if(res){
        //         commit("set_app_info",res)
        //     }
        // })
    }
};

export default actions;

【官方建议】

读/修饰状态放在computed

当 Vuex 中的状态发生变化时,computed 属性会自动更新。这避免了手动监听状态变化并进行手动更新的操作

computed: {
  userName() {
    return this.$store.state.user.name;
  }
}
mapState 辅助函数映射 Vuex 的状态到Vue实例上,可通过this.直接访问
单模块
computed: {
    ...mapState(['name']), // 经过解构后,自动就添加到了计算属性中,此时就可以直接像访问计算属性一样访问它
    ...mapState({ aliasName: 'name' }),  // 赋成别名aliasName,这里接收对象,而不是数组
  }

多模块
//Conversation 模块中的 state.videoMeetingData 映射为当前组件的 videoMeetingData 计算属性。
...mapState('Conversation', {
  videoMeetingData: (state: any) => state.videoMeetingData,
})
mapGetters
...mapGetters(['getMessage']),
...mapGetters({ aliasName: 'getMessage' }),  // 赋别名的话,这里接收对象,而不是数组

mapMutations:methods

<script>
import { mapMutations } from 'vuex';
export default {
  methods: {
    // 注意,mapMutations是解构到methods里面的,而不是计算属性了
    ...mapMutations(['setNumberIsWhat']),
  },
};
</script>

mapActions


import { mapActions } from 'vuex';

  async mounted() {
    await this.setNum({ number: 123 }); // 直接这样调用即可
  },

...mapActions({ setNumAlias: 'setNum' }),   // 赋别名的话,这里接收对象,而不是数组

状态持久化:vuex-persistedstate插件

将Vuex的状态持久化到本地存储中,解决页面刷新或重新打开应用时状态丢失的问题

Redux

redux相当于在顶层组件之上又加了一个组件

组件

  • Action 这是一个用来描述发生了什么事情的对象
  • Reducer 这是一个确定状态将如何变化的地方
  • Store 整个程序的状态/对象树保存在 Store 中
  • View 查只显示 Store 提供的数据

​​

与Vuex区别

Redux比较独立,可以跟很多框架结合使用,不过主要还是跟React配合比较好,也是最常见的React状态管理的库。

在 Vuex 中,有类似于 Redux 的 action 的概念,

但状态变更是通过称为 mutations 的同步函数来处理的,而异步逻辑则需要放在 action 中处理。

使用

//state存储共享数据
function counterReducer(state={count: 0}, action) {//reducer修改state
    switch(action.type){
        case 'inc':
            return {count: state.count + state.payload}
        default:
            return state;
    }
}
const store = createStore(counterReducer)
export default store

这样store对象就可以在其他组件中进行使用了,例如在<Bar>组件中。

import React from 'react'
import './Bar.scss'
import { useSelector,useDispatch } from 'react-redux'
export default function Bar() {
  const count = useSelector((state)=> state.count)//获取共享状态
  const dispatch=useDispatch();//修改共享状态
  const handleClick = () => {
    dispatch({//dispatch触发Reducer,分发action
      type: 'inc',
      payload: 5
    })
  }
  return (
    <div>
     <button onClick={handleClick}>修改count</button>     
     Bar, { count }
    </div>
  )
}

在主模块中进行注册。

import { RouterProvider } from 'react-router-dom'
import router from './router';
import { Provider } from 'react-redux'
import store from './store';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <Provider store={store}>//注册状态管理与React结合,自动完成重渲染
      <RouterProvider router={router}></RouterProvider>
    </Provider>
  </React.StrictMode>
);
  • 8
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值