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

长宁微信手机网站制作企业管理软件管理系统

长宁微信手机网站制作,企业管理软件管理系统,留下手机号预约看房,安徽省地图文章目录 前言❓ 直接用 localStorage.getItem() 分析🚨 不足点: ✅ 推荐的做法:使用 Zustand persist 插件进行封装📦 安装 persist 插件✅ 改造后的 userStore.ts(推荐风格)✅ 使用方式保持不变&#xff…

文章目录

  • 前言
    • ❓ 直接用 `localStorage.getItem()` 分析
      • 🚨 不足点:
    • ✅ 推荐的做法:使用 Zustand `persist` 插件进行封装
      • 📦 安装 persist 插件
      • ✅ 改造后的 userStore.ts(推荐风格)
      • ✅ 使用方式保持不变:
      • 🔄 它还可以:
    • 🔁 高级进阶:自定义存储引擎(例如 sessionStorage)
    • ✅ 总结1
    • ✅ 目标:三件事一起完成:
    • 📦 1. 安装中间件(如果还没安装)
    • ✨ 2. 改造后的 `userStore.ts`
    • 🔁 3. 支持多标签页同步(比如退出登录)
    • 📚 进阶建议(以后要做时)
    • ✅ 总结2
    • ✅ 目标
    • ✅ 步骤一:封装一个 `broadcast.ts` 工具
    • ✅ 步骤二:修改 `userStore.ts`,结合 `BroadcastChannel`
    • ✅ 步骤三:监听广播消息,全局响应
    • ✅ 效果演示(完整行为)
    • 🔄 可扩展场景(常见)
    • 📌 总结
  • BroadcastService
    • ✅ 第一步:定义类型和服务类
    • ✅ 第二步:定义用户消息类型 & 实例化频道
    • ✅ 第三步:在 `userStore.ts` 中使用统一服务广播
    • ✅ 第四步:在 `main.tsx` 订阅消息,强制同步登录状态
    • 🎉 最终你获得了:
    • 🧩 下一步可扩展示例
      • ✅ 系统通知频道 `notify-channel`


前言

一般在状态管理中,会用localStorage 来持久化 token ,

例如在react 的应用中:**Zustand 中使用原生 localStorage 来持久化 token **


❓ 直接用 localStorage.getItem() 分析

现在的实现方式是:

token: localStorage.getItem('token') || '',
setToken: (token) => {localStorage.setItem('token', token)set({ token })
}

虽然能用,但存在几个不足

🚨 不足点:

问题说明
❌ 副作用写在 Store 内部localStorage 属于浏览器副作用操作,污染了 store 的纯粹性
❌ 不可复用如果将来希望改用 sessionStorageIndexedDB 或 cookie,不易统一切换
❌ 不支持多标签页同步如果多标签页登录/登出,状态不会自动同步
❌ 不支持结构化存储若用户信息是对象,localStorage 只能保存字符串,管理复杂
❌ 不支持持久化插件Zustand 支持 persist 插件,可以自动存取+序列化/反序列化

✅ 推荐的做法:使用 Zustand persist 插件进行封装

Zustand 官方就提供了持久化插件,可以轻松实现持久化并保持 store 的清洁性。


📦 安装 persist 插件

pnpm add zustand-middleware

✅ 改造后的 userStore.ts(推荐风格)

