当前位置: 首页 > news >正文

vite+react+ts如何集成redux状态管理工具,实现持久化缓存

1.安装插件

这里的redux-persist--进行数据的持久化缓存,确保页面刷新数据不会丢失

yarn add react-redux@^9.2.0 redux-persist@^6.0.0 @reduxjs/toolkit@^2.5.1

2.创建仓库文件夹

在项目的src文件夹下创建名为store的文件夹,里面的具体文件如下

features文件夹对应文件如下

features文件夹中存放对应的需要进行状态管理的数据

couterSlice.ts

这里是一个简单的计数器的加减,赋值,清零的一个测试仓库

createSlice中包含的字段

initialState存储的字段

reducers对应useDispatch的分发行为

name仓库的唯一标识

import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import type { RootState } from "../store";// 为 slice state 定义一个类型
interface CounterState {value: number;
}// 使用该类型定义初始 state
const initialState: CounterState = {value: 0,
};export const counterSlice = createSlice({name: "counter",// `createSlice` 将从 `initialState` 参数推断 state 类型initialState,reducers: {increment: (state) => {state.value += 1;},decrement: (state) => {state.value -= 1;},// 使用 PayloadAction 类型声明 `action.payload` 的内容,用于登录,注册等传入具体的参数incrementByAmount: (state, action: PayloadAction<number>) => {state.value += action.payload;},//清零emptyCount: (state, action: PayloadAction<number>) => {state.value = action.payload;},},
});export const { increment, decrement, incrementByAmount, emptyCount } =counterSlice.actions;
// 选择器等其他代码可以使用导入的 `RootState` 类型
export const selectCount = (state: RootState) => state.counter.value;export default counterSlice.reducer;
user.ts

存储用户信息以及模拟登录token的reducer

import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import type { RootState } from "../store";
import {getToken,setToken,getLocal,setLocal,removeToken,removeLocal,
} from "@/utils/token";
import { Local } from "@/enums/Local";interface UserState {token: string | undefined | null;username: string | undefined | null;
}const initialState: UserState = {token: getToken() || undefined,username: getLocal(Local.USER_INFO)?.username || undefined,
};export const userSlice = createSlice({name: "user",initialState,reducers: {setInfo: (state, action: PayloadAction<UserState>) => {state.token = action.payload.token;state.username = action.payload.username;setToken(action.payload.token);setLocal(Local.USER_INFO, { username: action.payload.username });},remove: (state) => {state.token = undefined;state.username = undefined;removeToken();removeLocal(Local.USER_INFO);},},
});export const { setInfo, remove } = userSlice.actions;
// 选择器等其他代码可以使用导入的 `RootState` 类型
export const selectUser = (state: RootState) => state.user;export default userSlice.reducer;

user.ts文件夹下使用了一些方法,补充如下

