界面框架:



我采用了flex布局,先分左右,然后右侧再分上下。

步骤:

1. 首先实现简单的菜单

1.1 菜单是个菜单项数组 []

1.2 菜单项结构 例子

{
id:'001',
name: '历史轨迹', // 菜单名称
isTitle: true, // 表示可以展开
level: 1, // level控制缩进,vue动态class使用
expand: true, // 展开状态,
icon: require('@/assets/svg/track.svg'),
children:[ // 根据需要配置
{
id:'002',
name: '人员轨迹',
isTitle: false, // false表示是子节点,点击访问,而不是展开
level: 2, //
icon: require('@/assets/svg/person.svg'),
route:{
name:'historyTrack' // 这个name要和路由中配置的name保持一致,这个很关键
}
}
]
}

1.3 新建一个菜单,就叫 TreeMenu

下面代码就是TreeView菜单组件,里面递归了自己

<template>
<ul>
<li v-for="item in menu" :key="item.id">
<div :class='[item.isTitle? "menu-title": "menu-item", "level"+ item.level]' @click="toggleMenu(item)
<img v-show="item.icon" :src="item.icon" />
<span>{{item.name}}</span>
</div>
<TreeMenu v-if="item.children && item.expand" :menu="item.children" />
</li>
</ul>
</template>
  • "level-"+ item.level: 这是我设计的样式缩进level-1到level-5, panding-left每次增加12px
  • TreeMenu 递归调用自己绘制形成多级菜单
  • TreeMenu 有一个props,传递的数据结构就是 上面1.2定义的菜单项结构
  • li标签里的div中添加click事件 toggleMenu,负责处理是新打开一个菜单项对应的路由还是展开菜单,如:
toggleMenu(item){
const isTitle = item.isTitle
if(isTitle){ // 展开 or 折叠
this.$emit('expand', item) // 把该数据传给父组件,因为菜单数据是props从父组件传过来的,子组件修改会有警告,所以传事件给父组件,让父组件修改
}else{ // 打开菜单页面
if(this.$router.currentRoute.name !== item.route.name){ // 这个是为了防止点击已打开的页面,导致route模块告警说打开同一路由
this.$route.replace(item.route.name)
}
}
}

2. 然后实现AppMain:就是上面界面框架的内容部分

2.1 主要是<router-view></router-view>来展现菜单对应的路由里组件的内容

```HTML
<template>
<section>
<keep-alive :max="10" :include="cacheRoute">
<router-view :key="key" />
</keep-alive>
</section>
</template> <script>
// 省略乱七八糟的 ...
conputed:{
cacheRoute(){
const route = this.$store.getters['history/cacheRoute'] // 这个是Store中保存的已打开的路由,下面介绍,是个路由数组
return route.map(e=>e.name)
},
key(){
return this.$route.path
}
}
</script>
```
  • keep-alive 表示保活,就是你在打开其他组件的时候,当前组件不会销毁,下次打开不经历beforecreate、created、...、mounted等生命周期,从vue-devtools中也可以看到,他依然挂在AppMain下面,但是它是灰色的。注意:需要保活的组件vue配置的name属性必须配置且唯一。 详细信息见:keep-alive 官方文档
  • keep-alive:max="10 表示最多保活十个组件,第十一个进来,第一个则移除,不再保活,防止占用系统过多资源,根据实际需要调整该数
  • keep-alive:include="cacheRoute" 表示保活的组件包括这些。如果想让某个组件销毁,不再保活,则将组件对应的路由名称从cacheRoute中移除即可
  • router-view 个人理解就是用来展示当前路由对应组件的内容。 对这个理解不是太深,看了文档,模模糊糊的。详细信息见:router-view 官方文档
  • router-view:key="key" 是打开的路由路径

3. 所打开页面的tag

<template>
<!-- 这个是上面的一长条,就是界面框架右上方的空间 -->
<div>
<!-- 这个就是一个个小的tag标签 -->
<route-link v-for="item in cacheRoute" :ref="item.path" :key="item.path" :to="{path:item.path, fullPath:item.fullPath}" custom :class="{'active-tab':activeRoute === item.name}" @click.middle.native="closeTab(item)">
<div>
{{item.meta.title}} <!-- 路由配置的标题 -->
<i class="close-btn" v-if="item.meta.closable!== false" @click.prevent="closeTab(item)" /> <!-- 关闭按钮,根据路由中配置的属性来决定是否显示关闭按钮从而操作该tag是否可以关闭,路由相关的数据结构下面贴出来 -->
</div>
</route-link>
</div>
</template>
  • route-link:它组件支持用户在具有路由功能的应用中 (点击) 导航。 通过 to 属性指定目标地址,默认渲染成带有正确链接的<a>标签,可以通过配置 tag 属性生成别的标签(高版本中会抛出警告,说不再支持这个属性,请使用custom)。详细信息见:router-link 官方文档
  • <route-link v-for="item in cacheRoute"cacheRoute中保存的是在keep-alive保活的组件路由,使用store(VueX)管理
  • closeTab 方法可以将当前tag所代表的路由,从cacheRoute中移除,然后触发keep-alive的includes所绑定的数据,从keep-alive中移除,移除后会自动执行生命周期的destroyed 钩子进行销毁

