Pinia持久化插件 pinia-plugin-persistedstate 的基本使用

前言 在Vue项目开发过程中,状态管理是至关重要的环节。随着Pinia的推出,它凭借更简洁直观的API,逐渐成为Vuex的有力替代品。为了进一步简化本地存储的管理,pinia-plugin-persistedstate 插件应运而生,它能够帮助开发者轻松实现状态的持久化。 本文将详细介绍如何使用该插件,并解决在跨项目登录时由于数据格式不一致导致的问题。 安装插件 在项目的根目录下运行以下命令以安装插件: npm i pinia-plugin-persistedstate 随后,在main.ts文件中引入并配置插件: import { createPinia } from 'pinia' import piniaPluginPersistedstate from 'pinia-plugin-persistedstate' const pinia = createPinia() pinia.use(piniaPluginPersistedstate) 完成以上步骤后,Pinia便具备了持久化功能。 基本使用 假设我们需要管理用户信息userInfo,并将其持久化到本地存储中,那么就可以这样实现: import { defineStore } from 'pinia'; export const useUserInfoStore = defineStore('userInfo', { state: () => ({ userInfo: null as any }), persist: true, actions: { setUserInfo(info: any) { this.userInfo = info; } } }); 按照上述配置,用户信息将自动持久化到本地存储中。 仅持久化对象中的特定字段 在实际应用中,开发者可能会面临跨项目登录时出现的兼容性问题。具体场景为:用户在项目A完成登录操作后,随即打开项目B。由于Token的复用机制,项目B会自动完成登录流程。然而,在尝试获取用户信息userInfo时,由于不同项目对数据格式的定义存在差异,导致项目B无法准确获取用户的ID,进而无法基于此ID发起正确的网络请求。具体表现如下: 项目A的数据格式:{ name: 'xiaoming', nick_name: '小明', userID: '9527' } 项目B的数据格式:{ userInfo: { name: 'xiaoming', nick_name: '小明', userID: '9527' } } 由于插件默认将整个state对象存储起来,导致数据多了一层userInfo外壳,从而引发格式不一致的问题。 为了去掉userInfo这一层外壳,我们需要自定义序列化和反序列化逻辑。修改后的Store配置如下: import { defineStore } from 'pinia'; export const useUserInfoStore = defineStore('userInfo', { state: () => ({ userInfo: null as any }), persist: { key: 'userInfo', storage: localStorage, paths: ['userInfo'], // 明确声明要持久化的字段 serializer: { serialize: (state: any) => JSON.stringify(state.userInfo), deserialize: (str: string) => ({ userInfo: JSON.parse(str) }) } } as any, actions: { setUserInfo(info: any) { this.userInfo = info; } } }); 经过上述配置,用户信息的存储结构变为{ name: 'xiaoming', nick_name: '小明', userID: '9527' },不再有额外的userInfo外壳,从而解决了跨项目登录时的格式不一致问题。 ...

2025-04-14 · 2 分钟 · 247 字

基于Selenium实现的必应企业信息抓取工具

1. 前言 因为近期在做一些行业客户群的数据分析,拿到600多条客户信息,需要对其进行分析。由于所在的是To B行业,所以只能先清理掉个人以及没有明确显示企业相关信息的数据。在此之后,需要基于这些企业名单,仔细分析各企业的情况。这可以通过爱企查的批量功能快速导出各企业的情况,但其要求模板中提供的企业名称必须是全称。 因此,我需要把剩下的500多条企业数据的名称一一补全。一开始是打算使用DeepSeek帮我基于关键词把企业名称补全,但反复验证后发现给的数据基本都是瞎编的。无奈之下,我只能一个一个查,具体操作是通过必应搜索关键词,比如“宁德时代”,然后从搜索结果中找到完整的企业名称“宁德时代新能源科技股份有限公司”复制到表格中。 可是,如果只是几十条数据还好,这500多条数据,我要查到猴年马月了,这人工操作实在太繁琐,而且效率太低了,实在忍不了,就想着怎么把这一整个流程实现自动化。 通过DeepSeek查了下,可以使用Python实现,但我没学过Python,不过编程语言嘛,大同小异,就依葫芦画瓢,把教程走一遍。最开始是打算使用必应搜索API实现的,因为必应搜索API可以免费使用,虽然有额度,但对我来说已经足够。但在开通相关服务时需要用到VISA卡,各种操作实在太麻烦了,只能研究其他方案。结果好几个方案验证都行不通,我都打算放弃了,想老老实实一个个查算了,但昨晚回去又研究了一下,发现Selenium可以实现这个需求。 2. 需求描述 有一个.txt文档用来存放关键词,有一个.xlsx表格用来存放输出的结果,表格格式包含两个表头:关键词、企业名称。 代码读取.txt文档中的关键词,依次通过必应搜索,将结果中来自爱企查的信息补充到表格的企业全称中。 对于来自爱企查的结果,去掉后缀“ - 爱企查”,只保留企业名称内容。 因为来自爱企查的结果通常很精准,所以第一次执行时,得到的相关公司信息基本不会有问题。 如果没有来自爱企查的结果,则可能是关键词信息有误,这种情况下只能默认选择第一个出现的企业名称。待全部匹配输出成功后,再通过人工逐一确认。由于这种情况通常不会很多,所以工作量相对较小。 提供一个变量,可以控制是否要获取来自爱企查的结果。如果设置为“是”,则限制结果必须来自爱企查;否则选择必应搜索第一个出现的企业。 3. 项目地址 GitHub - dstweihao/bing-aiqicha-scraper 4. 项目结构 bing-aiqicha-scraper/ ├── keywords.txt # 输入关键词文件 ├── 企业名称清单.xlsx # 输出文件 └── run.py # 主程序 5. 依赖安装 脚本需在Python 3.6及以上版本运行,检查Python版本: python --version 创建虚拟环境: python -m venv .venv source .venv/bin/activate # Windows: .venv\Scripts\activate 安装核心依赖: pip install selenium webdriver-manager pandas openpyxl 其中,各依赖说明如下: 库名称 作用 安装命令 selenium 浏览器自动化控制 pip install selenium webdriver-manager 自动管理浏览器驱动 pip install webdriver-manager pandas 数据处理和Excel导出 pip install pandas openpyxl 增强Excel文件支持 pip install openpyxl 6. 脚本代码 ./bing-aiqicha-scraper/run.py ...

2025-02-22 · 2 分钟 · 254 字

unplugin-vue-router 的基本使用

1. 前言 在Vue3开发过程中,每次创建新的页面都需要注册路由,需要在src/router.ts中新增页面的路径,并将URL路径映射到组件中,如下所示: import { createMemoryHistory, createRouter } from 'vue-router' import HomePageView from './HomePageView.vue' import DevListView from './DevListView.vue' const routes = [ { path: '/', component: HomePageView }, { path: '/DevListView', component: DevListView }, ] const router = createRouter({ history: createMemoryHistory(), routes, }) 虽然看起来工作量不大,但如果页面特别多,就会感到繁琐。即使是微小的改动,如组件名的修改,也需要在路由文件中反复确认,反复如此就会感到不便。为了简化这部分工作,我想到了一个解决方案,那就是开发一个Vue3菜单路由生成工具,只需填写组件的中文名称,根据树形结构生成一个与routes结构相同的数组,然后替换使用即可。但还是觉得不够好,随后想到既然自己能发现这个问题,别人可能早已有了应对方案。接着,我就发现了 unplugin-vue-router 插件。 2. 配置 2.1 安装 npm install -D unplugin-vue-router 2.2 vite.config.ts import VueRouter from 'unplugin-vue-router/vite' export default defineConfig({ plugins: [ VueRouter({ /* options */ }), // ⚠️ Vue must be placed after VueRouter() Vue(), ], }) 2.3 tsconfig.json { "include": [ // other files... "./typed-router.d.ts" ], "compilerOptions": { // ... "moduleResolution": "Bundler", // ... } } 2.4 vite-env.d.ts /// <reference types="unplugin-vue-router/client" /> 3. 应用 3.1 常规方式 因为项目布局是基于Element Plus组件库的<el-container>搭建的,其中对<e-main>进行了处理,<router-view>是 Vue Router 的一个内置组件,用于渲染匹配当前路由的组件,如下所示: ...

2024-12-29 · 2 分钟 · 286 字

组态页面渲染器通过npm包方式使用页面没有渲染成功的问题

前言 在项目开发过程中,计划将组态页面的渲染器集成到组件库,以 npm 包的形式供后续项目模板复用。如此一来,倘若组态页面渲染出现问题,便能简化修复与迭代工作。 遇到问题 采用本地引入方式开发完成后,切换至 npm 包方式使用,此时面包屑可正常显示,然而组态页面部分却呈现空白状态。 分析问题 既然面包屑显示正常,那就表明通过向组件传入 Router 对象进行相关操作并无问题,毕竟面包屑与组态页面共同构成了项目中的具体功能页面。不可能 Router 有问题,面包屑却还能正常显示。 推测组件打包生成 npm 包后,自身未携带 Vue 环境,致使 Vue 内置特殊元素 <component> 渲染失败,此前使用 Pinia 时就碰到过类似情况。 那么,该如何在组件里创建 Vue 环境呢? 要是不使用 <component>,而改用渲染函数来实现会怎样呢? markRaw 的作用是什么? 利用渲染函数实现后,发现打包成 npm 包使用时依旧出现空白,这就说明并非 <component> 的问题,如此一来,问题范围便缩小到组态页面的数据源上了。 对比本地引用和 npm 包两种方式下的数据请求差异,发现使用 npm 包时,存在接口未发起请求的情况,进而定位到问题根源。 问题原因 由于该渲染器是在项目中使用,其请求的 baseURL 是通过 window.location.origin 获取的。在本地引入使用时,本地开发服务器地址为 http://localhost:3000/,并且在 Vue 项目的 vite.config.ts 中已做代理,所以请求正常。但当把渲染器代码移至组件库并以 npm 包方式使用时,它自行获取的请求地址仍是 http://localhost:3000/,并未经过代理处理,致使请求资源的接口异常,最终造成页面空白。 const baseURL = import.meta.env.DEV ? "http://192.168.50.20" : window.location.origin 总结 解决 Bug 的思路仍有待提升,自己还是过于急于求成了。刚察觉到问题的一点苗头,就贸然行事、妄下结论,实在有些武断。一开始认定是 <component> 的问题,就应当采用排除法,不该如此笃定。实际上,只需用简单示例测试一下,便能排除该选项,也不至于耗费大量精力深入研究如何在组件里创建 Vue 环境?如何用渲染函数实现组件?平白浪费了许多时间。 每次解决完一个 Bug 之后都会觉得,这个算啥问题,真的不值一提。可在解决过程中,却常常感到无奈,好几次都差点放弃。原本代码放在项目中使用正常,非要解耦,感觉像是没事找事。不过,最终还是坚持了下来,觉得应该差不多能弄清楚问题所在了。虽说花费的时间不太划算,就如同这篇文章写得好似没什么价值一般,但总结一下解决 Bug 的心路历程,相信还是会有所收获的。积累到一定程度,便能为自己提供更多面对问题时的视角与启发。 ...

2024-12-20 · 1 分钟 · 77 字

Web应用实现在手机端访问和使用方案

1. 背景 当前的后台管理系统主要负责云平台和云服务器的管理,并且是以Web应用的形式在使用。但是,当出现服务器紧急情况或需要进行平台注册审核时,如果这些任务发生在非工作时间,例如在通勤路上,我们就无法使用PC浏览器进行访问和操作,这显然是不方便的。另外,由于后台管理系统仅供内部人员使用,我们只需要它能满足基本的查看和配置需求,对于便利性和美观性并没有太高要求。因此,将Web端的所有功能移植到手机端并开发一个App,显然很不划算。毕竟,每当Web端功能迭代时,App端也需要同步更新,这意味着同一功能需要实现两次,所以,开发App的方案就不考虑了。 2. 方案 2.1 方案一:使用手机Edge、Firefox浏览器访问使用【推荐】 使用手机通过Edge或Firefox浏览器访问时,设置为“查看桌面网站”(Firefox中称为桌面版网站开关),即可浏览平台的完整布局,并通过手势放大和缩小来居中展示所需内容,操作便捷。 可将后台管理系统的管理平台添加到手机主屏幕,实现快速访问。 以TDesign页面模板演示效果。 2.2 方案二:当前页面 + 全屏 创建一个专为手机端使用的手机端菜单,仅显示关注页面,手机端访问时读取该菜单显示。 利用@media媒体查询调整各页面布局,例如筛选条件等,以避免布局错乱。 默认情况下,只能在手机横屏模式下使用,提供一个全屏按钮,点击后将当前页面全屏化,以争取更多展示空间。 2.3 方案三:远程软件控制电脑访问使用 使用远程软件(如向日葵)访问电脑,然后在手机端通过手势放大和缩小进行操作。效果与方案一相似,但存在以下不足: 输入时需要手动打开键盘。 页面有滚动条时操作繁琐。 连接可能不稳定,画质不佳。 3. 结论 方案一无需额外开发成本,只需在指定手机浏览器上使用即可。 方案二需要额外开发,且最终呈现效果可能不如方案一。 方案三存在上述提到的缺点。 综合考虑,推荐采用方案一。

2024-11-01 · 1 分钟 · 29 字