項目實戰 -- 狀態管理

redux基礎

還記得好久好久之前就想要實現的一個功能嗎?

收起側邊欄折疊菜單,沒錯,現在才實現

因為不是父子通信,所以處理起來相對麻煩一點

可以使用狀態樹或者中間人模式

這就需要會redux了

Redux工作流:

異步就是比同步多一個中間件

使用它有三大原則:

1.單一數據源

2.State是只讀的

3.使用純函數執行修改

首先安裝一下

 npm i --save redux react-redux

創建store

創建一個純函數:CollApsedReducer

// 純函數
export const CollApsedReducer = (prevState={isCollapsed:false
},action)=>{return prevState
}
//導入antd
import { Layout, theme, Button,Menu } from 'antd'
import { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons'
import React, { useState } from 'react'
import { changeConfirmLocale } from 'antd/es/modal/locale'
import { Dropdown, Space } from 'antd'
import { DownOutlined, SmileOutlined } from '@ant-design/icons'
import { Avatar } from 'antd'
import { UserOutlined } from '@ant-design/icons'
import { useNavigate } from 'react-router-dom'
import { connect } from 'react-redux'//從Layout組件中解構Header組件
const { Header } = Layout
function TopHeader(props) {console.log(props)//v6的寫法
const navigate = useNavigate()const [collapsed, setCollapsed] = useState(false)//定義changeCollapsed函數,用于展開/收起側邊欄,通過取反實現const changeCollapsed = () => {setCollapsed(!collapsed)}const { token } = theme.useToken() // 獲取主題 tokenconst { colorBgContainer, borderRadiusLG } = token//使用戶名動態渲染// const {role:{roleName},username} = JSON.parse(localStorage.getItem('token'))//使用戶名動態渲染const {role:{roleName},username} = JSON.parse(localStorage.getItem('token')) || {}; // 確保 tokenData 是一個對象 const items = [{key: '1',label: (<atarget="_blank"rel="noopener noreferrer"href="https://www.antgroup.com">幫{roleName}做模電實驗</a>),},{key: '2',label: (<atarget="_blank"rel="noopener noreferrer"href="https://www.aliyun.com">幫{roleName}上電磁場課</a>),},{key: '3',label: (<atarget="_blank"rel="noopener noreferrer"href="https://www.luohanacademy.com">幫{roleName}輔助面試</a>),},{key: '4',danger: true,label: '要退出嗎',onClick: () => {localStorage.removeItem('token')//使用navigate實現重定向navigate('/login')},},]return (<Headerstyle={{padding: '0 16px',background: colorBgContainer,}}><div style={{ float: 'right' }}>{/* 定義歡迎語 */}<span>歡迎<span style={{color:'blue'}}>{username}</span>回來</span>{/* 定義下拉菜單 */}<Dropdownmenu={{items,}}placement="bottomLeft"arrow><Space size={16} wrap><Avatar src={'/頭像.jpg'} /></Space>{/* <Button>🥺</Button> */}</Dropdown><Dropdownmenu={{items,}}placement="bottom"arrow></Dropdown></div><Buttontype="text"//展開/收起側邊欄,綁定onClick事件icon={collapsed ? (<MenuUnfoldOutlined onClick={changeCollapsed} />) : (<MenuFoldOutlined onClick={changeCollapsed} />)}onClick={() => setCollapsed(!collapsed)}style={{fontSize: '16px',width: 64,height: 64,}}/></Header>)
}const mapStateToProps = ({CollApsedReducer:{isCollapsed}})=>{return{isCollapsed}
}export default connect(mapStateToProps)(TopHeader)

在這里取出狀態

App.jsx:

import { RouterProvider} from 'react-router-dom';
import router from './router/indexRouter';
import './App.css'
import { Provider } from 'react-redux';
import store from './redux/store';function App() {return <Provider store={store}><RouterProvider router={router} />;</Provider>
}export default App;

store.jsx:

import {createStore,combineReducers} from 'redux'
import { CollApsedReducer } from './reducers/CollapsedReducer'const reducer = combineReducers({CollApsedReducer
})
const store = createStore(reducer)export default store

不過現在的createStore已經棄用了

折疊側邊欄

首先開局的時候科文老師的寫法就已經棄用了,問了雞皮替

createStore 已經被官方標記為不推薦使用,在新版 Redux 中推薦使用的是 configureStore 來自 Redux Toolkit(RTK)

先要安裝一下:

npm install @reduxjs/toolkit react-redux

對store.jsx進行重寫:

import { configureStore } from '@reduxjs/toolkit'
import CollApsedReducer from './reducers/CollapsedReducer'  const store = configureStore({reducer: {CollApsedReducer, // 自動組合多個 reducer},
})export default store

reducer(進行redux state的設計,維護了一個布爾值isCollapsed,reducer函數是純函數可以根據傳入的舊的state和action返回新的state,redux會自動把dispatch的action扔進這個函數里):

const initialState = {isCollapsed: false,
}export default function CollApsedReducer(state = initialState, action) {console.log('CollApsedReducer收到 action:', action)switch (action.type) {case 'change_collapsed':return {...state,isCollapsed: !state.isCollapsed,}default:return state}
}

側邊欄:

import React, { useState, useEffect } from'react';
import { Layout, Menu } from 'antd';
import { useNavigate } from'react-router-dom';
import axios from 'axios';
import {UserOutlined,SettingOutlined,UploadOutlined,VideoCameraOutlined,AuditOutlined,FormOutlined,HomeOutlined,
} from '@ant-design/icons';
import { connect } from 'react-redux';
import './index.css';
import { useLocation } from'react-router-dom';const { SubMenu } = Menu;
const { Sider } = Layout;// **手動映射菜單項對應的圖標**
const iconMap = {首頁: <HomeOutlined />,用戶管理: <UserOutlined />,用戶列表: <UserOutlined />,權限管理: <SettingOutlined />,新聞管理: <FormOutlined />,審核管理: <AuditOutlined />,發布管理: <UploadOutlined />,
};function SideMenu(props) {const [menu, setMenu] = useState([]);const location = useLocation(); // 獲取當前的路徑useEffect(() => {axios.get('http://localhost:3000/rights?_embed=children').then((res) => {setMenu(res.data);}).catch((error) => {console.error('獲取菜單數據失敗:', error);// 可根據情況設置默認菜單數據或提示用戶});
}, []);const navigate = useNavigate();const tokenData = JSON.parse(localStorage.getItem('token')) || {};
const { role = {} } = tokenData;
let allRights = [];// 兼容數組結構(普通角色)和對象結構(超級管理員)
if (Array.isArray(role.rights)) {allRights = role.rights;
} else if (typeof role.rights === 'object' && role.rights !== null) {const { checked = [], halfChecked = [] } = role.rights;allRights = [...checked, ...halfChecked];
}const checkPermission = (item) => {// 檢查用戶是否具有訪問權限return item.pagepermisson && allRights.includes(item.key);};const renderMenu = (menuList) => {return menuList.map((item) => {const icon = iconMap[item.title] || <VideoCameraOutlined />; // 默認圖標if (item.children?.length > 0 && checkPermission(item)) {return (<SubMenu key={item.key} icon={icon} title={item.title}>{renderMenu(item.children)}</SubMenu>);}return (checkPermission(item) && (<Menu.Itemkey={item.key}icon={icon}onClick={() => navigate(item.key)}>{item.title}</Menu.Item>));});};//找到路徑const selectKeys = [location.pathname];//分割字符串const openKeys = ['/' + location.pathname.split('/')[1]];return (<Sider trigger={null} collapsible collapsed={props.isCollapsed}><div style={{ display: 'flex', height: '100%', flexDirection: 'column' }}><div className="logo">新聞發布系統</div><div style={{ flex: 1, overflow: 'auto' }}><Menutheme="dark"mode="inline"selectedKeys={selectKeys}defaultOpenKeys={openKeys}>{renderMenu(menu)}</Menu></div></div></Sider>);
}const mapStateToProps = ({CollApsedReducer:{isCollapsed}})=>({isCollapsed})export default connect(mapStateToProps)(SideMenu);
//導入antd
import { Layout, theme, Button,Menu } from 'antd'
import { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons'
import React, { useState } from 'react'
import { changeConfirmLocale } from 'antd/es/modal/locale'
import { Dropdown, Space } from 'antd'
import { DownOutlined, SmileOutlined } from '@ant-design/icons'
import { Avatar } from 'antd'
import { UserOutlined } from '@ant-design/icons'
import { useNavigate } from 'react-router-dom'
import { connect } from 'react-redux'//從Layout組件中解構Header組件
const { Header } = Layout
function TopHeader(props) {console.log(props)//v6的寫法
const navigate = useNavigate()const [collapsed, setCollapsed] = useState(false)//定義changeCollapsed函數,用于展開/收起側邊欄,通過取反實現const changeCollapsed = () => {// 改變state的isCollapsed的值// setCollapsed(!collapsed)// console.log(props)props.changeCollapsed()}const { token } = theme.useToken() // 獲取主題 tokenconst { colorBgContainer, borderRadiusLG } = token//使用戶名動態渲染// const {role:{roleName},username} = JSON.parse(localStorage.getItem('token'))//使用戶名動態渲染const {role:{roleName},username} = JSON.parse(localStorage.getItem('token')) || {}; // 確保 tokenData 是一個對象 const items = [{key: '1',label: (<atarget="_blank"rel="noopener noreferrer"href="https://www.antgroup.com">幫{roleName}做模電實驗</a>),},{key: '2',label: (<atarget="_blank"rel="noopener noreferrer"href="https://www.aliyun.com">幫{roleName}上電磁場課</a>),},{key: '3',label: (<atarget="_blank"rel="noopener noreferrer"href="https://www.luohanacademy.com">幫{roleName}輔助面試</a>),},{key: '4',danger: true,label: '要退出嗎',onClick: () => {localStorage.removeItem('token')//使用navigate實現重定向navigate('/login')},},]return (<Headerstyle={{padding: '0 16px',background: colorBgContainer,}}><div style={{ float: 'right' }}>{/* 定義歡迎語 */}<span>歡迎<span style={{color:'blue'}}>{username}</span>回來</span>{/* 定義下拉菜單 */}<Dropdownmenu={{items,}}placement="bottomLeft"arrow><Space size={16} wrap><Avatar src={'/頭像.jpg'} /></Space>{/* <Button>🥺</Button> */}</Dropdown><Dropdownmenu={{items,}}placement="bottom"arrow></Dropdown></div><Buttontype="text"//展開/收起側邊欄,綁定onClick事件icon={props.isCollapsed ? (<MenuUnfoldOutlined onClick={changeCollapsed} />) : (<MenuFoldOutlined onClick={changeCollapsed} />)}onClick={() => setCollapsed(!collapsed)}style={{fontSize: '16px',width: 64,height: 64,}}/></Header>)
}const mapStateToProps = ({CollApsedReducer:{isCollapsed}})=>{return{isCollapsed}
}const mapDispatchToProps ={changeCollapsed(){return{type:"change_collapsed"}}
}export default connect(mapStateToProps,mapDispatchToProps)(TopHeader)

在App.jsx中還要包一下

import { RouterProvider} from 'react-router-dom';
import router from './router/indexRouter';
import './App.css'
import { Provider } from 'react-redux';
import store from './redux/store';function App() {return <Provider store={store}><RouterProvider router={router} />;</Provider>
}export default App;

?使用 connect() 獲取 Redux 中的 isCollapsed 狀態

使用Redux管控側邊欄狀態的意義:?

?loading加載

現在想給程序加上一個加載的效果做指引

加載中 Spin - Ant Designhttps://ant-design.antgroup.com/components/spin-cn這個的使用就是在數據請求的外面包上loading就好了

這個效果應該是讓數據請求到了就消失

使用一下攔截器捏!

axios/axios: Promise based HTTP client for the browser and node.jshttps://github.com/axios/axios?tab=readme-ov-file#interceptors

?http.jsx:

import axios from "axios";
import store from "../redux/store";
// 對axios做全局配置
axios.defaults.baseURL = "http://localhost:300"// const instance = axios.create();// Add a request interceptor
axios.interceptors.request.use(function (config) {// Do something before request is sent// 顯示loadingstore.dispatch({type:"change_loading",payload:true})return config;}, function (error) {// Do something with request errorreturn Promise.reject(error);});// Add a response interceptor
axios.interceptors.response.use(function (response) {// Any status code that lie within the range of 2xx cause this function to trigger// Do something with response data// 隱藏loadingstore.dispatch({type:"change_loading",payload:false})return response;}, function (error) {store.dispatch({type:"change_loading",payload:false})// Any status codes that falls outside the range of 2xx cause this function to trigger// Do something with response errorreturn Promise.reject(error);});

store.jsx:

import { configureStore } from '@reduxjs/toolkit'
import CollApsedReducer from './reducers/CollapsedReducer'
import LoadingReducer from './reducers/LoadingReducer'const store = configureStore({reducer: {CollApsedReducer, // 自動組合多個 reducerLoadingReducer},
})export default store

Loading.jsx:

const initialState = {isLoading: false,}export default function LoadingReducer(state = initialState, action) {//   console.log('CollApsedReducer收到 action:', action)let {type,payload} = actionswitch (action.type) {case 'change_loading':return {...state,isLoading: payload}default:return state}}

?NewsRouter.jsx:

import SideMenu from "../../components/sandbox/sidemenu";
import TopHeader from '../../components/sandbox/TopHeader'
import { Routes, Route } from'react-router-dom'
import Home from '../../views/sandbox/home/Home'
import RightList from '../../views/sandbox/right-manage/RightList'
import UserList from '../../views/sandbox/user-manage/UserList'
import RoleList from '../../views/sandbox/right-manage/RoleList'
import { Navigate } from'react-router-dom'
import Nopermission from '../../views/sandbox/nopermission/Nopermission'
//引入antd
import { theme, Layout, ConfigProvider, Spin } from 'antd'
import NewsAdd from '../../views/sandbox/news-manage/NewsAdd'
import NewsDraft from '../../views/sandbox/news-manage/NewsDraft'
import NewsCategory from '../../views/sandbox/news-manage/NewsCategory'
import Audit from '../../views/sandbox/audit-manage/Audit'
import AuditList from '../../views/sandbox/audit-manage/AuditList'
import Published from '../../views/sandbox/publish-manage/Published'
import Unpublished from '../../views/sandbox/publish-manage/Unpublished'
import Sunset from '../../views/sandbox/publish-manage/Sunset'
import NewsUpdate from '../../views/sandbox/news-manage/NewsUpdate'
import NewsPreview from '../../views/sandbox/news-manage/NewsPreview'
import { useEffect, useState } from'react'
import axios from 'axios'
import { connect } from "react-redux";//創建一個本地的路由映射表
const LocalRouterMap = {'/home': Home,'/user-manage/list': UserList,'/right-manage/right/list': RightList,'/right-manage/role/list': RoleList,//寫什么新聞列表啊,各種權限啊'/news-manage/add': NewsAdd,'/news-manage/draft': NewsDraft,'/news-manage/category': NewsCategory,'/news-manage/preview/:id':NewsPreview,'/news-manage/update/:id':NewsUpdate,'/audit-manage/audit': Audit,'/audit-manage/list': AuditList,'/publish-manage/published': Published,'/publish-manage/unpublished': Unpublished,'/publish-manage/sunset': Sunset,
}function NewsRouter(props) {// 后端返回的路由映射表const [BackRouteList, setBackRouteList] = useState([])useEffect(() => {Promise.all([axios.get('http://localhost:3000/rights'),axios.get('http://localhost:3000/children'),]).then((res) => {setBackRouteList([...res[0].data, ...res[1].data])})}, [])const tokenData = JSON.parse(localStorage.getItem('token')) || {}; // 確保 tokenData 是一個對象const { role = {} } = tokenData; // 確保 role 是一個對象let rights = []; // 初始化 rights 為一個空數組if (role.rights) {if (Array.isArray(role.rights)) {rights = role.rights;} else if (typeof role.rights === 'object') {// 如果 rights 是對象,提取 checked 和 halfChecked 數組并合并rights = [...(role.rights.checked || []), ...(role.rights.halfChecked || [])];}}// console.log(rights)const checkRoute = (item) => {return LocalRouterMap[item.key] && (item.pagepermisson || item.routepermisson)}const checkUserPermisson = (item) => {const hasPermission = rights.includes(item.key);return hasPermission; }return (<Spin size="large" spinning={props.isLoading}><Routes>{/* 動態渲染路由 */}{BackRouteList.map((item) => {const Component = LocalRouterMap[item.key]// console.log(item.key)if (checkRoute(item) && checkUserPermisson(item)) {return (Component && (<Route path={item.key} key={item.key} element={<Component />} />))}return null})}{/* 首頁重定向 */}<Route path="/" element={<Navigate to="/home" />} />{/* 權限不足頁面 */}{BackRouteList.length > 0 && (<Route path="*" element={<Nopermission />} />)}</Routes></Spin>)
}const mapStateToProps = ({LoadingReducer:{isLoading}})=>({isLoading
})export default connect(mapStateToProps)(NewsRouter)

這樣就實現了一閃而過的加載效果勒?

持久化

本來我們設置了側邊欄,比如我們把側邊欄收起,但是一刷新就會被打回原形,這就涉及到了持久化的概念

我們應該讓redux持久化的存儲在系統中捏

redux持久化的工具:

rt2zz/redux-persist: persist and rehydrate a redux storehttps://github.com/rt2zz/redux-persist進行數據持久化的操作:

import { configureStore } from '@reduxjs/toolkit'
import CollApsedReducer from './reducers/CollapsedReducer'
import LoadingReducer from './reducers/LoadingReducer'import { combineReducers} from 'redux'
import { persistStore, persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage' // defaults to localStorage for webconst persistConfig = {key: 'root',storage: storage,blacklist: ['LoadingReducer']//放在黑名單中的數據不會被持久化
}const reducer = combineReducers({CollApsedReducer,LoadingReducer
})const persistedReducer = persistReducer(persistConfig, reducer)const store = configureStore({reducer:persistedReducer
})
const persistor = persistStore(store)export {store,persistor}

持久化有黑名單白名單的機制,放在黑名單的數據就不會被持久化了

持久化數據的邏輯是,配置redux-persist 的規則,然后進行把兩個小模塊的狀態進行合并,最后使用persistReducer包裝(persistReducer會根據persistConfig給reducer加上存到localStorage的能力)然后是創建store

最后創建persistor,負責在應用初始化的時候把localStorage里面的數據還原到Redux store中

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/78609.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/78609.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/78609.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Go語言之路————指針、結構體、方法

Go語言之路————指針、結構體、方法 前言指針結構體聲明初始化使用組合引用結構體和指針結構體的標簽 方法例子結合結構體總結 前言 我是一名多年Java開發人員&#xff0c;因為工作需要現在要學習go語言&#xff0c;Go語言之路是一個系列&#xff0c;記錄著我從0開始接觸Go…

[創業之路-390]:人力資源 - 社會性生命系統的解構與重構:人的角色嬗變與組織進化論

前言&#xff1a; 人、財、物、信息、機制、流程、制度、方法共同組合了一個持續的消耗資源、持續的價值創造、持續面臨生存與發展、遺傳與變異的社會性生命系統。 "人"是所有社會性生命系統最最基礎性的要素&#xff0c;它彌漫在系統中多維立體空間的不同節點上&am…

JS執行器在UI自動化測試中的應用

前言 在進行UI自動化過程會遇到滾動條下拉、隱藏元素定位、只讀屬性元素的編輯、富文本處理等&#xff0c;此時可以使用JS執行器簡化我們的一些處理操作。 具體應用 JS執行器的使用步驟&#xff1a; 1.先寫個JS腳本&#xff0c;如果需要獲取操作后的值&#xff0c;JS腳本前面…

解析Suna:全球首款開源通用AI智能體

導語&#xff1a; 嘿&#xff0c;哥們兒&#xff0c;最近 AI Agent 這塊兒挺火的&#xff0c;有個叫 Suna 的開源項目冒出來挺快&#xff01;聽說只用了 3 周就開發出來了&#xff0c;但功能上感覺已經能跟那個商業版的 Manus掰掰手腕了。它能幫你搞定瀏覽器自動化、管文件、爬…

模板方法模式:定義算法骨架的設計模式

模板方法模式&#xff1a;定義算法骨架的設計模式 一、模式核心&#xff1a;模板方法定義算法骨架&#xff0c;具體步驟延遲到子類實現 在軟件開發中&#xff0c;經常會遇到這樣的情況&#xff1a;某個算法的步驟是固定的&#xff0c;但具體步驟的實現可能因不同情況而有所不…

淺談Java 內存管理:棧與堆,垃圾回收

在Java編程世界里&#xff0c;內存管理是一項極為關鍵的技能&#xff0c;它就像程序運行背后的“隱形守護者”&#xff0c;默默影響著程序的性能與穩定性。今天&#xff0c;咱們就來簡單學習一下Java內存管理中的兩大核心要點&#xff1a;棧與堆的內存分配機制&#xff0c;以及…

【WebGL小知識】WebGL平臺上不同Json的比較

今天來總結一下WebGL平臺上不同Json插件的差別&#xff0c;話不多說直接開始。 JsonUtility JsonUtility是Unity自帶的Json解析&#xff0c;無需另外安裝插件。 優點&#xff1a; Unity自帶&#xff0c;兼容性好&#xff0c;WebGL平臺可以使用輕量級&#xff0c;性能較好。 …

4.22tx視頻后臺開發一面

總時長大概在一個小時&#xff0c;主要提問C、操作系統、計網以及數據庫等方面&#xff0c;最后兩個算法編程題。 一上來先介紹項目 Linux下的mybash命令處理器和內存池 mybash可以再總結歸納一下&#xff0c;一上來有點緊張沒有條理 內存池是用邊界標識法寫的&#xff0c;…

從StandardMaterial和PBRMaterial到PBRMetallicRoughnessMaterial:Babylon.js材質轉換完全指南

在現代3D圖形開發中&#xff0c;基于物理的渲染(PBR)已成為行業標準。本文將深入探討如何在Babylon.js中將傳統StandardMaterial和PBRMaterial轉換為PBRMetallicRoughnessMaterial&#xff0c;并保持視覺一致性。 為什么需要轉換&#xff1f; PBRMetallicRoughnessMaterial作…

UEditor文檔在Servlet項目上的應用

UEditor 是一款功能強大的富文本編輯器&#xff0c;在項目中應用廣泛。 Ueditor使用 引入 UEditor 下載 UEditor&#xff1a;從 UEditor 官方網站&#xff08;ueditor 官網&#xff09;下載適合項目需求的版本。解壓文件&#xff1a;將下載的壓縮包解壓到項目的靜態資源目錄…

ThinkPHP快速使用手冊

目錄 介紹 安裝&#xff08;windows環境&#xff09; 安裝Composer 安裝ThinkPHP 目錄結構 配置文件 第一個接口&#xff08;Controller層&#xff09; Hello World 自定義Controller 請求參數 獲取查詢參數&#xff08;Get請求&#xff09; 獲取指定請求參數 獲取…

面向 C# 初學者的完整教程

&#x1f9f1; 一、項目結構說明 你的項目大致結構如下&#xff1a; TaskManager/ ├── backend/ │ ├── TaskManager.Core/ // 實體類和接口 │ ├── TaskManager.Infrastructure/ // 數據庫、服務實現 │ └── TaskManager.API/ // We…

Axios 的 GET 和 POST 請求:前端開發中的 HTTP 通信

&#x1f90d; 前端開發工程師、技術日更博主、已過CET6 &#x1f368; 阿珊和她的貓_CSDN博客專家、23年度博客之星前端領域TOP1 &#x1f560; 牛客高級專題作者、打造專欄《前端面試必備》 、《2024面試高頻手撕題》、《前端求職突破計劃》 &#x1f35a; 藍橋云課簽約作者、…

【前端】如何檢查內存泄漏

在實際的場景中&#xff0c;如果觀察到內存持續出現峰值&#xff0c;并且內存消耗一直沒有減少&#xff0c;那可能存在內存泄漏。 使用 Chrome DevTools 來識別內存圖和一些內存泄漏&#xff0c;我們需要關注以下兩個方面&#xff1a; ● 使用性能分析器可視化內存消耗&#xf…

JavaScript的JSON處理Map的弊端

直接使用 Map 會遇到的問題及解決方案 直接使用 Map 會導致數據丟失&#xff0c;因為 JSON.stringify 無法序列化 Map。以下是詳細分析及解決方法&#xff1a; 問題復現 // 示例代碼 const myMap new Map(); myMap.set(user1, { name: Alice }); myMap.set(user2, { name: B…

【數據結構】第五彈——Stack 和 Queue

文章目錄 一. 棧(Stack)1.1 概念1.2 棧的使用1.3 棧的模擬實現1.3.1 順序表結構1.3.2 進棧 壓棧1.3.3 刪除棧頂元素1.3.4 獲取棧頂元素1.3.5 自定義異常 1.4 棧的應用場景1.改變元素序列2. 將遞歸轉化為循環3. 四道習題 1.5 概念分區 二. 隊列(Queue)2.1 概念2.2 隊列的使用2.3…

第七屆能源系統與電氣電力國際學術會議(ICESEP 2025)

重要信息 時間&#xff1a;2025年6月20-22日 地點&#xff1a;中國-武漢 官網&#xff1a;www.icesep.net 主題 能源系統 節能技術、能源存儲技術、可再生能源、熱能與動力工程 、能源工程、可再生能源技術和系統、風力發…

深入解析C++ STL Stack:后進先出的數據結構

一、引言 在計算機科學中&#xff0c;棧&#xff08;Stack&#xff09;作為一種遵循后進先出&#xff08;LIFO&#xff09;?原則的數據結構&#xff0c;是算法設計和程序開發的基礎構件。C STL中的stack容器適配器以簡潔的接口封裝了底層容器的操作&#xff0c;為開發者提供了…

Golang | 自行實現并發安全的Map

核心思路&#xff0c;讀寫map之前加鎖&#xff01;哈希思路&#xff0c;大map化分為很多個小map

Mac 「brew」快速安裝MySQL

安裝MySQL 在 macOS 上安裝 MySQL 環境可以通過Homebrew快速實現&#xff0c;以下是步驟指南&#xff1a; 方法 1&#xff1a;使用 Homebrew 安裝 MySQL 1. 安裝 Homebrew 如果尚未安裝 Homebrew&#xff0c;可以通過以下命令安裝&#xff1a; /bin/bash -c "$(curl -…