Skip to content

Commit

Permalink
Feat: 增加侧栏折叠和托拽组件
Browse files Browse the repository at this point in the history
  • Loading branch information
Lruihao committed Jun 13, 2024
1 parent 0a9bb3f commit c609e0a
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 12 deletions.
107 changes: 96 additions & 11 deletions src/components/AsideToggler/index.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
<template>
<div class="aside-toggler-container">
<div
class="aside-toggler-container"
:data-position="position"
@mousedown="dragEvent"
>
<div v-if="!isCollapse && dragElement !== null" class="resize-bar" />
<el-tooltip
v-if="tooltipVisible"
effect="dark"
:content="tooltipContent"
:placement="position === 'right' ? 'left' : 'right'"
>
<div class="aside-toggler" :data-position="position" @click="toggle">
<div class="aside-toggler" @click="toggle">
<i :class="iconClass" />
</div>
</el-tooltip>
Expand All @@ -16,7 +21,11 @@
<script>
/**
* 侧栏折叠按钮,用法参考功能用例、产品版本管理等页面
* @example <AsideToggler :is-collapse="isCollapse" />
* dragEvent 拖动事件使用说明:
* 设置 dragElementClass 为【父组件】中可拖动的元素的 class,然后在【父组件】引入该组件即可
* @example
* <el-aside v-show="!isCollapse" class="drag-element"> ... </el-aside>
* <aside-toggler :is-collapse="isCollapse" drag-element-class="drag-element" />
*/
export default {
name: 'AsideToggler',
Expand All @@ -40,11 +49,24 @@ export default {
position: {
type: String,
default: 'left'
},
minWidth: {
type: Number,
default: 200
},
maxWidth: {
type: Number,
default: 600
},
dragElementClass: {
type: String,
default: ''
}
},
data() {
return {
tooltipVisible: true
tooltipVisible: true,
dragElement: null
}
},
computed: {
Expand All @@ -59,7 +81,7 @@ export default {
'el-icon-caret-left': !this.isCollapse,
'el-icon-caret-right': this.isCollapse,
}
}
},
},
watch: {
/**
Expand All @@ -72,11 +94,51 @@ export default {
})
}
},
mounted() {
this.$nextTick(() => {
if (this.dragElementClass) {
this.dragElement = this.$parent.$el.getElementsByClassName(this.dragElementClass)[0]
}
})
},
methods: {
toggle() {
toggle(e) {
e.stopPropagation()
this.$emit('update:isCollapse', !this.isCollapse)
this.$emit('toggle', !this.isCollapse)
}
},
dragEvent(e) {
// 阻止事件冒泡
e.stopPropagation()
// 如果隐藏或者没有侧栏不能拖动
if (this.isCollapse || !this.dragElement) {
return
}
const oldPointX = e.clientX
const oldOffsetWidth = this.dragElement.offsetWidth
document.onmousemove = (event) => {
// 算出新的宽度
const newOffsetWidth = this.position === 'left'
? (oldOffsetWidth + (event.clientX - oldPointX))
: (oldOffsetWidth - (event.clientX - oldPointX))
// 限定在宽度最小宽度到最大宽度之间
this.dragElement.style.width = `clamp(${this.minWidth}px, ${newOffsetWidth}px, ${this.maxWidth}px)`
// 设置鼠标样式
let cursor = 'col-resize'
if (newOffsetWidth <= this.minWidth) {
cursor = this.position === 'left' ? 'e-resize' : 'w-resize'
} else if (newOffsetWidth >= this.maxWidth) {
cursor = this.position === 'left' ? 'w-resize' : 'e-resize'
}
document.body.style.cursor = cursor
}
document.onmouseup = (event) => {
document.onmousemove = null
document.onmouseup = null
// 移除鼠标样式
document.body.style.cursor = ''
}
},
}
}
</script>
Expand All @@ -85,6 +147,29 @@ export default {
.aside-toggler-container {
height: 100%;
position: relative;
z-index: 100;
}
.resize-bar {
position: absolute;
width: 4px;
height: 100%;
flex-shrink: 0;
z-index: 100;
background: none;
user-select: none;
transform: translateX(-50%);
}
.resize-bar:active,
.resize-bar:focus,
.resize-bar:hover {
cursor: col-resize;
--active-color: #65aff5;
[data-position='left'] & {
background: linear-gradient(to left, transparent 50%, var(--active-color) 50%);
}
[data-position='right'] & {
background: linear-gradient(to right, transparent 50%, var(--active-color) 50%);
}
}
.aside-toggler {
background-image: url('holder.svg');
Expand All @@ -106,13 +191,13 @@ export default {
&:hover {
opacity: 1;
}
&[data-position='left'] {
[data-position='left'] & {
transform: translateY(-50%);
left: 0;
left: 50%;
}
&[data-position='right'] {
[data-position='right'] & {
transform: translateY(-50%) rotate(180deg);
right: 0;
right: 50%;
}
}
</style>
2 changes: 1 addition & 1 deletion src/directives/overflow-tooltip.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const setTooltip = (el, binding) => {
// 浮层中的文字 通过属性值传递动态的显示文案
document.getElementById('vc-tooltip').innerHTML = binding.value
}
// 鼠标移动时,动态修改浮沉的位置属性
// 鼠标移动时,动态修改浮层的位置属性
el.onmousemove = function(e) {
if (!isEllipsis) { return }
const vcTooltipDom = document.getElementById('vc-tooltip')
Expand Down
6 changes: 6 additions & 0 deletions src/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ const routes = [
meta: { description: '网站预览图生成' },
component: () => import(/* webpackChunkName: "appleDevicesPreview" */ '@/views/apple-devices-preview'),
},
{
path: '/aside-toggle-drag',
name: 'asideToggleDrag',
meta: { description: '侧栏折叠和托拽组件' },
component: () => import(/* webpackChunkName: "asideToggleDrag" */ '@/views/aside-toggle-drag'),
},
{
path: '/card-collapse',
name: 'cardCollapse',
Expand Down
77 changes: 77 additions & 0 deletions src/views/aside-toggle-drag.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<!-- 侧栏折叠和托拽组件 -->
<template>
<el-container class="content-container">
<el-aside v-show="!isCollapse" width="200px" class="drag-element-left">
左侧栏内容
</el-aside>
<aside-toggler :is-collapse.sync="isCollapse" drag-element-class="drag-element-left" />
<el-main class="content-main">
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Tempora perspiciatis sunt nam mollitia suscipit totam! Libero cupiditate eum suscipit adipisci eos, rerum sit iure ducimus facilis corrupti ut sint a.
Dignissimos fuga voluptatibus, vel, dolores doloremque quis aliquid quasi, unde rem asperiores veniam officia cumque libero ducimus perferendis? Cum consequuntur quibusdam officiis quo nam aliquam, aut architecto. Recusandae, tenetur aperiam.
Praesentium recusandae aliquid dolores, dignissimos sequi veritatis totam aliquam error similique laborum nemo explicabo commodi ex, eos dolore tempora. Aperiam aliquid necessitatibus, veritatis totam ipsum quia id perspiciatis voluptatibus? Aliquid?
Autem, sed dicta illo atque quas voluptatem dolor itaque illum quaerat nihil iusto laborum, eius ad aliquam. At consequuntur nesciunt dolores expedita libero veniam quos animi repellendus, in, ad ratione?
Qui, dolores praesentium. Dolorum, vero ipsam exercitationem excepturi placeat nihil nobis. Quas, nostrum nemo. Harum earum accusantium blanditiis eligendi veritatis architecto reprehenderit quo sapiente odio, eaque laborum, ullam possimus error?
Labore dolorum tenetur exercitationem! Cupiditate assumenda consequatur tempora accusamus. Perspiciatis expedita ipsum deleniti laudantium alias in, voluptates reiciendis sunt porro labore odit error adipisci quo, ea sed repellendus accusantium illum.
Dignissimos, error inventore. Officia necessitatibus fugit neque magni reiciendis placeat vel voluptate assumenda, ducimus, modi rerum dicta id tempore quae error, eaque et sit illum culpa quasi ratione eveniet doloribus?
Dicta ut porro, totam perferendis cupiditate illum dignissimos quam necessitatibus culpa, iste molestiae aliquid, quis quidem inventore aspernatur. Veniam similique, placeat quo deleniti aut cum modi provident magnam libero nostrum.
Excepturi, labore! Nisi aliquam eaque, officiis eveniet et quia rem cum libero ut culpa aut voluptas perferendis sed dignissimos laudantium repudiandae a optio repellat? Placeat assumenda numquam reiciendis nobis magni?
Dicta maiores deserunt numquam, laudantium a distinctio nisi quidem, culpa totam amet rem aspernatur magnam doloribus obcaecati aut reprehenderit temporibus ab sint possimus aliquid? Dolorum numquam minima voluptatibus? Ex, facere.
Eius totam quia expedita atque quae suscipit quam. Optio ad alias soluta neque vitae! Possimus, itaque ullam quia vel, ipsum distinctio aliquid expedita fugiat voluptatum totam non consectetur laudantium quidem!
Officia voluptatem atque aliquid! Ratione unde, tempora ipsam porro doloribus quasi provident, harum voluptatem, reprehenderit quos sunt voluptates quia! Earum, praesentium! In nesciunt optio iusto fugit ab quasi sunt libero.
Vitae, amet. Voluptatem reprehenderit sint, officiis dicta suscipit voluptates corporis expedita pariatur, unde laudantium in blanditiis deserunt magnam at! Voluptate iste vitae exercitationem tempore perferendis eaque commodi aut laudantium hic?
Aliquam dolore voluptatum impedit officiis itaque ab alias accusantium, corporis qui repudiandae sit cum nihil unde ratione beatae. Debitis repellendus facilis soluta quos sit esse, suscipit vitae beatae tempora tempore!
Optio at id sint facere minus officia eveniet eius quod sapiente doloribus perspiciatis sunt, quos, exercitationem delectus, nisi dolor nesciunt? Facilis odit officia tempora neque repudiandae unde accusantium explicabo vero!
Velit doloribus debitis odio inventore cum beatae quod eligendi laboriosam ut! Soluta ratione aperiam tempora optio ea placeat, recusandae officia veniam eligendi, amet iusto nihil, provident blanditiis dignissimos facere aspernatur.
Ullam quae beatae inventore, dolore minima numquam aut eum consequatur perferendis odio delectus aliquam corporis ipsam omnis cupiditate, amet, nam quaerat commodi totam doloremque obcaecati quibusdam iure? Minima, labore quos!
Ex obcaecati quidem, molestias, delectus possimus ipsa nulla consectetur autem sequi iste vitae dolorum, veniam quam. Quia provident ducimus exercitationem libero inventore, iusto ratione voluptate dolorem beatae. Aperiam, sed recusandae!
A labore natus rem fuga, omnis neque perferendis maiores iusto nemo similique, assumenda expedita accusamus reiciendis corrupti numquam excepturi, deserunt nihil. Magnam, mollitia recusandae a iure cumque dolorem ipsa consequuntur?
Dolorem voluptates ad consectetur repudiandae sit vero accusantium debitis veniam odio corporis, iste odit, quidem cumque? Omnis est illo ea, quasi, voluptates illum, beatae officiis iure blanditiis optio enim obcaecati!
Sit eveniet molestiae in vitae enim tempore culpa vel aliquid laborum eaque expedita commodi reprehenderit architecto veniam perferendis aspernatur repudiandae obcaecati, doloribus odit. Nobis cupiditate consectetur rem ut quos repellendus!
Numquam quis, sit amet autem in et tenetur sunt. Itaque autem repellendus iure nostrum labore qui laboriosam sed esse quibusdam, dignissimos, sit hic eum ea! A tempora molestias illo nam?
Nostrum beatae doloribus magni vero ducimus dolorem optio necessitatibus ullam, facere quae qui quaerat nobis non ad cupiditate dignissimos quo et. Itaque animi asperiores minus delectus corporis? Laboriosam, ducimus provident?
Facilis maxime, corporis doloribus molestiae corrupti nisi sed nemo. Incidunt suscipit id ea minima blanditiis asperiores accusantium tenetur delectus, repellendus, veritatis vero non, explicabo repudiandae quaerat laboriosam harum fugiat expedita.
Natus nobis reprehenderit alias amet vel blanditiis ea? Eaque accusamus est saepe nihil illum. Illo veniam temporibus, repudiandae mollitia totam sint nihil nam quo, explicabo maiores vel, aliquid minima nulla.
Omnis velit facere, repudiandae magnam suscipit tenetur distinctio esse laborum quidem, natus quia libero necessitatibus totam quos nesciunt iste doloribus ullam! Consequuntur accusamus aliquid nisi eveniet incidunt, rem nesciunt adipisci.
Voluptatibus veritatis iste provident repellendus dolorem nihil unde quasi quam, eveniet veniam, laudantium in laboriosam officiis iusto, nemo id sapiente eius voluptatum? Nobis, vel quasi possimus eos et temporibus a.
Nobis nostrum, est aspernatur veritatis ducimus distinctio, a temporibus eum dolore commodi vero excepturi. Veritatis illum necessitatibus optio nulla quam assumenda voluptatum culpa nam id? Aut accusantium ipsum nulla excepturi.
Reiciendis, sed? Id eos vero neque asperiores nihil dolorem repudiandae quia nostrum laboriosam ratione quos sit voluptatum ex blanditiis, quasi accusamus officia. Inventore velit repellat necessitatibus laudantium qui omnis perspiciatis?
Fugiat aliquam cupiditate eveniet quibusdam. Molestias omnis iure ratione assumenda alias expedita, numquam, culpa temporibus quis vitae voluptatum quibusdam amet facere. Dignissimos ipsum molestiae, omnis culpa excepturi explicabo laborum porro.
</el-main>
<aside-toggler :is-collapse.sync="isCollapseRight" position="right" drag-element-class="drag-element-right" />
<el-aside v-show="!isCollapseRight" width="200px" class="drag-element-right">
右侧栏内容
</el-aside>
</el-container>
</template>

<script>
import AsideToggler from '@/components/AsideToggler'
export default {
name: 'AsideToggleDrag',
components: {
AsideToggler,
},
data() {
return {
isCollapse: false,
isCollapseRight: false,
}
},
}
</script>

<style lang="scss" scoped>
.content-container {
height: 100%;
padding: 0 !important;
.el-main {
border-left: 1px solid #e6e6e6;
border-right: 1px solid #e6e6e6;
}
.drag-element-left,
.drag-element-right {
padding: 20px;
}
}
</style>

0 comments on commit c609e0a

Please sign in to comment.