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

后台管理系统-4-vue3之pinia实现导航栏按钮控制左侧菜单栏的伸缩

文章目录

  • 1 引入pinia
    • 1.1 引入并注册(main.js)
    • 1.2 stores/index.js(pinia示例)
      • 1.2.1 定义一个store
      • 1.2.2 组件中使用这个store
  • 2 pinia实现菜单收缩功能
    • 2.1 stores/index.js(pinia)
    • 2.2 侧边栏(CommonAside.vue)
    • 2.3 导航栏(CommonHeader.vue)
  • 3 状态变更的集中管理
    • 3.1 stores/index.js(pinia)
    • 3.2 导航栏(CommonHeader.vue)
  • 4 附录
    • 4.1 computed
    • 4.2 参考附录

使用pinia进行集中式状态管理,定义一个isCollapse,通过导航栏的按钮修改其值,菜单栏随着其值的变化而展开或伸缩。

1 引入pinia

Pinia是一个专门为Vue.js应用程序设计的状态管理库。
它由Vue.js团队成员开发,作为Vuex的继任者,旨在提供更简洁、更直观的API,并更好地支持TypeScript和组合式API。
作用:用于多个组件共享数据。
安装npm install pinia。

1.1 引入并注册(main.js)

在这里插入图片描述

import { createApp } from 'vue'
import App from './App.vue'
import '@/assets/less/index.less';
import router from './router';import ElementPlus from 'element-plus';
import 'element-plus/dist/index.css';
import * as ElementPlusIconsVue from '@element-plus/icons-vue';const app = createApp(App);import { createPinia } from 'pinia';
const pinia = createPinia();
app.use(pinia);for (const [key, component] of Object.entries(ElementPlusIconsVue)) {app.component(key, component);
}app.use(router);
app.use(ElementPlus);
app.mount('#app');

1.2 stores/index.js(pinia示例)

import { defineStore } from "pinia";
import { ref, computed } from "vue";
function initState(){  }
export const useAllDataStore = defineStore("allData", ()=>{//   ref() 相当于state属性//   computed() 相当于getters//   function() 相当于actionsconst state = ref(initState());return {state}
});

响应式: 使用ref()包装state确保它是响应式的。

1.2.1 定义一个store

在这里插入图片描述

1.2.2 组件中使用这个store

在这里插入图片描述

2 pinia实现菜单收缩功能

(1)收缩
在这里插入图片描述
(2)展开
在这里插入图片描述

2.1 stores/index.js(pinia)

定义一个变量isCollapse,初始化为true,用于传递给菜单的collapse属性,控制菜单的折叠。

import { defineStore } from "pinia";
import { ref, computed } from "vue";
function initState(){return {isCollapse:true,}
}
export const useAllDataStore = defineStore("allData", ()=>{//   ref() 相当于state属性//   computed() 相当于getters//   function() 相当于actionsconst state = ref(initState());return {state}
});

注意:useAllDataStore不是默认导出,所以在其他组件中导入时,需要使用{}

2.2 侧边栏(CommonAside.vue)

(1)菜单的宽度需要变化。
(2)el-menu的折叠属性collapse需要随着isCollapse变化。
(3)collapse-transition,是否开启折叠动画,设置为不开启。
(4)h3显示的字样,使用v-show属性,随着isCollapse变化。
在这里插入图片描述

(5)使用计算属性获取值,保持其响应性
computed会“追踪”store.state.isCollapse的变化。
一旦store.state.isCollapse改变,isCollapse.value会自动更新。
在模板中使用时,会自动重新渲染。
(6)为了让width本身也成为响应式数据,能自动更新,也用computed进行包装。
在这里插入图片描述
通过计算属性isCollapse监听store中的isCollapse状态。
通过计算属性width根据折叠状态动态返回宽度值:折叠时64px,展开时180px。

<template><el-aside :width="width"><el-menu background-color="#545c64" :collapse="isCollapse" :collapse-transition="false"><h3 v-show="!isCollapse">后台管理系统</h3><h3 v-show="isCollapse">后台</h3><el-menu-item v-for="item in noChildren" :index="item.path" :key="item.path"><component class="icons" :is="item.icon"></component><span>{{ item.label }}</span></el-menu-item><el-sub-menu v-for="item in hasChildren" :index="item.path" :key="item.path"><template #title><component class="icons" :is="item.icon"></component><span>{{ item.label }}</span></template><el-menu-item-group><el-menu-item v-for="(subItem,subIndex) in item.children" :index="subItem.path" :key="subItem.path"><component class="icons" :is="subItem.icon"></component><span>{{ subItem.label }}</span></el-menu-item></el-menu-item-group></el-sub-menu></el-menu></el-aside>
</template >
<script setup>import {useAllDataStore} from '@/stores'const store = useAllDataStore()const isCollapse = computed(()=>store.state.isCollapse)const width = computed(()=>isCollapse.value?'64px':'180px')import {ref,computed} from 'vue'import { useRouter } from 'vue-router';const router = useRouter()const list = ref([{path:"/home",name:"home",label:"首页",icon:"house",url:"Home"},{path:"/mail",name:"mail",label:"商品管理",icon:"video-play",url:"Mail"},{path:"/user",name:"user",label:"用户管理",icon:"user",url:"User"},{path:"other",label:"其他",icon:"location",children:[{path:"/page1",name:"page1",label:"页面1",icon:"setting",url:"Page1"},{path:"/page2",name:"page2",label:"页面2",icon:"setting",url:"Page2"}]}])const noChildren = computed(()=>list.value.filter(item=>!item.children))const hasChildren = computed(()=>list.value.filter(item=>item.children))
</script>