import { create } from 'zustand'
import { persist } from 'zustand/middleware'interface UserState {token: stringsetToken: (token: string) => voidclearToken: () => void
}export const useUserStore = create<UserState>()(persist((set) => ({token: '',setToken: (token) => set({ token }),clearToken: () => set({ token: '' })}),{name: 'user-store', // localStorage keypartialize: (state) => ({ token: state.token }), // 可持久化字段})
)

✅ 使用方式保持不变:

const token = useUserStore(state => state.token)
const setToken = useUserStore(state => state.setToken)

而且内部的持久化逻辑都交给 zustand/middleware 来处理了 ✅


🔄 它还可以:

  • 自动从 localStorage 读取初始化值
  • 支持序列化复杂对象
  • 支持多个状态切片持久化(例如 token、theme、userInfo 分别存储)
  • 支持同步事件监听(例如:退出登录广播)

🔁 高级进阶:自定义存储引擎(例如 sessionStorage)

persist((set) => ({ ... }),{name: 'user-store',storage: {getItem: (key) => sessionStorage.getItem(key),setItem: (key, value) => sessionStorage.setItem(key, value),removeItem: (key) => sessionStorage.removeItem(key),}}
)

✅ 总结1

方法是否推荐说明
原生 localStorage 调用🚫 不推荐无法复用、副作用重、扩展性差
zustand + persist 插件✅ 推荐大厂常用方式,结构清晰、支持扩展和统一管理

✅ 目标:三件事一起完成:

✅ 使用 zustand/persist 插件实现持久化

✅ 支持多标签页 token 同步(退出登录后其他页也退出)

✅ 保持代码整洁,方便后续扩展(支持 userInfo、theme 等)

升级 Zustand 用户状态管理:


📦 1. 安装中间件(如果还没安装)

pnpm add zustand-middleware

✨ 2. 改造后的 userStore.ts

📁 src/store/user.ts

import { create } from 'zustand'
import { persist } from 'zustand/middleware'interface UserState {token: stringsetToken: (token: string) => voidclearToken: () => void
}export const useUserStore = create<UserState>()(persist((set) => ({token: '',setToken: (token) => {set({ token })// 👇 触发多标签页广播(可选)localStorage.setItem('token-updated', Date.now().toString())},clearToken: () => {set({ token: '' })localStorage.setItem('token-updated', Date.now().toString())},}),{name: 'user-store', // localStorage keypartialize: (state) => ({ token: state.token }), // 只存 token})
)

🔁 3. 支持多标签页同步(比如退出登录)

📁 在 src/main.tsx 中监听 storage 事件

window.addEventListener('storage', (event) => {if (event.key === 'token-updated') {const token = localStorage.getItem('user-store')if (token) {const parsed = JSON.parse(token)const current = parsed.state.tokenconst storeToken = useUserStore.getState().tokenif (storeToken && !current) {// token 被清空,触发登出location.href = '/login'}}}
})

🔄 效果:在 A 页退出登录,B 页会立即刷新跳转回 /login


📚 进阶建议(以后要做时)

需求做法
保存 userInfostate.userInfo + partialize 中加上它
使用 sessionStorage替换 persiststorage 为 sessionStorage
Token 自动刷新配合 Axios 拦截器,统一处理 401 逻辑
权限控制加个 roles 字段,配合路由动态控制

✅ 总结2

现在的登录状态管理已经是:

  • 持久化(自动保存/恢复 token)
  • 无副作用(副作用交给中间件处理)
  • 多标签页同步(用户体验拉满)
  • 适合的结构(易扩展、可维护、好调试)

进一步:相比传统的 storage 事件,现代浏览器推荐使用 BroadcastChannel API 来实现多标签页之间的通信,性能更高,功能更强,特别适合多标签页状态同步,如:强制登出、通知刷新、全局消息推送等。


✅ 目标

构建一个 强一致性、主动广播、现代化的多标签页通信机制 来同步登录状态。


✅ 步骤一:封装一个 broadcast.ts 工具

📁 src/utils/broadcast.ts

// 全局广播频道(支持跨页面通信)
export const userChannel = new BroadcastChannel('user-channel')// 消息类型(可扩展)
export type UserChannelMessage =| { type: 'logout' }| { type: 'login'; token: string }| { type: 'sync' } // 预留

✅ 步骤二:修改 userStore.ts,结合 BroadcastChannel

📁 src/store/user.ts

import { create } from 'zustand'
import { persist } from 'zustand/middleware'
import { userChannel } from '@/utils/broadcast'interface UserState {token: stringsetToken: (token: string) => voidclearToken: () => void
}export const useUserStore = create<UserState>()(persist((set) => ({token: '',setToken: (token) => {set({ token })userChannel.postMessage({ type: 'login', token })},clearToken: () => {set({ token: '' })userChannel.postMessage({ type: 'logout' })},}),{name: 'user-store',partialize: (state) => ({ token: state.token }),})
)

✅ 步骤三:监听广播消息,全局响应

📁 在 src/main.tsx 里添加监听器:

import { userChannel } from '@/utils/broadcast'
import { useUserStore } from '@/store/user'// 跨标签页同步响应:强制登录/登出
userChannel.onmessage = (event) => {const { type, token } = event.dataif (type === 'logout') {useUserStore.getState().clearToken()window.location.href = '/login'}if (type === 'login' && token) {useUserStore.getState().setToken(token)}
}

✅ 效果演示(完整行为)

操作行为
登录页面点击登录所有标签页同步设置 token
任意页面点击登出所有标签页立即跳转到 /login,并清除 token
不依赖 localStorage 的副作用或轮询☑️ 性能更好 ☑️ 响应更快 ☑️ 可扩展性更强

🔄 可扩展场景(常见)

应用实现
🔐 Token刷新在一个页中刷新 token 后广播 setToken(token)
🔔 全局提示userChannel.postMessage({ type: 'notify', msg })
🧠 状态同步多 tab 同步 userInfo、theme、unreadCount 等状态

📌 总结

能力BroadcastChannel vs localStorage
多标签页同步✅ 强一致性
支持主动推送
跨域支持❌(同源限制)
性能✅ 高效

BroadcastService

接下来我们封装一个大厂常用的 BroadcastService 服务类,支持:

  • ✅ 统一管理多个频道
  • ✅ 可注册多个监听器,支持解绑
  • ✅ 支持类型安全的广播消息
  • ✅ 支持扩展多个频道(如 user-channelnotify-channel

✅ 第一步:定义类型和服务类

📁 src/utils/broadcast.ts

type MessageHandler<T> = (msg: T) => void// 通用广播服务类
export class BroadcastService<TMessage> {private channel: BroadcastChannelprivate listeners = new Set<MessageHandler<TMessage>>()constructor(channelName: string) {this.channel = new BroadcastChannel(channelName)this.channel.onmessage = (event: MessageEvent<TMessage>) => {this.listeners.forEach((handler) => {try {handler(event.data)} catch (err) {console.error(`[BroadcastService] handler error`, err)}})}}post(msg: TMessage) {this.channel.postMessage(msg)}subscribe(handler: MessageHandler<TMessage>) {this.listeners.add(handler)}unsubscribe(handler: MessageHandler<TMessage>) {this.listeners.delete(handler)}close() {this.channel.close()this.listeners.clear()}
}

✅ 第二步:定义用户消息类型 & 实例化频道

📁 src/utils/channels.ts

import { BroadcastService } from './broadcast'export type UserChannelMessage =| { type: 'login'; token: string }| { type: 'logout' }export const userChannel = new BroadcastService<UserChannelMessage>('user-channel')

✅ 第三步:在 userStore.ts 中使用统一服务广播

📁 src/store/user.ts

import { create } from 'zustand'
import { persist } from 'zustand/middleware'
import { userChannel } from '@/utils/channels'interface UserState {token: stringsetToken: (token: string) => voidclearToken: () => void
}export const useUserStore = create<UserState>()(persist((set) => ({token: '',setToken: (token) => {set({ token })userChannel.post({ type: 'login', token })},clearToken: () => {set({ token: '' })userChannel.post({ type: 'logout' })}}),{name: 'user-store',partialize: (state) => ({ token: state.token })})
)

✅ 第四步:在 main.tsx 订阅消息,强制同步登录状态

📁 src/main.tsx

import { userChannel } from '@/utils/channels'
import { useUserStore } from '@/store/user'userChannel.subscribe((msg) => {if (msg.type === 'logout') {useUserStore.getState().clearToken()location.href = '/login'}if (msg.type === 'login' && msg.token) {useUserStore.getState().setToken(msg.token)}
})

🎉 最终你获得了:

  • 🔄 多标签页同步(性能更高,无需依赖 localStorage)
  • 📦 解耦广播逻辑(支持复用与扩展)
  • 🧠 类型安全(可扩展通知、消息、刷新、Theme 切换等)

🧩 下一步可扩展示例

✅ 系统通知频道 notify-channel

export type NotifyChannelMessage = { type: 'alert'; message: string }
export const notifyChannel = new BroadcastService<NotifyChannelMessage>('notify-channel')// notifyChannel.post({ type: 'alert', message: '你有一条新消息!' })

http://www.cadmedia.cn/news/2649.html

相关文章:

  • 网站建设中最重要的是什么网站优化建设
  • 网站使用手册重庆森林为什么不能看
  • 武汉网站营销优化源码下载百度 安装
  • 用javaweb做网站成都网络营销推广
  • 开封网站建设-中企动力百度直播间
  • 网站一直建设中长沙网站公司品牌
  • 《动态网站建设》 课程考核宁波seo公司排名
  • 什么是软件开发者重庆百度关键词优化软件
  • 益保网做推广网站吗?哪个网站是免费的
  • 做ppt的软件模板下载网站品牌推广营销
  • 中国十大网络安全公司排名天津seo排名
  • 长沙高新区建设局网站中小企业管理培训班
  • 企业网站优化推广怎么做最新国内新闻10条
  • 东莞哪家网站建设专业深圳网站设计制作
  • 网站快速建设保定seo排名优化
  • 重庆最大的网站制作公司郑州网站建设哪家好
  • 网站设计哪家精准客源
  • 建设网站赚广告费是否可行百度关键词seo排名
  • 门户网站是以什么为主今日最新的新闻
  • 高端网站建设公司谷歌浏览器安卓版下载
  • 外贸站群成都网站建设团队
  • 河北建设厅录入业绩的网站如何让百度收录网站
  • 快速做网站的技术十大接单平台
  • 邯郸企业网站建设公司短视频入口seo
  • 深圳东门动漫城西安网站seo公司
  • 网站编程电子书百度高级搜索首页
  • 做网站一定要买服务器么seo的优缺点
  • 音乐网站网页设计站长工具app
  • 四川鼎能建设集团网站如何让自己的网站被百度收录
  • 成都网站建设怎么样宁波seo博客