4. 路由数据结构

4.1 例子

{
path:'/home',
name:'home', // 这个name要和1-2的菜单配置里route{name}一致
meta:{
title: '历史主页', // router-link 显示的tag标题
closable: false, // 这个是是否可以关闭
},
component:()=>import('@/views/home/home.vue'),
}
  • name: 1-2的菜单配置里route{name} 要和它一致
  • meta:它可以根据自己需要填充属性,title为 tag显示内容,closable是是否可以关闭

5. Store(VueX)

5.1 相关Store(VueX)的数据结构

{
cacheRoute: Array<Route>, // 实现:添加、删除(在组件被挂载、销毁的时候操作)
activeRoute: string,// 在挂载的时候操作,主要是为了修改css,高亮当前选择的菜单项和tag
}

6. mixin

6.1 mixin 内容

export default({
created(){
const cacheRoute = this.$route.getters['history/cacheRoute'] // 5.1 中的 cacheRoute,是个路由对象数组
if(cacheRoute.length === 0){ // 如果有路由是不可被关闭的,那么他将一直存在cacheRoute中,如果不在,那么就添加进去
// 找到不可关闭的路由,这里似乎可以通过route的mata属性配置的closable进行判定,我这样是写死的,固定住了
const route=this.$router.getRoutes().find(e=>e.name == "home")
this.$store.commit('history/addCacheRoute', route) // 添加进cacheRoute,这样就能显示在tag里面了
}
this.$store.commit('history/addCacheRoute', this.$route.currentRoute) // 将当前的路由加入 cacheRoute
this.$store.commit('history/setActiveRoute', this.$route.currentRoute.name)// 将当前路由设为活动的,便于高亮tag和菜单项
},
actived(){ // 这个生命周期的钩子是keep-alive的,激活当前组件时触发,还有个deactivated,取消激活当前组件时触发
this.$store.commit('history/setActiveRoute', this.$route.currentRoute.name)// 将当前路由设为活动的,便于高亮tag和菜单项
}
})

注意:该mixin需要在组件中混入

7. 界面组件层级

8. 依照7中图片结构实现思路

8.1 先设计路由,计算菜单有哪些,在Vue项目Router中设计好路由信息

8.2 HistoryHome组件中放入左上下模块:SideViewTagViewAppMain三个模块:菜单、标签栏、显示内容区域

8.3 在SideView中对着设计好的路由构造menu数据,对vue的Router理解比较深者可以根据路由来生成menu数据,我们项目需要自己手动构造menu数据。然后把构造好的menu数据给TreeView组件,使其生成菜单项,并绑定点击事件。在点击事件中,处理点击对象是展开/折叠或者路由跳转打开新页面。

8.4 新页面混入上面写的minxin,在created生命周期中将自身的路由对象存入StorecacheRoute,方便TagView组件遍历展示。同时,将自身的name存入StoreactiveRoute,便于SideViewTagView高亮。

8.5 TagView利用router-link,来实现组件跳转。遍历StorecacheRoute,填充route-link所需要的属性,添加关闭按钮,实现关闭tag方法。在关闭tag方法中,只需要将tag对应的route从cacheRoute移除即可。router-link的tag属性不能用了,我使用css控制样式。

8.6 AppMain组件利用keep-alive 进行组件保活,即发生路由跳转,但是页面不执行销毁操作。使用router-view显示当前路由对应的组件内容。采用computed计算属性获取cacheRoute中存放的路由name属性,形成数组给keep-alive,这样在 打开新页面/需要关闭页面 时,双向绑定会触发,keep-alive会自动保活/取消保活组件,与操作联动起来。然后在router-view中将当前路由的path给出即可。

