element-ui 抽屉组件(el-drawer ) 二次封装 增加resize拖曳改变宽度大小

<template>
  <div :id="`drawer_container_${id}`">
    <el-drawer :id="id+'_drawer'" :wrapperClosable="false" @close="onClose" v-if="isShowDraw" :visible.sync="isShowDraw" :direction="direction" :size="sizePercentLabel">
        <template slot="title">
           <slot name="title"></slot>
        </template>
        <div v-if="isIframe && isShowIframeModal" class="iframe-model"></div>
        <slot></slot>
    </el-drawer>
  </div>
</template>

<script>
export default {
  name: 'Drawer',
  data() {
    return {
      isShowDraw: this.isShow,
      sizePercentDraw: this.sizePercent,
      drawerElement: null,
      isEffectiveEdge: false,
      isMouseDown: false,
      isShowIframeModal: false
    }
  },
  computed: {
    sizePercentLabel() {
      return this.sizePercentDraw * 100 + '%'
    }
  },
  props: {
    id: {
      type: String,
      default: 'my'
    },
    sizePercent: {
      type: Number,
      default: .6
    },
    isShow: {
      type: Boolean,
      default: false
    },
    direction: {
      type: String,
      default: 'rtl'
    },
    minSizePercent: {
      type: Number,
      default: .4
    },
    maxSizePercent: {
      type: Number,
      default: .99
    },
    isIframe: {  //内容里如果包含iframe 需要单独处理resize
      type: Boolean,
      default: false
    },
    moveEdge: {
      type: Number,
      default: 10
    },
  },
  watch: {
    isShow(value) {
      this.isShowDraw = value
      value ? this.bindEvents() : this.unbindEvents()
    }
  },
  beforeDestroy() {
    this.unbindEvents()
  },
  methods: {
    onClose() {
      this.isShowDraw = false
      this.$emit('update:isShow', false);
    },
    bindEvents() {
      const containerElement = document.getElementById(`drawer_container_${this.id}`)
      if (containerElement) {
        containerElement.addEventListener('mousemove', this.onMouseMove)
        containerElement.addEventListener('mousedown', this.onMouseDown)
        containerElement.addEventListener('mouseup', this.onMouseUp)
      }
    },
    unbindEvents() {
      const containerElement = document.getElementById(`drawer_container_${this.id}`)
      if (containerElement) {
        containerElement.removeEventListener('mousemove', this.onMouseMove)
        containerElement.removeEventListener('mousedown', this.onMouseDown)
        containerElement.removeEventListener('mouseup', this.onMouseUp)
      }
    },
    isMoveToEdge(clientX) { 
      this.drawerElement = document.getElementById(this.id + '_drawer')
      const { width } = this.drawerElement.getBoundingClientRect()
      //实际遮罩范围宽度
      const modalWidth = width * (1 - this.sizePercentDraw)

      //3像素是边缘范围
      return clientX <= modalWidth + this.moveEdge && clientX >= modalWidth - this.moveEdge
    },
    onMouseMove({ clientX }) {
      if (this.isMouseDown) {
         //动态改变宽度
         const { width } = this.drawerElement.getBoundingClientRect()
         if (clientX < width) {
            const tempSizePercent = (width - clientX) / width
            if (tempSizePercent >= this.minSizePercent && tempSizePercent <= this.maxSizePercent) {
              this.sizePercentDraw = tempSizePercent.toFixed(2)
            }
         }
      }

      //处理鼠标移到到边缘
      if (this.isMoveToEdge(clientX) || this.isMouseDown) {
        this.isEffectiveEdge = true
        this.drawerElement.style.cursor = 'e-resize'
      } else {
        this.isEffectiveEdge = false
        this.drawerElement.style.cursor = 'default'
      }
    },
    onMouseDown() {
      //处理鼠标移到到边缘 然后按下
      if (this.isEffectiveEdge) {
         this.isMouseDown = true
      }

      //处理iframe 遮罩层
      this.isShowIframeModal = true
    },
    onMouseUp() {
      this.isMouseDown = false 
      this.isShowIframeModal = false
    }
  }
}
</script>

<style lang="scss" scoped>
.iframe-model {
  width: 100%;
  height: 100%;
  position: absolute;
  z-index: 3000;
  filter: alpha(opacity=0);
  opacity: 0;
  background: transparent;
}
</style>

 

倒过来看 please~~~

 

posted @ 2021-09-23 18:22  创业男生  阅读(4588)  评论(0编辑  收藏  举报