utils文件夹下的token.ts文件 以及enums文件夹下的Loacl文件如下
import { Local } from "@/enums/Local";
/*** @Description: 生成一个随机token* @Date: 2024-11-20 17:14:19*/
export function generateToken(length: number) {const characters ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";let token = "";for (let i = 0; i < length; i++) {const randomIndex = Math.floor(Math.random() * characters.length);token += characters[randomIndex];}return token;
}/*** @Description: 将token存储到localStorage中* @Date: 2024-11-20 17:15:12*/
export function setToken(token: string) {const expireTime = new Date().getTime() + 24 * 60 * 60 * 1000; // 设置当前时间加上24小时为过期时间const data = {token: token,expire: expireTime,};localStorage.setItem("token", JSON.stringify(data));
}/*** @Description: 从localStorage中获取token* @Date: 2024-11-20 17:15:42*/
export function getToken() {const dataString = localStorage.getItem("token");if (dataString) {const data = JSON.parse(dataString);const currentTime = new Date().getTime();if (currentTime > data.expire) {// 如果过期,则删除tokenremoveToken();return null; // token已过期,返回null}return data.token; // 返回有效的token}return null; // 如果没有token,返回null
}/*** @Description: 将localStorage中的token删除* @Date: 2024-11-20 17:16:02*/
export function removeToken() {localStorage.removeItem("token"); // 删除token
}/*** @Description: 设置本地存储* @Date: 2024-12-05 14:16:45*/
export function setLocal(key: Local, value: any) {localStorage.setItem(key, JSON.stringify(value));
}/*** @Description: 获取本地存储* @Date: 2024-12-05 14:19:02*/
export function getLocal(key: Local) {const dataString = localStorage.getItem(key);if (dataString) {console.log(JSON.parse(dataString));return JSON.parse(dataString);} else {return null;}
}/*** @Description: 清除本地存储* @Date: 2024-12-05 14:19:48*/
export function removeLocal(key: Local) {localStorage.removeItem(key);
}
export enum Local {USER_INFO = "USER_INFO",REDIRECT_PATH = "redirectPath",
}

hook.d.ts

定义这个声明文件,允许将它们导入到任何需要使用的 hooks 的组件文件中,并避免潜在的循环导入的依赖问题。

import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'
import type { RootState, AppDispatch } from './store'// 在整个应用程序中使用,而不是简单的 `useDispatch` 和 `useSelector`
export const useAppDispatch: () => AppDispatch = useDispatch
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector

store.ts仓库入口文件如下

使用persistConfig进行持久化配置,root为存储到本地的名称,没有特别的要求,whiteList白名单,存放的是需要持久化存储的仓库blackList则相反

import { configureStore } from "@reduxjs/toolkit";
import { persistStore, persistReducer } from "redux-persist";
import storage from "redux-persist/lib/storage"; // 默认使用 localStorage
import counterReducer from "./features/couterSlice";
import userReducer from "./features/user";
// ...// 持久化配置
const persistConfig = {key: "root", // 存储的键名storage, // 存储方式whitelist: ["user"], // 需要持久化的reducerblacklist: ["counter"], // 不需要持久化的reducer
};const persistedReducer = persistReducer(persistConfig, userReducer);const store = configureStore({reducer: {counter: counterReducer,user: persistedReducer,},middleware: (getDefaultMiddleware) =>getDefaultMiddleware({serializableCheck: {// 忽略 redux-persist 的持久化 actionignoredActions: ["persist/PERSIST", "persist/REHYDRATE"],},}),
});const persistor = persistStore(store);// 从 store 本身推断出 `RootState` 和 `AppDispatch` 类型
export type RootState = ReturnType<typeof store.getState>;
// 推断出类型: {posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch;export { store, persistor };

在入口文件main.tsx引入store.ts并配置

采取provider上下文的方式实现 数据的传输 使用PersistGate组件对白名单中的reducer进行持久化存储

import { createRoot } from "react-dom/client";
import "./index.css";
import { HashRouter } from "react-router-dom";
import App from "./App.tsx";
import { store, persistor } from "./store/store.ts";
import { Provider } from "react-redux";
import { PersistGate } from "redux-persist/integration/react";createRoot(document.getElementById("root")!).render(<HashRouter><Provider store={store}><PersistGate loading={null} persistor={persistor}><App /></PersistGate></Provider></HashRouter>
);

3.使用仓库

通过useSelector从redux的state中读取对应的值

useSelector((state: any) => state?.'仓库名称'.value)

useDispatch ,用于在组件中分发操作(action),从而更新 Redux store 中的数据。

从对应的reducer中引入对应的分发操作,因为reduxjs/toolkit的特性,再进行传参赋值的时候,不必要再像老版本一样{...旧值,新值}

传参赋值参考emptyCount这一函数等

使用conuterSlice仓库
import { useSelector, useDispatch } from "react-redux";
import {decrement,increment,incrementByAmount,emptyCount,
} from "@/store/features/couterSlice";
import { setInfo, remove } from "@/store/features/user";
import { Button } from "antd";function DefaultPage() {const count = useSelector((state: any) => state?.counter.value);const userInfo = useSelector((state: any) => state?.user);const dispatch = useDispatch();return (<><div><div><ButtonclassName="mr-4"onClick={() => dispatch(emptyCount(0))}type="primary">清零</Button><Button type="primary" onClick={() => dispatch(increment())}>increment增加</Button><div className="mt-2 mb-2">{count}</div><Buttontype="primary"className="mr-4"onClick={() => dispatch(decrement())}>Decrement减少</Button><Buttontype="primary"onClick={() => dispatch(incrementByAmount(count > 0 ? count : 1))}>增加指定值</Button></div></div></>);
}export default DefaultPage;
补充:结合user.ts这一reducer实现鉴权登录。

这里需要封装一个鉴权组件判断是否登录,给需要鉴权登录的组件嵌套上即可

import React from "react";
import { Local } from "@/enums/Local";
import { setLocal } from "@/utils/token";
import { Navigate, useLocation, useNavigate } from "react-router-dom";
import { useSelector } from "react-redux"; // 假设你使用 Redux// 这是一个路由守卫组件,用于检查用户是否登录
const RequireAuth = ({ children }: { children: React.ReactNode }) => {const location = useLocation();const userInfo = useSelector((state: any) => state?.user);// 如果用户未登录,则保存当前路径并重定向到登录页面if (!userInfo?.token) {setLocal(Local.REDIRECT_PATH, location.pathname);return <Navigate to="/login" />;}return children;
};export default RequireAuth;
登录页面

这里在用户名密码都正确后 采用useDispatch调用reducer中的serInfo方法 将用户名和token存储到storage 和 仓库中去,登录成功后重定向到第一次访问的默认页

import { Button, Checkbox, Form, Input, message } from "antd";
import { Local } from "@/enums/Local";
import { generateToken, getLocal, removeLocal } from "@/utils/token";
import { setInfo } from "@/store/features/user";
import { useDispatch } from "react-redux";
import { useNavigate } from "react-router-dom";
import type { FormProps } from "antd";
import "./index.less";function Login() {const [messageApi, contextHolder] = message.useMessage();const myCleft = "c_left";const myCright = "c_right";const userList = [{userName: "admin",password: "123456",},{userName: "student",password: "123456",},
];type FieldType = {username?: string;password?: string;};const dispatch = useDispatch();const navigate = useNavigate();const onFinish: FormProps<FieldType>["onFinish"] = (values) => {console.log("Success:", values);checkInfo(values);};const onFinishFailed: FormProps<FieldType>["onFinishFailed"] = (errorInfo) => {console.log("Failed:", errorInfo);};//判断用户名密码是否正确const checkInfo = (value: FieldType) => {//用户名const userIndex = userList.findIndex((item) => item.userName == value.username);if (userIndex == -1) {messageApi.open({type: "error",content: "用户名错误",duration: 1,});return;} else {const passwordIndex = userList.findIndex((item) => item.password == value.password);if (passwordIndex == -1) {messageApi.open({type: "error",content: "密码错误",duration: 1,});} else {messageApi.open({type: "loading",content: "登录中",duration: 1.5,}).then(() => {messageApi.open({type: "success",content: "登录成功",duration: 1,}).then(() => {handleLogin(value);});});}}};//登录const handleLogin = (value: FieldType) => {const token = generateToken(16);dispatch(setInfo({ token, username: value.username }));// 登录成功后const redirectPath = getLocal(Local.REDIRECT_PATH) || "/";removeLocal(Local.REDIRECT_PATH); // 清除路径navigate(redirectPath, { replace: true }); // 重定向};return (<>{contextHolder}<div className="w-full h-full " style={{ background: "lightgray" }}><div className="w-full h-full flex justify-center items-center"><div className="l_container"><div className="c_left"><div className={`${myCleft}-title`}>欢迎您的到来!</div><div className={`${myCleft}-title`}>WELCOME !</div><div className={`${myCleft}-desc`}>请在右侧输入账号密码,登录您的账号</div></div><div className="c_right"><div className={`${myCright}-title`}>请输入信息!</div><div className={`${myCright}-form`}><Formname="basic"labelCol={{ span: 8 }}wrapperCol={{ span: 16 }}style={{ maxWidth: 600 }}initialValues={{ remember: true }}onFinish={onFinish}onFinishFailed={onFinishFailed}autoComplete="off"><Form.Item<FieldType>label="用户名:"name="username"rules={[{required: true,message: "请输入用户名称!",},]}><Input /></Form.Item><Form.Item<FieldType>label="密码:"name="password"rules={[{required: true,message: "请输入密码!",},]}><Input.Password /></Form.Item><Form.Item label={null}><ButtonclassName="sub_btn"type="primary"size="large"htmlType="submit">登录</Button></Form.Item></Form></div></div></div></div></div></>);
}export default Login;

参考git地址如下:

myReactRouterOnlyRead: 仅供参考

相关文章:

vite+react+ts如何集成redux状态管理工具,实现持久化缓存

1.安装插件 这里的redux-persist--进行数据的持久化缓存&#xff0c;确保页面刷新数据不会丢失 yarn add react-redux^9.2.0 redux-persist^6.0.0 reduxjs/toolkit^2.5.1 2.创建仓库文件夹 在项目的src文件夹下创建名为store的文件夹&#xff0c;里面的具体文件如下 featur…...

文字的力量

不知道以前的时代的年轻人有没有这样的感受。现在我觉得自己是不是出现了认知偏差&#xff0c;发现在很多描写现在的二十几岁年轻人的成长经历的文字下面都会出现很多共鸣&#xff0c;包括我自己也有&#xff0c;就让我有一个错觉:是不是中国所有的和我同龄的年轻人都是这样过来…...

网络空间安全(4)web应用程序安全要点

前言 Web应用程序安全是确保Web应用程序、服务和服务器免受网络攻击和威胁的关键环节。 一、编写安全的代码 输入验证与过滤&#xff1a;确保所有的用户输入都被正确验证和过滤&#xff0c;以防止注入攻击等安全漏洞。开发者应对URL、查询关键字、HTTP头、POST数据等进行严格的…...

openwebUI访问vllm加载deepseek微调过的本地大模型

文章目录 前言一、openwebui安装二、配置openwebui环境三、安装vllm四、启动vllm五、启动openwebui 前言 首先安装vllm&#xff0c;然后加载本地模型&#xff0c;会起一个端口好。 在安装openwebui,去访问这个端口号。下面具体步骤的演示。 一、openwebui安装 rootautodl-co…...

安全测试之五:SQL Server注入漏洞几个实例

示例 1&#xff1a;在 GET 请求中测试 SQL 注入 最简单且有时最有效的情况是针对登录页面进行测试。当登录页面请求用户输入用户名和密码时&#xff0c;攻击者可以尝试输入以下字符串 “ or 11”&#xff08;不包含双引号&#xff09;&#xff1a; https://vulnerable.web.ap…...

计算机毕业设计SpringBoot+Vue.js线上辅导班系统(源码+文档+PPT+讲解)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…...

C#委托(delegate)的常用方式

C# 中委托的常用方式&#xff0c;包括委托的定义、实例化、不同的赋值方式以及匿名委托的使用。 委托的定义 // 委托的核心是跟委托的函数结构一样 public delegate string SayHello(string c);public delegate string SayHello(string c);&#xff1a;定义了一个公共委托类型 …...

《白帽子讲 Web 安全》之移动 Web 安全

目录 摘要 一、WebView 简介 二、WebView 对外暴露 WebView 对外暴露的接口风险 三、通用型 XSS - Universal XSS 介绍 四、WebView 跨域访问 五、与本地代码交互 js 5.1接口暴露风险&#xff1a; 5.2漏洞利用&#xff1a; 5.3JavaScript 与 Native 代码通信 六、Chr…...

【Tourism】Yongzhou

永州市&#xff08;英文&#xff1a;Yongzhou city、Yungchow city&#xff09;是湖南省辖地级市&#xff0c;简称“永”&#xff0c;别称“零陵”或“潇湘”。位于湖南南部&#xff0c;潇、湘二水汇合处&#xff0c;地势三面环山、地貌复杂多样。截至2022年10月&#xff0c;永…...

C语言--预处理详解

预处理详解 1. 预定义符号 C语言设置了一些预定义符号&#xff0c;可以直接使用&#xff0c;预定义符号也是在预处理期间处理的。 __FILE__ //进行编译的源文件__LINE__ //文件当前的行号__DATE__ //文件被编译的日期__TIME__ //文件被编译的时间__STDC__ //如果编译器遵循A…...

不要升级,Flutter Debug 在 iOS 18.4 beta 无法运行,提示 mprotect failed: Permission denied

近期如果有开发者的 iOS 真机升级到 18.4 beta&#xff0c;大概率会发现在 debug 运行时会有 Permission denied 的相关错误提示&#xff0c;其实从 log 可以很直观看出来&#xff0c;就是 Dart VM 在初始化时&#xff0c;对内核文件「解释运行&#xff08;JIT&#xff09;」时…...

Kubespray部署企业级高可用K8S指南

目录 前言1 K8S集群节点准备1.1 主机列表1.2 kubespray节点python3及pip3准备1.2.1. 更新系统1.2.2. 安装依赖1.2.3. 下载Python 3.12源码1.2.4. 解压源码包1.2.5. 编译和安装Python1.2.6. 验证安装1.2.7. 设置Python 3.12为默认版本&#xff08;可选&#xff09;1.2.8. 安装pi…...

基于zookeeper搭建kafka集群

1、什么是kafka Kafka 是一款开源的分布式流处理平台&#xff0c;最初由 LinkedIn 开发&#xff0c;后由 Apache 基金会维护。它被设计用于高吞吐、可扩展的实时数据管道和流处理场景。Kafka 的核心功能包括发布和订阅消息流、持久化存储数据以及实时处理数据流。其架构基于生…...

Linux操作系统5- 补充知识(可重入函数,volatile关键字,SIGCHLD信号)

上篇文章&#xff1a;Linux操作系统5-进程信号3&#xff08;信号的捕捉流程&#xff0c;信号集&#xff0c;sigaction&#xff09;-CSDN博客 本篇Gitee仓库&#xff1a;myLerningCode/l26 橘子真甜/Linux操作系统与网络编程学习 - 码云 - 开源中国 (gitee.com) 目录 一. 可重入…...

PyCharm中通过命令行执行`pip`命令下载到哪里了:虚拟环境目录下

PyCharm中通过命令行执行pip命令下载到哪里了:虚拟环境目录下 在PyCharm中通过命令行执行pip命令安装工具包,包的下载位置取决于多种因素 虚拟环境 如果项目使用了虚拟环境(通常是推荐的做法): Windows:虚拟环境通常位于项目目录下的.venv文件夹(默认情况)或你指定…...

JeeWMS graphReportController.do SQL注入漏洞复现(CVE-2025-0392)

免责申明: 本文所描述的漏洞及其复现步骤仅供网络安全研究与教育目的使用。任何人不得将本文提供的信息用于非法目的或未经授权的系统测试。作者不对任何由于使用本文信息而导致的直接或间接损害承担责任。如涉及侵权,请及时与我们联系,我们将尽快处理并删除相关内容。 0x0…...

部署Joplin私有云服务器postgres版-docker compose

我曾经使用过一段时间 Joplin&#xff0c;官方版本是收费的&#xff0c;而我更倾向于将数据掌握在自己手中。因此&#xff0c;在多次权衡后&#xff0c;我决定自己搭建 Joplin 服务器并进行尝试。 个人搭建的版本与数据库直连&#xff0c;下面是使用 Docker Compose 配置数据库…...

高频 SQL 50 题(基础版)_550. 游戏玩法分析 IV

高频 SQL 50 题&#xff08;基础版&#xff09;_550. 游戏玩法分析 IV select IFNULL(round(count(distinct(restult.player_id))/count(distinct(Activity.player_id)),2),0) as fraction from(select Activity.player_id,Activity.event_datefrom Activity join(select play…...

Redis Redis介绍、安装 - Redis客户端

目录 redis是什么&#xff0c;他的应用场景是什么&#xff1f; Redis的一些主要特点和应用场景&#xff1a; redis的官方网站&#xff1a;Redis redis是键值型数据库&#xff1a;&#xff08;也就是key-value模式&#xff09;&#xff08;跟python的字典很像&#xff09; …...

计算机毕业设计SpringBoot+Vue.js智能无人仓库管理系统(源码+文档+PPT+讲解)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…...

课程《MIT Introduction to Deep Learning》

在Youtubu上&#xff0c;MIT Introduction to Deep Learning (2024) | 6.S191 共8节课&#xff1a; (1) MIT Introduction to Deep Learning (2024) | 6.S191 (2) MIT 6.S191: Recurrent Neural Networks, Transformers, and Attention (3) MIT 6.S191: Convolutional Neural N…...

Linux ls 命令

Linux ls&#xff08;英文全拼&#xff1a; list directory contents&#xff09;命令用于显示指定工作目录下之内容&#xff08;列出目前工作目录所含的文件及子目录)。 语法 ls [-alrtAFR] [name...] 参数 : -a 显示所有文件及目录 (. 开头的隐藏文件也会列出)-d 只列出目…...

苹果廉价机型 iPhone 16e 影像系统深度解析

【人像拍摄差异】 尽管iPhone 16e支持后期焦点调整功能&#xff0c;但用户无法像iPhone 16系列那样通过点击屏幕实时切换拍摄主体。前置摄像头同样缺失人像深度控制功能&#xff0c;不过TrueTone原彩闪光灯系统在前后摄均有保留。 很多人都高估了 iPhone 的安全性&#xff0c;查…...

SpringBoot项目中读取resource目录下的文件(六种方法)

文章目录 一、先获取绝对路径再读取文件(jar包里会获取不到) 方法一&#xff1a;类加载器的getResource().getPath()获取目录路径方法二&#xff1a;类加载器的getResource().getPath()获取文件路径 二、直接获取文件流&#xff08;jar包可用&#xff09; 方法三&#xff1a;Cl…...

人工智能之数学基础:矩阵的范数

本文重点 在前面课程中,我们学习了向量的范数,在矩阵中也有范数,本文来学习一下。矩阵的范数对于分析线性映射函数的特性有重要的作用。 矩阵范数的本质 矩阵范数是一种映射,它将一个矩阵映射到一个非负实数。 矩阵的范数 前面我们学习了向量的范数,只有当满足几个条…...

Vscode通过Roo Cline接入Deepseek

文章目录 背景第一步、安装插件第二步、申请API key第三步、Vscode中配置第四步、Deepseek对话 背景 如何在vscode编译器中使用deepseek&#xff0c;记录下来&#xff0c;方便备查。 第一步、安装插件 在vscode中安装Roo Cline&#xff08;prev.Roo Client&#xff09;插件&…...

一周一个Unity小游戏2D反弹球游戏 - 球反弹的方向

前言 本文将实现当球在球板上反弹时,会根据球板移动的方向来给球施加反弹的力,例如当球板往左移动时反弹球,则球应向左上方反弹,若球板往右移动时反弹球,则球应向右上方反弹。 实现球板的反弹方向逻辑 首先给SpringBoard游戏物体添加上2D的刚体,并设置好对应的参数, 锁定…...

大数据学习(52)-MySQL数据库基本操作

&&大数据学习&& &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 承认自己的无知&#xff0c;乃是开启智慧的大门 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4dd;支持一下博主哦&#x1f91…...

Pico 4 Enterprise(企业版)与Unity的交互-有线串流调试篇

入手了Pico 4 E做VR开发&#xff0c;谁知入了天坑...根据官方文档&#xff0c;尝试了串流助手、企业串流、PICO Developer Center&#xff0c;陷入了各种版本问题、环境问题的陷阱。而且Pico4E的OS自24年12开始就不再更新&#xff0c;头盔中预装的企业串流版本也较低&#xff0…...

40岁开始学Java:Java中单例模式(Singleton Pattern),适用场景有哪些?

在Java中&#xff0c;单例模式&#xff08;Singleton Pattern&#xff09;用于确保一个类只有一个实例&#xff0c;并提供全局访问点。以下是详细的实现方式、适用场景及注意事项&#xff1a; 一、单例模式的实现方式 1. 饿汉式&#xff08;Eager Initialization&#xff09; …...

【基于Raft的KV共识算法】-序:Raft概述

本文目录 1.为什么会有Raft&#xff1f;CAP理论 2.Raft基本原理流程为什么要以日志作为中间载体&#xff1f; 3.实现思路任期领导选举日志同步 1.为什么会有Raft&#xff1f; 简单来说就是数据会随着业务和时间的增长&#xff0c;单机不能存的下&#xff0c;这个时候需要以某种…...

windows下玩转vllm:在wsl下安装vllm后续,设置modelscope作为下载源

文章目录 前言所涉及的之前的关键步骤解决模型权重下载网络不通畅的问题vllm和modelscope整合后的bug附录 ImportError: cannot import name _try_login from modelscope.utils.hf_util 全部报错信息前言 之前,咱们说了,由于windows不支持直接部署vllm,所以要么采用wsl,要…...

redis --- 相关基础知识整理

目录 一、基本1、数据结构2、有序集合的编码1. 压缩列表&#xff08;Ziplist&#xff09;2. 跳跃列表&#xff08;SkipList&#xff09;3. 动态转换机制 二、应用场景三、持久化1、 RDB 持久化2、 AOF 持久化3、 混合持久化&#xff08;RDB AOF&#xff09;4、 RDB和AOF的对比…...

基于Rook的Ceph云原生存储部署与实践指南(下)

#作者&#xff1a;任少近 文章目录 6Ceph资源对像管理6.1查看services6.2查看Jobs6.3 查看deployments.apps6.4查看daemonsets.apps6.5查看configmaps6.6查看clusterroles.rbac.authorization.k8s.io6.7查看clusterrolebindings.rbac.authorization.k8s.io6.8通过cephclusters…...

计算机网络---TCP三握四挥

文章目录 TCPTCP 的核心特点TCP 与 UDP 特性对比TCP 标志位 TCP 的三次握手&#xff08;建立连接&#xff09;TCP 三次握手概述图解 TCP 三次握手为什么需要三次握手&#xff0c;而不是两次为什么要三次握手&#xff0c;而不是四次三次握手连接阶段&#xff0c;最后一次 ACK 包…...

linux基础知识

Linux版本 内核版和开发版 奇数为开发板 偶数为稳定版 Debian 属于自由开源稳定的linux发行版本&#xff0c;可以由用户进行维护&#xff0c;目前被教育机构、商业公司、非盈利组织和政府机构使用 Red Hat Enterprise Linux(RHEL) 由red hat公司开发的开源linux版本 RHEL服…...

快检查达梦库怎么了

扁鹊的弟弟来了 要求5分钟定位达梦数据库问题 #!/bin/bash## content 实例个数 告警日志 实例状态 用户连接 活动会话 锁 集群状态 服务状态 磁盘空间 cpu mem 侦听及日志 ## scope 单机、DW、DSC Linux 多实例 ## example 将脚本保存为d.sh&#xff0c;用root用执行&#…...

Python可视化大框架的研究与应用

## 摘要 随着数据科学和人工智能的快速发展&#xff0c;数据可视化成为了数据分析中不可或缺的一部分。Python作为一种功能强大且易于学习的编程语言&#xff0c;提供了多种可视化工具和库。本文旨在探讨Python可视化的主要框架&#xff0c;分析其特点、应用场景以及未来发展趋…...

【智能音频新风尚】智能音频眼镜+FPC,打造极致听觉享受!【新立电子】

智能音频眼镜&#xff0c;作为一款将时尚元素与前沿科技精妙融合的智能设备&#xff0c;这种将音频技术与眼镜形态完美结合的可穿戴设备&#xff0c;不仅解放了用户的双手&#xff0c;更为人们提供了一种全新的音频交互体验。新立电子FPC在智能音频眼镜中的应用&#xff0c;为音…...

jeecgboot项目idea启动项目(二)

文章目录 一、IntelliJ IDEA1.安装2.配置maven3.配置jdk 二、IDEA启动项目三、IDEA2024.1.4破解 一、IntelliJ IDEA ‌IntelliJ IDEA是一款由JetBrains开发的集成开发环境&#xff08;IDE&#xff09;&#xff0c;主要用于Java和Kotlin编程&#xff0c;但也支持多种其他编程语…...

【计算机网络基础】-------计算机网络概念

1.什么是计算机网络 定义&#xff1a; 图解&#xff1a; 2.最简单的计算机网络 其中&#xff1a; 结点可以是计算机、集线器、交换机、路由器等链路可以是有线链路、无线链路 2.1集线器 2.2交换机 3.互连网&#xff08;internet&#xff09;与 路由器 路由器 与 家用路由…...

MCAL-存储器驱动

存储器驱动由内部EEPROM驱动、内部Flash驱动、RAM测试和Flash测试四部分组成。 (1)内部EEPROM驱动 内部EEPROM驱动提供初始化服务,以及对内部EEPROM的读、写、擦除等操作。该驱动模块一次只能接受一个任务。这意味着在任何给定的时间点,只能有一个操作被处理 (2)内部F…...

爬虫系列之【数据解析之正则】《二》

目录 前言 一、正则基本使用 1.1 导包 1.2 接口方法 1.3 换行匹配问题 二、实战案例 完整代码 前言 在爬虫工作中&#xff0c;我们主要会遇到两种类型的文本数据&#xff1a; JSON格式数据 HTML文档数据 对于JSON字符串数据&#xff0c;通常使用Python的字典操作进行键…...

【每日学点HarmonyOS Next知识】全局调整字体、h5选择框无法取消选中、margin不生效、Length转换为具体值、Prop和link比较

【每日学点HarmnoyOS Next知识】全局调整字体、h5选择框无法取消选中、margin不生效、Length转换为具体值、Prop和link比较 1、HarmonyOS 是否存在统一调整全局字体大小的方法&#xff1f; 是否存在统一调整全局字体大小的方法 可以用动态属性&#xff0c;自定义class实现At…...

ORM Bee V2.5.2.x 发布,支持 CQRS; sql 性能分析;更新 MongoDB ORM分片

Bee, 一个具有分片功能的 ORM 框架. Bee Hibernate/MyBatis plus Sharding JDBC Jpa Spring data GraphQL App ORM (Android, 鸿蒙) 小巧玲珑&#xff01;仅 940K, 还不到 1M, 但却是功能强大&#xff01; V2.5.2 (2025・LTS 版) 开发中... **2.5.2.1 新年 ** 支持 Mong…...

【CVPR2024】基于小波的傅里叶信息交互与频率扩散调整的水下图像恢复

论文信息 题目&#xff1a; Wavelet-based Fourier Information Interaction with Frequency Diffusion Adjustment for Underwater Image Restoration 基于小波的傅里叶信息交互与频率扩散调整的水下图像恢复 源码:https://github.com/ChenzhaoNju/WF-Diff 论文创新点 基于频…...

《今日AI-编程-人工智能日报》

一、AI编程工具与行业动态 OpenAI推出GPT-4.5“猎户座”研究预览版 OpenAI发布了迄今为止“最大、最有知识”的模型GPT-4.5“猎户座”&#xff0c;面向Pro用户开放&#xff0c;并计划下周向Plus用户开放。该模型在自然对话中展现出情感智能&#xff0c;但在编程性能上不及深度研…...

计算机网络---SYN Blood(洪泛攻击)

文章目录 三次握手过程SYN Flood攻击原理防御措施协议层优化网络层拦截系统配置调整 TCP协议是 TCP/IP 协议栈中一个重要的协议&#xff0c;平时我们使用的浏览器&#xff0c;APP等大多使用 TCP 协议通讯的&#xff0c;可见 TCP 协议在网络中扮演的角色是多么的重要。 TCP 协议…...

DeepSeek教unity------UI元素长按响应

主要功能说明&#xff1a; ​长按检测&#xff1a;通过记录指针按下的时间&#xff0c;判断是否达到 longClickTime&#xff0c;从而触发长按事件。​状态管理&#xff1a;使用 StateEnum 枚举管理点击项的当前状态&#xff08;未按下、按下等待长按、长按已触发&#xff09;。…...

virtualbox安装ubuntu,配置静态ip

一.安装virtualbox和ubuntu 在VirtualBox中安装无界面版Ubuntu&#xff08;即Ubuntu Server&#xff09;的步骤如下&#xff1a; 准备工作 下载Ubuntu Server镜像&#xff1a;从Ubuntu官网 https://ubuntu.com/download/server 下载ISO文件。 安装VirtualBox&#xff1a;确保…...