ruoyi-vue 界面框架构造的更多相关文章

  1. [虾扯蛋] android界面框架-Window

    从纯sdk及framwork的角度看,android中界面框架相关的类型有:Window,WindowManager,View等.下面就以这几个类为出发点来概览下安卓开发的"界面架构&quo ...

  2. iOS开发之旅:实现一个APP界面框架

    在上一篇博客中,给大家介绍了一下我们传统的 APP 界面框架-标签导航的一些优缺点,在这篇文章中我会来给大家演示,如何用代码去实现这一框架.本次的实现我会分成俩部分来讲,好了闲话少说,接下来进入到开发 ...

  3. 分享非常漂亮的WPF界面框架源码及插件化实现原理

      在上文<分享一个非常漂亮的WPF界面框架>中我简单的介绍了一个界面框架,有朋友已经指出了,这个界面框架是基于ModernUI来实现的,在该文我将分享所有的源码,并详细描述如何基于Mod ...

  4. 使用Vue+JFinal框架搭建前后端分离系统

    前后端分离作为Web开发的一种方式,现在应用越来越广泛.前端一般比较流行Vue.js框架,后端框架比较多,网上有很多Vue+SpringMVC前后端分离的demo,但是Vue+JFinal框架貌似没有 ...

  5. .Net/.Net Core 的界面框架 NanUI 发布新版本啦!

    发布前感悟 NanUI 自从上一次更新 NanUI 0.7 已经过去大半年,B站和头条的教学视频也只制作到了第二集. 有朋友悄悄问我是不是发生什么事故我删库跑路了所以那么长时间不更新项目不发布教程,当 ...

  6. 【Windows编程】系列第十一篇:多文档界面框架

    前面我们所举的例子中都是单文档界面框架,也就是说这个窗口里面的客户区就是一个文档界面,可以编写程序在里面输入或者绘制文本和图形输出,但是不能有出现多个文档的情况.比如下面的UltraEdit就是一个典 ...

  7. 【源码分享】WPF漂亮界面框架实现原理分析及源码分享

    1 源码下载 2 OSGi.NET插件应用架构概述 3 漂亮界面框架原理概述 4 漂亮界面框架实现  4.1 主程序  4.2 主程序与插件的通讯   4.2.1 主程序获取插件注册的服务   4.2 ...

  8. 分享一个漂亮WPF界面框架创作过程及其源码

    本文会作为一个系列,分为以下部分来介绍: (1)见识一下这个界面框架: (2)界面框架如何进行开发: (3)辅助开发支持:Demo.模板.VsPackage制作. 框架源码如下所示. 本文介绍第(1) ...

  9. 分享一个漂亮的ASP.NET MVC界面框架

    本文分享一个插件化的界面框架,该框架提供了用户.角色.权限管理功能,也提供了插件的管理和插件中心.下图是该界面框架的样式(全部源码和原理介绍下一篇分享,推荐越多,源码放的越早,呵呵). 要使用该界面框 ...

  10. Onsen UI – 新鲜出炉的 PhoneGap 界面框架

    Onsen UI 是一个基于元素自定义的 HTML5 UI 框架,用于构建你的移动前端.这个一个基于 Web 组件的概念的框架,让构建应用程序变得更加轻松.Onsen UI 专门针对 PhoneGap ...

随机推荐

  1. Element Plus组件v-loading在el-dialog组件上使用无效

    前情 公司有经常需要做一些后台管理页面,我们选择了Element Plus,它是基于 Vue 3,面向设计师和开发者的组件库,是Vue框架生态中比较火的UI组件库,组件库丰富易用,组件链接:一个 Vu ...

  2. 百度地图各种控件:地图平移缩放控件NavigationControl、地图类型控件MapTypeControl

    注:代码复制即可用,标色代码为主要代码 百度地图提供了如下控件: 1.Control:控件的抽象基类,所有控件均继承此类的方法.属性.通过此类您可实现自定义控件. 2.NavigationContro ...

  3. 虚拟机安装 Win10 ,无法启动,报错EFI Network ... Time out

    问题情况 VMWare 16 安装 win10 的镜像文件,无法启动,报错 EFI Network ... Time out 解决办法 虚拟机设置中 固件类型 改用 BIOS 已解决

  4. SM国密算法

    package com.abc.apollo.common.util; import javax.crypto.IllegalBlockSizeException; import java.secur ...

  5. Qt编写视频监控系统78-视频推流到流媒体服务器

    一.前言 视频推流作为独立的模块,目前并没有集成到视频监控系统中,目前是可以搭配监控系统一起使用,一般是将添加好的摄像头通道视频流地址打开后,读取视频流重新推到流媒体服务器,然后第三方可以从流媒体服务 ...

  6. Windows7下关闭和打开IPV6隧道

    IPv6隧道是将IPv6报文封装在IPv4报文中,让IPv6数据包穿过IPv4网络进行通信.对于采用隧道技术的设备来说,在隧道的入口处,将IPv6的数据报封装进IPv4,IPv4报文的源地址和目的地址 ...

  7. [转]WorldWind开发中WorldWindowGLCanvas .setPreferredSize()函数找不到

    值高温假期,无意翻到了csdn中三维GIS开发的专栏,讲的是worldwind Java三维GIS系统开发的东西,十分感兴趣.恰巧要求的环境已经存在,直接耍起来.将最新的Worldwind和JOGL下 ...

  8. 基于开源IM即时通讯框架MobileIMSDK:RainbowChat v10.0版已发布

    关于MobileIMSDK MobileIMSDK 是一套专门为移动端开发的开源IM即时通讯框架,超轻量级.高度提炼,一套API优雅支持UDP .TCP .WebSocket 三种协议,支持iOS.A ...

  9. 阿里技术分享:闲鱼IM基于Flutter的移动端跨端改造实践

    本文由阿里闲鱼技术团队祈晴分享,本次有修订和改动,感谢作者的技术分享. 1.内容概述 本文总结了阿里闲鱼技术团队使用Flutter在对闲鱼IM进行移动端跨端改造过程中的技术实践等,文中对比了传统Nat ...

  10. IM跨平台技术学习(七):得物基于Electron开发客服IM桌面端的技术实践

    本文由得物技术团队Uni分享,即时通讯网收录时有内容修订和排版优化. 一.引言 本文要分享的是得物技术团队基于Electron开发客服IM桌面端的技术实践过程,内容包括桌面技术选型.Electron的 ...