2.3 导航栏(CommonHeader.vue)

左侧的按钮添加click触发的方法,用于处理菜单折叠事宜。
在这里插入图片描述
在这里插入图片描述

<template><div class="header"><div class="l-content"><el-button size="small" @click="handleCollapse"><component class="icons" is="menu"></component></el-button><el-breadcrumb separator="/" class="bread"><el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item></el-breadcrumb></div><div class="r-content"><el-dropdown><span class="el-dropdown-link"><img :src="getImageUrl('user')" class="user"/></span><template #dropdown><el-dropdown-menu><el-dropdown-item>个人中心</el-dropdown-item><el-dropdown-item>退出</el-dropdown-item></el-dropdown-menu></template></el-dropdown></div></div>
</template><script setup>import {useAllDataStore} from '@/stores'const store = useAllDataStore()const handleCollapse = () => { store.state.isCollapse = !store.state.isCollapse}const getImageUrl= (user) => { return new URL(`../assets/img/${user}.png`,import.meta.url).href}
</script>

3 状态变更的集中管理

不推荐直接修改 store.state.xxx?
(1)违反了“单一状态更新来源”的原则
Pinia(以及Vuex)鼓励将状态的变更逻辑集中管理,而不是在组件中随意修改。
正确做法:使用actions来定义修改状态的方法。
(2)不利于维护和调试
如果多个组件都直接修改state,你很难追踪是谁改了状态。
没有统一的日志、调试工具支持(比如Vue DevTools中看不到“action被调用”)。

3.1 stores/index.js(pinia)

在这里插入图片描述

import { defineStore } from "pinia";
import { ref, computed } from "vue";
function initState(){return {isCollapse:true,}
}
export const useAllDataStore = defineStore("allData", ()=>{//   ref() 相当于state属性//   computed() 相当于getters//   function() 相当于actionsconst state = ref(initState());// 定义 actionfunction toggleCollapse() {state.value.isCollapse = !state.value.isCollapse}return {state,toggleCollapse}
});

3.2 导航栏(CommonHeader.vue)

在这里插入图片描述

4 附录

4.1 computed

const isCollapse = computed(() => store.state.isCollapse)
我想要一个值,它始终等于store.state.isCollapse的当前值,一旦它变了,我就跟着变。const isCollapse = store.state.isCollapse
我现在把store.state.isCollapse的值复制一份,以后它变不变都和我没关系了。

4.2 参考附录

参考elementplus官网地址
参考vue3实现通用后台管理(傻瓜式一步一步记录代码实现过程)

http://www.dtcms.com/a/334554.html

相关文章:

  • 机器学习——线性回归
  • 平滑方法(smoothing)
  • Python-深度学习——pytorch的安装
  • 开源 Arkts 鸿蒙应用 开发(十八)通讯--Ble低功耗蓝牙服务器
  • VSCode匹配删除多行注释
  • JavaScript 核心语法与实战笔记:从基础到面试高频题
  • 从“Hello World”到“高并发中间件”:Go 语言 2025 系统学习路线图
  • 深入解析C++ STL链表(List)模拟实现
  • 微服务之注册中心与ShardingSphere关于分库分表的那些事
  • 类与类加载器
  • 基于GIS的无人机模拟飞行控制系统设计与实现
  • 某智慧教育平台登录流程分析
  • 元宇宙娱乐:重构数字时代的沉浸式体验
  • 嵌入式 Linux LED 驱动开发实验
  • RK3568 NPU RKNN(五):RKNN-ToolKit-lite2板端推理
  • 要导入StandardScaler类进行数据标准化,请使用以下语句:
  • JavaScript学习第十章-第三部分(dom)
  • B3865 [GESP202309 二级] 小杨的 X 字矩阵(举一反三)
  • C#计算阶乘程序改进
  • C# 元组的用法
  • Nona生命之树作品TRO突袭,冻结名单曝光
  • Vue2.x核心技术与实战(一)
  • 摩搭api 实现
  • 025 理解文件系统
  • 多机编队——(6)解决机器人跟踪过程中mpc控制转圈问题
  • 第四章 Linux实用操作
  • OpenJDK 17的C1和C2编译器实现中,方法返回前插入安全点(Safepoint Poll)的机制
  • 【LeetCode题解】LeetCode 35. 搜索插入位置
  • [Linux] Linux逻辑卷管理
  • 知识点汇总linuxC高级 -2系统命令压缩与链接