Vue3.5 企业级管理系统实战(八):Sidebar组件开发 2

本篇通过 Pinia 实现侧边栏(Sidebar)的展开收起功能,并通过 Pinia 实现展开状态的持久化。

1 安装 Pinia Persistedstate

Pinia 是 Vue.js 的状态管理库,而 pinia-plugin-persistedstate 是一个针对 Pinia 的插件,它能让 Pinia 管理的状态实现持久化存储。在前端开发中,持久化状态意味着即使页面刷新或用户关闭浏览器重新打开,某些关键状态依然能保持不变,极大提升用户体验。比如侧边栏的展开或收起状态,用户设置后希望再次访问页面时依然保持之前的设置。使用以下命令进行安装:

pnpm install pinia-plugin-persistedstate

2 在 main.ts 中使用

在 main.ts 中引入持久化插件 pinia-plugin-persistedstate,通过pinia.use(piniaPluginPersistedstate) 这行代码,将该插件应用到 Pinia 实例中。这样,后续定义的 Store 中的状态,只要按照插件规则配置,就能实现持久化存储。代码如下:

//main.ts
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import "normalize.css/normalize.css";
import { createPinia } from "pinia";
import element from "./plugins/element";
import piniaPluginPersistedstate from "pinia-plugin-persistedstate";
// import ElementPlus from "element-plus";
// import "element-plus/dist/index.css";
import "@/style/index.scss";
import "uno.css";
const app = createApp(App);
const pinia = createPinia();
pinia.use(piniaPluginPersistedstate); // 安装持久化插件
app.use(router);
app.use(pinia);
app.use(element);
// app.use(ElementPlus);
app.mount("#app");

3 配置 Pinia 和持久化插件

在 src 目录下创建 stores 文件夹,并在其中创建 app.ts 文件,代码如下:

