封装左侧抽屉可拖拽组件【可多个】

发布于:2024-10-12 ⋅ 阅读:(125) ⋅ 点赞:(0)

一、案例效果

在这里插入图片描述
在这里插入图片描述

二、案例代码

  • 封装抽屉组件
<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哦
在这里插入图片描述
在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到