拿来改造主义,Vue + Element UI + Less 做了一个拖拽条

 其实Element UI 只用了文字提示的 el-tooltip 组件,不喜欢可以去掉,不记得是从哪拿到的原始代码,我给加了高亮渐变显示,图标,和拖拽时只能拖拽图标的位置,效果如上图,可以水平方向拖动,也可以垂直方向拖动。样式是less写的,css写嵌套样式太繁琐了。拿来主义,改造有理!

 下面贴代码

<template>
 <div ref="splitPane" class="split-pane" :class="direction" :style="{ flexDirection: direction }">
  <div class="pane pane-one" :style="lengthType + ':' + paneLengthValue">
    <slot name="one"></slot>
  </div>
  <div
    ref="trigger"
    class="pane-trigger"
    v-if="triggerDefaultColor && triggerMoveColor"
    :style="lengthType + ':' + triggerLengthValue + ';' + triggerBackGroud">
      <div @click="handleMouseOver"
        @mouseover="handleMouseOver"
        @mouseleave="handleMouseLeave"
        @mousedown="handleMouseDown"
        class="icon"
        :style="lengthType + ':' + triggerLengthValue">
      </div>
  </div>
  <div class="pane pane-two" :style="lengthType + ':calc(' + (100 - paneLengthPercent) + '% - ' + triggerLength / 2 + 'px)'">
    <slot name="two"></slot>
  </div>
 </div>
</template>
<script>
export default {
  props: {
    direction: {
      type: String,default: 'row'
    },min: {
      type: Number,default: 10
    },max: {
      type: Number,default: 90
    },paneLengthPercent: {
      type: Number,default: 50
    },triggerLength: {
      type: Number,default: 10
    }
  },data () {
    return {
      triggerLeftOffset: 0,// 鼠标距滑动器左(顶)侧偏移量,triggerBackGroud: ''
    }
  },computed: {
    lengthType () {
      return this.direction === 'row' ? 'width' : 'height'
    },// 拖拽条默认颜色
    triggerDefaultColor () {
      return this.direction === 'row' ? '-webkit-gradient(linear,left top,right top,from(white),to(#D7D7D9))' : '-webkit-gradient(linear,0 0,0 bottom,to(#D7D7D9))'
    },// 鼠标拖动时拖拽条的颜色
    triggerMoveColor () {
      return this.direction === 'row' ? '-webkit-gradient(linear,from(#A6D4E1),to(#2591C8))' : '-webkit-gradient(linear,to(#2591C8))'
    },paneLengthValue () {
      return `calc(${this.paneLengthPercent}% - ${this.triggerLength / 2 + 'px'})`
    },triggerLengthValue () {
      return this.triggerLength + 'px'
    }
  },mounted () {
    this.$nextTick(() => {
      this.triggerBackGroud = 'background:' + this.triggerDefaultColor
    })
  },methods: {
    handleMouseLeave () {
      this.$nextTick(() => {
        this.triggerBackGroud = 'background:' + this.triggerDefaultColor
      })
    },handleMouseOver () {
      this.$nextTick(() => {
        this.triggerBackGroud = 'background:' + this.triggerMoveColor
      })
    },// 按下滑动器
    handleMouseDown (e) {
      document.addEventListener('mousemove',this.handleMouseMove)
      document.addEventListener('mouseup',this.handleMouseUp)

      if (this.direction === 'row') {
        this.triggerLeftOffset = e.pageX - e.srcElement.getBoundingClientRect().left
      } else {
        this.triggerLeftOffset = e.pageY - e.srcElement.getBoundingClientRect().top
      }
    },// 按下滑动器后移动鼠标
    handleMouseMove (e) {
      this.$nextTick(() => {
        this.triggerBackGroud = 'background:' + this.triggerMoveColor
      })
      const clientRect = this.$refs.splitPane.getBoundingClientRect()
      let paneLengthPercent = 0
      if (this.direction === 'row') {
        const offset = e.pageX - clientRect.left - this.triggerLeftOffset + this.triggerLength / 2
        paneLengthPercent = (offset / clientRect.width) * 100
      } else {
        const offset = e.pageY - clientRect.top - this.triggerLeftOffset + this.triggerLength / 2
        paneLengthPercent = (offset / clientRect.height) * 100
      }
      if (paneLengthPercent < this.min) {
        paneLengthPercent = this.min
      }
      if (paneLengthPercent > this.max) {
        paneLengthPercent = this.max
      }
      this.$emit('update:paneLengthPercent',paneLengthPercent)
    },// 松开滑动器
    handleMouseUp () {
      this.$nextTick(() => {
        this.triggerBackGroud = 'background:' + this.triggerDefaultColor
      })
      document.removeEventListener('mousemove',this.handleMouseMove)
    }
  }
}
</script>
<style lang="less" scoped>
@icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAABHNCSVQICAgIfAhkiAAAAIJJREFUKFNjZMANBIBS64E4EIg/YFPGiEdzA1CuHogbgRjExgAgzQeA+D8WOQckMZAanJrxOAC3FD5nEzSQYs0gv2HzM1E2k6URZDLI2cihStA2ZAUU+5kk29BtxpVICBoKS2HYFNojCR7ElcJw2dAAlCCYtnFpBuWqDUAcAMRYcxUAYvURjNoDrtgAAAAASUVORK5CYII=';
@background-size: 10px 10px;
.split-pane {
 background: transparent;
 height: 100%;
 display: flex;
  .pane-one {
    background: transparent;
  }
  .pane-trigger {
    border-radius: 25px;
    user-select: none;
    border-width: 0.1em;
  }
  .pane-two {
    flex: 1;
    background: transparent;
  }
}
.split-pane.row {
  .pane {
    height: 100%;
  }
  .pane-trigger {
    margin-left: 1px ;
    margin-right: 1px;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    .icon {
      cursor: col-resize;
      height: 10px;
      width: 100%;
      background-image: url(@icon);
      background-repeat:no-repeat;
      background-size : @background-size;
      transform: rotate(90deg);
    }
  }
}
.split-pane.column {
  .pane {
    width: 100%;
  }
  .pane-trigger {
    margin-top: 1px ;
    margin-bottom: 1px;
    width: 100%;
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: center;
    .icon {
      cursor: row-resize;
      height: 100%;
      width: 10px;
      background-image: url(@icon);
      background-repeat:no-repeat;
      background-size : @background-size;
    }
  }
}
</style>

使用代码

<template>
  <div class="page">
    <SplitPane direction="column" :min="20" :max="80" :triggerLength="15" :paneLengthPercent.sync="paneLengthPercent">
      <template v-slot:one>
        <div>这里放你要展现的内容<div>
      </template>
      <template v-slot:two>
        <div>这里放你要展现的内容<div>
      </template>
    </SplitPane>
  </div>
</template>

direction 这个参数等于 column 时是上下拖动,参数等于 row 时是左右拖动,paneLengthPercent 是初始宽度或高度(看你的direction是column还是row),triggerLength 是拖拽条的宽度或高度(看你的direction是column还是row)

相关文章

https://segmentfault.com/a/1190000022018995 https://www....
ES6 (ECMAScript 6)中的模块是一个包含 JavaScript 代码的...
from https://mp.weixin.qq.com/s/-rc1lYYlsfx-wR4mQmIIQQ V...
D:\Temp&gt;npm init vite@latest vue3study --temp...
文章浏览阅读1.2k次。最近自己从零撸起的甘特图组件需要子组...
文章浏览阅读3.3k次,点赞3次,收藏16次。静默打印是什么?简...