一、案例效果
二、案例代码
- 封装抽屉组件
<template>
<div class="drag-drawer">
<div class="out-box" :style="style">
<mtd-tooltip
:content="collapse ? '展开面板' : '收起面板'"
class="tool-tip"
:placement="mode === 'right' ? 'left' : 'right'"
:show-arrow="false"
>
<div class="switch" @mousedown="onSwitchDragStart($event)"></div>
</mtd-tooltip>
</div>
<div
class="border"
@mousedown="onDragStart($event)"
:style="borderStyle"
></div>
<div
class="wrapper"
v-if="!collapse"
:style="{ width: currentWidth + 'px', paddingLeft: '20px' }"
>
<slot name="content"></slot>
</div>
</div>
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
@Component
export default class DragDrawer extends Vue {
@Prop({ type: String, default: 'right' }) public mode!: string;
@Prop({ type: Boolean, default: false }) private hasTab?: boolean;
@Prop({ type: Number, default: 0 }) private leftMargin: number;
private collapse = false;
private currentWidth = 400;
private fromPage = '';
get style() {
if (!this.isLeft) {
return {
right: this.collapse ? '-3px' : `${this.currentWidth - 2}px`,
};
} else {
return {
left: this.collapse
? -3 + this.leftMargin + 'px'
: `${this.currentWidth - 2}px`,
transform: 'rotate(180deg)',
};
}
}
// drawer是否在左侧
get isLeft() {
return this.mode === 'left';
}
get borderStyle() {
if (this.isLeft) {
return {
right: 0,
};
} else {
return {
left: 0,
};
}
}
private onDragStart(e: any) {
const startWidth = this.currentWidth;
const pageX = e.pageX;
let isMoving = false;
const moveCb = (ev: any) => {
if (this.collapse) {
return;
}
const currentWidth = this.isLeft
? startWidth + (ev.pageX - pageX)
: startWidth + pageX - ev.pageX;
if (currentWidth > 360 && currentWidth <= 800) {
this.currentWidth = currentWidth;
}
isMoving = true;
};
const upCb = () => {
this.$store.state.paint.key++;
document.removeEventListener('mousemove', moveCb);
document.removeEventListener('mouseup', upCb);
};
document.addEventListener('mousemove', moveCb);
document.addEventListener('mouseup', upCb);
}
private onSwitchDragStart(e: any) {
const startWidth = this.currentWidth;
const pageX = e.pageX;
let isMoving = false;
const moveCb = (ev: any) => {
if (this.collapse) {
return;
}
const currentWidth = this.isLeft
? startWidth + (ev.pageX - pageX)
: startWidth + pageX - ev.pageX;
if (currentWidth > 360 && currentWidth <= 800) {
this.currentWidth = currentWidth;
}
isMoving = true;
};
const upCb = () => {
document.removeEventListener('mousemove', moveCb);
document.removeEventListener('mouseup', upCb);
if (!isMoving) {
this.collapse = !this.collapse;
}
};
document.addEventListener('mousemove', moveCb);
document.addEventListener('mouseup', upCb);
}
}
</script>
<style scoped lang="less">
.drag-drawer {
background: #fff;
position: relative;
width: 100%;
height: 100%;
.out-box {
font-size: 20px;
cursor: pointer;
width: 18px;
z-index: 999;
position: absolute;
background: #edededfd;
top: 0;
bottom: 0;
height: 100%;
.tool-tip {
display: inline-block;
width: 20px;
height: 40px;
position: relative;
top: 93%;
.switch {
height: 100%;
background: url('../../../assets/paintSwitch.png') no-repeat center
center;
background-size: cover;
-moz-user-select: none; /* Firefox私有属性 */
-webkit-user-select: none; /* WebKit内核私有属性 */
-ms-user-select: none; /* IE私有属性(IE10及以后) */
-khtml-user-select: none; /* KHTML内核私有属性 */
-o-user-select: none; /* Opera私有属性 */
user-select: none; /* CSS3属性 */
&:hover {
background-image: url('../../../assets/paintSwitchHover.png');
}
}
}
.nav {
position: absolute;
right: 10px;
text-decoration: none;
display: inline-block;
width: 25px;
height: 25px;
cursor: pointer;
padding: 3px 0 0 6px;
.text {
font-size: 12px;
width: 25px;
transform: rotate(-180deg);
}
&:hover {
color: dodgerblue;
}
}
.nav::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: #fff;
border: 1px solid #edededfd;
border-right: none;
border-radius: 5px 0 0 5px;
box-shadow: -3px -3px 5px #edededfd;
transform: perspective(10px) scale(1.1, 1.3) rotateY(-15deg);
z-index: -1;
}
.tab_s {
color: dodgerblue;
}
}
.border {
width: 1px;
background: rgba(0, 0, 0, 0.12);
box-sizing: border-box;
position: absolute;
top: 0;
bottom: 0;
cursor: col-resize;
z-index: 9999;
}
.wrapper {
height: 100%;
}
}
</style>
- 使用组件
<DragDrawer ref="drawer" mode="left">
<template slot="content"> 抽屉内容1 </template>
</DragDrawer>
<DragDrawer ref="drawer" mode="left" :leftMargin="21">
<template slot="content"> 抽屉内容2 </template>
</DragDrawer>
三、 使用的图片
可换成icon哦