//src/stores/app.ts// 使用defineStore定义名为'app'的store
export const useAppStore = defineStore("app",() => {//定义响应式状态const state = reactive({sidebar: {opened: true}// ...// theme});//计算属性,方便获取sidebar状态const sidebar = computed(() => state.sidebar);//切换侧边栏展开状态的函数const toggleSidebar = () => {state.sidebar.opened = !state.sidebar.opened;};return { state, sidebar, toggleSidebar };},{//持久化配置persist: {storage: window.localStorage,//使用window.localStorage存储状态pick: ["state.sidebar"]//只持久化state.sidebar这个属性}}
);

注:state 必须导出,否则无法使用

在 Store 的定义中,通过 persist 选项来配置持久化相关参数。storage 指定了存储方式,这里使用window.localStorage,意味着状态会存储在浏览器的本地存储中。pick 数组指定了要持久化的具体状态属性,这里只选择了state.sidebar,即只对侧边栏的展开状态进行持久化。如果有多个状态需要持久化,可以在pick数组中添加更多属性路径。

4 创建 Hamburger 组件

在 src/components 下创建 Hamburger 文件夹,其下创建 index.vue 文件,代码如下:

//src/components/Hamburger/index.vue
<template><div class="hamburger-container"><!-- svg-icon组件,用于显示菜单图标,根据collapse状态添加旋转类名 --><svg-iconicon-name="ant-design:bars-outlined"custom-class="hamburger":class="{ 'rotate-180': collapse }"@click="handleClick"></svg-icon></div>
</template><style scoped lang="scss">
.hamburger-container {@apply leading-[50px] float-left cursor-pointer px-10px hover:(bg-black/5);
}
.hamburger {@apply w-30px h-30px transition-transform duration-300;
}
</style><script lang="ts" setup>
// 定义组件props,接收collapse状态
const { collapse } = defineProps({collapse: {type: Boolean,default: false}
});
// 定义组件事件emit,用于触发toggleCollapse事件
const emit = defineEmits<{ (e: "toggleCollapse"): void }>();
// 点击处理函数,触发toggleCollapse事件
const handleClick = () => {emit("toggleCollapse");
};
</script>

5 创建 Navbar 组件

在 src/layout/components  文件夹下创建 Navbar.vue,代码如下:

//src/layout/components/Navbar.vue
<template><div class="navbar" flex><!-- hamburger组件,绑定toggleCollapse事件和collapse状态 --><hamburger@toggleCollapse="toggleSidebar":collapse="sidebar.opened"></hamburger></div>
</template><style scoped lang="scss">
.navbar {@apply h-[var(--navbar-height)];
}
</style><script lang="ts" setup>
import { useAppStore } from "@/stores/app";
// 获取app store中的toggleSidebar和sidebar状态
// 在解构的时候要考虑值是不是对象,如果非对象解构出来就 丧失响应式了
const { toggleSidebar, sidebar } = useAppStore();
</script>

6 修改 Sidebar 组件

修改 src/layout/components/Sidebar/index.vue,使用 pinia 存储的值,代码如下:

//src/layout/components/Sidebar/index.vue
<template><el-menurouterclass="sidebar-container-menu":default-active="defaultActive":background-color="variables.menuBg":text-color="variables.menuText":active-text-color="variables.menuActiveText":collapse="sidebar.opened"><el-menu-item index="/dashboard"><el-icon><setting /></el-icon><template #title>Navigator</template></el-menu-item></el-menu>
</template><script lang="ts" setup>
import { useAppStore } from "@/stores/app";
import variables from "@/style/variables.module.scss";const route = useRoute();
const { sidebar } = useAppStore();
const defaultActive = computed(() => {return route.path;
});
</script>
<style scoped></style>

7 修改 layout 

修改 layout/index.vue,代码如下:

//src/layout/index.vue
<template><div class="app-wrapper"><div class="sidebar-container"><sidebar></sidebar></div><div class="main-container"><div class="header"><!--  上边包含收缩的导航条 --><navbar></navbar></div><div class="app-main"><router-view></router-view></div></div></div>
</template>
<style lang="scss" scoped>
.app-wrapper {@apply flex w-full h-full;.sidebar-container {// 跨组件设置样式@apply bg-[var(--menu-bg)];:deep(.sidebar-container-menu:not(.el-menu--collapse)) {@apply w-[var(--sidebar-width)];}}.main-container {@apply flex flex-col flex-1;}.header {@apply h-84px;.navbar {@apply h-[var(--navbar-height)] bg-yellow;}.tags-view {@apply h-[var(--tagsview-height)] bg-blue;}}.app-main {@apply bg-cyan;min-height: calc(100vh - var(--tagsview-height) - var(--navbar-height));}
}
</style>

 至此,就实现了侧边栏的展开收起及展开收起状态的持久化,页面效果如下:

下一篇将继续探讨菜单组件,敬请期待~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/30379.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

驱动 AI 边缘计算新时代!高性能 i.MX 95 应用平台引领未来

智慧浪潮崛起&#xff1a;AI与边缘计算的时代 正悄然深植于我们的日常生活之中&#xff0c;无论是火热的 ChatGPT 与 DeepSeek 语言模型&#xff0c;亦或是 Meta 智能眼镜&#xff0c;AI 技术已经无形地影响着我们的生活。这股变革浪潮并未停歇&#xff0c;而是进一步催生了更高…

vue3 vite项目安装eslint

npm install eslint -D 安装eslint库 npx eslint --init 初始化配置&#xff0c;按项目实际情况选 自动生成eslint.config.js&#xff0c;可以添加自定义rules 安装ESLint插件 此时打开vue文件就会标红有问题的位置 安装prettier npm install prettier eslint-config-pr…

【RocketMQ】二、架构与核心概念

文章目录 1、发布订阅模型2、角色3、工作流程4、RocketMQ的架构4.1 RocketMQ4.x版本4.2 RocketMQ5.0版本 1、发布订阅模型 几乎所有主流MQ产品&#xff0c;都是发布订阅模型&#xff08;Pub/Sub模型&#xff09;&#xff0c;是生产者和消费者进行基于主题Topic的消息传送 在这…

vue3 遇到babel问题(exports is not defined) 解决方案

由于我在引用ant-design-vue插件&#xff0c;于是产生了下图的问题。 1.问题分析 Babel 是一个 JavaScript 编译器&#xff0c;主要用于&#xff1a;将 ES6 代码转译为 ES5 代码&#xff0c;以兼容旧版浏览器。处理模块化语法&#xff08;如 import/export&#xff09;。 2.解…

【笔记】STM32L4系列使用RT-Thread Studio电源管理组件(PM框架)实现低功耗

硬件平台&#xff1a;STM32L431RCT6 RT-Thread版本&#xff1a;4.1.0 目录 一.新建工程 二.配置工程 ​编辑 三.移植pm驱动 四.配置cubeMX 五.修改驱动文件&#xff0c;干掉报错 六.增加用户低功耗逻辑 1.设置唤醒方式 2.设置睡眠时以及唤醒后动作 ​编辑 3.增加测试命…

数据结构篇——串(String)

一、引入 在计算机中的处理的数据内容大致可分为以整形、浮点型等的数值处理和字符、字符串等的非数值处理。 今天我们主要学习的就是字符串数据。本章主要围绕“串的定义、串的类型、串的结构及其运算”来进行串介绍与学习。 二、串的定义 2.1、串的基本定义 串&#xff08;s…

STM32F4 UDP组播通信:填一填ST官方HAL库的坑

先说写作本文的原因&#xff0c;由于开项目开发中需要用到UDP组播接收的功能&#xff0c;但是ST官方没有提供合适的参考&#xff0c;使用STM32CubeMX生成的代码也是不能直接使用的&#xff0c;而我在网上找了一大圈&#xff0c;也没有一个能够直接解决的方案&#xff0c;deepse…

考研数一非数竞赛复习之Stolz定理求解数列极限

在非数类大学生数学竞赛中&#xff0c;Stolz定理作为一种强大的工具&#xff0c;经常被用来解决和式数列极限的问题&#xff0c;也被誉为离散版的’洛必达’方法&#xff0c;它提供了一种简洁而有效的方法&#xff0c;使得原本复杂繁琐的极限计算过程变得直观明了。本文&#x…

MWC 2025 | 紫光展锐与中国联通联合发布5G eSIM 平板

2025 年 3 月 3 日至 6 日&#xff0c;在全球移动通信行业的年度盛会 —— 世界移动通信大会&#xff08;MWC 2025&#xff09;上&#xff0c;紫光展锐联合中国联通重磅发布了支持eSIM的5G平板VN300E。 该产品采用紫光展锐T9100高性能5G SoC芯片平台&#xff0c;内置8 TOPS算力…

MySQL进阶-关联查询优化

采用左外连接 下面开始 EXPLAIN 分析 EXPLAIN SELECT SQL_NO_CACHE * FROM type LEFT JOIN book ON type.card book.card; 结论&#xff1a;type 有All ,代表着全表扫描&#xff0c;效率较差 添加索引优化 ALTER TABLE book ADD INDEX Y ( card); #【被驱动表】&#xff0…

大模型gpt结合drawio绘制流程图

draw下载地址 根据不同操作系统选择不同的安装 截图给gpt 并让他生成drawio格式的&#xff0c;选上推理 在本地将生成的内容保存为xml格式 使用drawio打开 保存的xml文件 只能说效果一般。

2025-03-08 学习记录--C/C++-C 语言 判断一个数是否是完全平方数

C 语言 判断一个数是否是完全平方数 使用 sqrt 函数计算平方根&#xff0c;然后判断平方根的整数部分是否与原数相等。 #include <stdio.h> #include <math.h>int isPerfectSquare(int num) {if (num < 0) {return 0; // 负数不是完全平方数}int sqrtNum (int)…

Java高频面试之集合-07

hello啊&#xff0c;各位观众姥爷们&#xff01;&#xff01;&#xff01;本baby今天来报道了&#xff01;哈哈哈哈哈嗝&#x1f436; 面试官&#xff1a;ArrayList 和 Vector 的区别是什么&#xff1f; ArrayList 与 Vector 的区别详解 ArrayList 和 Vector 都是 Java 中基于…

《原型链的故事:JavaScript 对象模型的秘密》

原型链&#xff08;Prototype Chain&#xff09; 是 JavaScript 中实现继承的核心机制。每个对象都有一个内部属性 [[Prototype]]&#xff08;可以通过 __proto__ 访问&#xff09;&#xff0c;指向其原型对象。每个对象都有一个原型&#xff0c; 原型本身也是一个对象&#xf…

第11章 web应用程序安全(网络安全防御实战--蓝军武器库)

网络安全防御实战--蓝军武器库是2020年出版的&#xff0c;已经过去3年时间了&#xff0c;最近利用闲暇时间&#xff0c;抓紧吸收&#xff0c;总的来说&#xff0c;第11章开始学习利用web应用程序安全&#xff0c;主要讲信息收集、dns以及burpsuite&#xff0c;现在的资产测绘也…

【redis】全局命令set、get、keys

生产环境 未来在工作中会涉及到的几个环境&#xff1a; 办公环境&#xff08;入职后&#xff0c;公司给你发个电脑&#xff09;开发环境 有的时候&#xff0c;开发环境和办公环境是一个&#xff08;一般做前端和做客户端&#xff09;有的时候&#xff0c;开发环境是一个单独的…

Paper Reading | AI 数据库融合经典论文回顾

人工智能&#xff08;AI&#xff09;和数据库&#xff08;DB&#xff09;在过去的50年里得到了广泛的研究&#xff0c;随着数据库近年来的不断发展&#xff0c;数据库开始与人工智能结合&#xff0c;数据库和人工智能&#xff08;AI&#xff09;可以相互促进。一方面&#xff0…

Linux上位机开发(开篇)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 传统的上位机开发&#xff0c;一般都是默认pc软件开发。既然是pc软件&#xff0c;一般来说都是基于windows平台开发。开放的框架&#xff0c;无非是…

最长递增子序列--蓝桥oj3046拍照

题目链接 arr[] 1700 1701 1702 1703 1704 1705 dp1[] 1 2 3 4 5 6 dp2[] 6 5 4 3 2 1 sum[]dp1[]dp2[] sum[] 7 7 7 7 7 7 7是最大的倒叙和正序的…

upload-labs文件上传

第一关 上传一个1.jpg的文件&#xff0c;在里面写好一句webshell 保留一个数据包&#xff0c;将其中截获的1.jpg改为1.php后重新发送 可以看到&#xff0c;已经成功上传 第二关 写一个webshell如图&#xff0c;为2.php 第二关在过滤tpye的属性&#xff0c;在上传2.php后使用b…