【vue+ElementUI】实现NavMenu侧边导航栏的手动缩放功能-类似表格缩放功能
利用鼠标的mousedown、mouseup和mousemove事件实现ElementUI侧边栏的手动缩放功能。
【vue+ElementUI】实现NavMenu侧边导航栏的手动缩放功能
一、背景
最近在做个开源webapp项目,在使用ElementUI
的NavMenu
侧边导航栏过程中,由于title
过长,会产生文字溢出的bug:
对于这样情况题主所思考的解决方法就是采用文字溢出省略的方式解决,需要注意的点是ElementUI
的侧边导航栏使用的是span
标签,它是内联元素,需要使用display: inline-block;
将其改为内联块元素,并设置width
宽度,css
样式才能生效:
.text-overflow-hidden {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
display: inline-block;
}
但是这样就产生了一个问题:用户如何查看侧边栏中的完整内容。对于这样的问题,有两种解决方式,一是鼠标悬停显示完整内容,二是实现对侧边栏宽度的手动缩放功能(类似表格操作)。
二、解决方式
1、鼠标悬停显示完整内容
鼠标悬停显示完整内容有两种方式:一是使用ElementUI
的ToolTip
文字提示,这个查看ElementUI
文档就知道怎么使用,这里就不讲了。二是利用span
标签的title
属性,题主采用的是这种方式,原因是ToolTip
文字提示的使用整体效果不如span
标签的title
属性。效果如下:
代码如下:
<span
slot="title"
:title="item.metadata.name"
style="width: 70%"
class="text-overflow-hidden">
{{item.metadata.name}}
</span>
2、实现对侧边栏宽度的手动缩放功能
A.效果展示
侧边栏缩放效果
B.侧边栏的手动缩放
实现对侧边栏宽度的手动缩放功能本质上就是对侧边栏宽度的修改,利用鼠标的按下、抬起和移动事件,监听用户的操作并获取鼠标位置。因此可以在侧边栏右边添加一个空白标签div
用作事件监听。需要注意的是,由于mousemove
和mouseup
事件会被限制在该空白标签内,且该标签较小,容易造成监听失效问题,因此需要将两个事件冒泡绑定到父级标签内,题主是将其绑定到组件的根div
上。
代码如下:
html
代码:
<div @mousemove="shrinkMove" @mouseup="shrinkUp" style="width:100%; height:100%">
<el-container>
<el-aside :width="fatherWidth" class="bd-top flex" style="position:relative;">
<aside-component></aside-component>
<div class="resize" @mousedown="shrinkDown" title="Shrink sidebar"></div>
</el-aside>
<el-main style="background-color: var(--color-background)">
<component :is="mainComponent"></component>
</el-main>
</el-container>
</div>
js
代码
data() {
return {
mainComponent: "mainStartCom",
isShrink: false,//控制是否改变宽度
}
},
methods: {
shrinkMove(e) {
if (this.isShrink) {
let wid = e.screenX + 5//误差值
if (wid <= 65) {// 设定65为最短宽度
this.$store.commit('changeCollapse', true)
this.$store.commit('changeFatherWidth', '65px')
}else {
this.$store.commit('changeCollapse', false)
this.$store.commit('changeFatherWidth', wid + 'px')
}
}
},
shrinkDown(e) {
this.isShrink = true
},
shrinkUp(e) {
this.isShrink = false
}
}
css
代码
.resize {
cursor: col-resize;
position: absolute;
right: 0;
height: 100%;
width: 5px;
}
C.折叠功能的实现
在js
代码中需要注意shrinkMove
方法,由于题主之前实现了通过按钮控制NavMenu
导航菜单的折叠功能,其原理是通过NavMenu
的属性collapse
进行控制,并使用vuex进行组件通信,读者也可以不使用该功能,直接通过shrinkMove
方法修改侧边栏的宽度即可。整体效果如下:
菜单折叠效果图
菜单释放效果图
实现代码如下:
<!-- 顶部导航栏组件 -->
<template>
<div class="flex center pointer icon-size" @click="changeAsideWidth">
<el-tooltip class="item" effect="dark" :content="!isCollapse ? 'Collapse menu' : 'Expand menu'" placement="bottom">
<i class="el-icon-s-fold icon" v-if="!isCollapse"></i>
<i class="el-icon-s-unfold icon" v-else></i>
</el-tooltip>
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
name: 'HeaderComponent',
data() {
return {}
},
computed: {
...mapState({
showButton: (state) => state.header.showButton,
isCollapse: (state) => state.aside.isCollapse,
})
},
methods: {
changeAsideWidth() {
if (this.isCollapse) {
this.$store.commit('changeCollapse', false)
this.$store.commit('changeFatherWidth', '200px')
} else {
this.$store.commit('changeCollapse', true)
this.$store.commit('changeFatherWidth', '65px')
}
}
},
}
</script>
<!-- 侧边导航栏组件 -->
<template>
<el-menu
default-active="2"
active-text-color="#6E38F7"
style="height: 100%;"
:collapse="isCollapse"
:collapse-transition="false">
</el-menu>
</template>
<script>
import { mapState } from 'vuex'
export default {
name: 'AsideComponent',
data() {
return {}
},
computed: {
...mapState({
isCollapse: (state) => state.aside.isCollapse
})
},
}
</script>
<!-- 主页面 -->
<el-container>
<el-aside :width="fatherWidth" class="bd-top flex" style="position:relative;">
<aside-component></aside-component>
<div class="resize" @mousedown="shrinkDown" title="Shrink sidebar"></div>
</el-aside>
<el-main></el-main>
</el-container>
<script>
export default {
data() {
return {}
},
computed: {
...mapState({
fatherWidth: (state) => state.aside.fatherWidth
})
},
}
</script>
vuex
代码如下:
// index.js
import Vue from 'vue'
import Vuex from 'vuex'
import aside from './aside'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
},
mutations: {
},
actions: {
},
modules: {
aside
}
})
// aside.js
export default {
state: {
fatherWidth: '200px',
isCollapse: false
},
mutations: {
changeFatherWidth(state, val) {
state.fatherWidth = val
},
changeCollapse(state, val) {
state.isCollapse = val
}
}
}
3.注意事项
- 题主的代码中,标签属性
class
里的内容是题主自定义的CSS
样式,若有需要可在题主的git仓库直接获取文件使用:
https://github.com/WuChuSheng1/skywalking-banyandb/tree/main/ui/src/assets
- 目前在效果上仍然有个小bug,就是折叠后的效果仍然有文字存在,正常情况下是只有
icon
图标的,这个情况之前没有,今天突然产生的(又要疯狂查代码emmm)。
三、总结
本题客主要是实现ElementUI
的侧边导航栏缩放功能,建立在实现菜单折叠功能的基础之上,读者也可不实现折叠功能,可参考题主代码进行修改即可。
更多推荐
所有评论(0)