25-vue中實現拖動調整左右兩側盒子的寬度


這里是直接完整一個組件,路由引入即可看到效果。

<template>
  <div class="box" ref="box">
    <div class="left">
      <!--左側div內容-->
      <h1>到了時間你就一定要上場</h1>
      <h1>當意識到達,那就必須上岸</h1>
    </div>
    <div class="resize" title="收縮側邊欄"></div>
    <div class="mid">
      <!--右側div內容-->
      <h1>我希望我希望的有希望</h1>
      <h1>想着光向着光</h1>
    </div>
  </div>
</template>

<script> export default { data() { return {}; }, methods: { dragControllerDiv() { var resize = document.getElementsByClassName("resize")[0]; var left = document.getElementsByClassName("left"); var mid = document.getElementsByClassName("mid"); var box = document.getElementsByClassName("box")[0]; // 鼠標按下事件
      resize.onmousedown = function (e) { //顏色改變提醒
        resize.style.background = "#818181"; var startX = e.clientX; resize.left = resize.offsetLeft; // 鼠標拖動事件
        document.onmousemove = function (e) { var endX = e.clientX; var moveLen = resize.left + (endX - startX); // (endx-startx)=移動的距離。resize.left+移動的距離=左邊區域最后的寬度
          var maxT = box.clientWidth - resize.offsetWidth; // 容器寬度 - 左邊區域的寬度 = 右邊區域的寬度

          if (moveLen < 32) moveLen = 32; // 左邊區域的最小寬度為32px
          if (moveLen > maxT - 150) moveLen = maxT - 150; //右邊區域最小寬度為150px
 resize.style.left = moveLen; // 設置左側區域的寬度

          for (let j = 0; j < left.length; j++) { left[j].style.width = moveLen + "px"; mid[j].style.width = box.clientWidth - moveLen - 10 + "px"; } }; // 鼠標松開事件
        document.onmouseup = function () { //顏色恢復
          resize.style.background = "#d6d6d6"; document.onmousemove = null; document.onmouseup = null; resize.releaseCapture && resize.releaseCapture(); //當你不在需要繼續獲得鼠標消息就要應該調用ReleaseCapture()釋放掉
 }; resize.setCapture && resize.setCapture(); //該函數在屬於當前線程的指定窗口里設置鼠標捕獲
        return false; }; }, }, mounted() { this.dragControllerDiv(); }, }; </script>

<style scoped>
/* 拖拽相關樣式 */
/*包圍div樣式*/ .box { width: 100%; height: 50vh; margin: 5vh 0px; overflow: hidden; box-shadow: -1px 9px 10px 3px rgba(0, 0, 0, 0.11); } /*左側div樣式*/ .left { width: calc(32% - 10px); /*左側初始化寬度*/ height: 100%; background: #ffffff; float: left; } /*拖拽區div樣式*/ .resize { cursor: col-resize; float: left; position: relative; top: 45%; background-color: #d6d6d6; border-radius: 5px; margin-top: -10px; width: 10px; height: 50px; background-size: cover; background-position: center; /*z-index: 99999;*/ font-size: 32px; color: white; } /*拖拽區鼠標懸停樣式*/ .resize:hover { color: #444444; } /*右側div'樣式*/ .mid { float: left; width: 68%; /*右側初始化寬度*/ height: 100%; background: #fff; box-shadow: -1px 4px 5px 3px rgba(0, 0, 0, 0.11); } </style>

 左側如果有ifame,解決方案參考


 

封裝好的組件:(vue文件)

 

<template>
  <div id="dragLayoutBox">
    <div class="left_box">
      <slot name="left-content"></slot>
    </div>
    <div class="right_box">
      <div v-if="iframeIsHave" class="opacity_box"></div>
      <div v-show="dragBtnFlag" class="drag_btn" @mousedown="changeBoxStyleFn('')" @onmouseup="changeBoxStyleFn('none')"
      ></div>
      <slot name="right-content"> </slot>
    </div>
  </div>
</template>

<script> export default { props: { // 是否默認顯示拖拽按鈕
 dragBtnFlag: { typeof: Boolean, default: true }, // 盒子中是否有iframme
 iframeIsHave: { typeof: Boolean, default: false }, // 配置項 注意:色值暫時只支持16進制寫法
 setCssProps: { typeof: Object, default: () => ({ // 左右盒子最小拖動寬度
        leftMinWidth: '200px', rightMinWidth: '500px', dragBtnCss: { mousedown: { background: '#919191' }, onmouseup: { background: '#d6d6d6' } } }) } }, mounted() { if (this.iframeIsHave) { this.changeBoxStyleFn('none') } this.dragChangeLayoutFn() }, methods: { getDomFn(name) { const ele = document.querySelector(name) const ws = new WeakSet() ws.add(ele) return ele }, changeBoxStyleFn(value) { if (this.iframeIsHave) { const opacityBox = this.getDomFn('.opacity_box') opacityBox.style.display = value } }, dragChangeLayoutFn() { const that = this const dragBtn = this.getDomFn('.drag_btn') const left_box = this.getDomFn('.left_box') const right_box = this.getDomFn('.right_box') const dragLayoutBox = this.getDomFn('#dragLayoutBox') dragBtn.onmousedown = function (e) { const styleStr = that.handleEleStyleFn(that.setCssProps.dragBtnCss.mousedown) dragBtn.style.cssText = `${styleStr}` const startPos = e.clientX dragBtn.left = dragBtn.offsetLeft document.onmousemove = e => { const endPos = e.clientX let moveW = dragBtn.left - 20 + (endPos - startPos) const maxW = dragLayoutBox.clientWidth - dragBtn.offsetWidth // 左邊區域的最小寬度
          const leftValue = parseInt(that.setCssProps.leftMinWidth) if (moveW < leftValue) { moveW = leftValue } // 右邊區域最小寬度
          const rightValue = parseInt(that.setCssProps.rightMinWidth) if (moveW > maxW - rightValue) { moveW = maxW - rightValue } left_box.style.cssText = `width:${moveW}px` right_box.style.width = dragLayoutBox.clientWidth - moveW + 'px' } document.onmouseup = () => { const styleStr = that.handleEleStyleFn(that.setCssProps.dragBtnCss.onmouseup) dragBtn.style.cssText = `${styleStr}` document.onmousemove = document.onmouseup = null
          if (that.iframeIsHave) { that.changeBoxStyleFn('none') } dragBtn.releaseCapture && dragBtn.releaseCapture() } dragBtn.setCapture && dragBtn.setCapture() return false } }, // 處理傳來的對象:{k1:"v1",k2:"v2"} => "k1:v1;k2:v2"
 handleEleStyleFn(obj) { let str = JSON.stringify(obj) const indexstart = str.indexOf('{') const indexEnd = str.indexOf('}') str = str.slice(indexstart + 1).slice(0, indexEnd - 1) const reg1 = /,/g const reg2 = /"|'/g return str.replace(reg1, ';').replace(reg2, '') } } } </script>

<style scoped> #dragLayoutBox { width: 100%; display: flex; justify-content: space-between; box-shadow: 0px 20px 40px 0px rgba(0, 0, 0, 0.08); } .drag_btn { position: absolute; top: calc((100vh - 50px) / 2); width: 8px; height: 50px; cursor: col-resize; background: rgba(0, 0, 0, 0.1); border-radius: 5px; margin-top: -10px; background-size: cover; background-position: center; font-size: 32px; color: white; z-index: 1112; } .opacity_box { width: 100%; height: 100%; position: absolute; margin-top: 30px; filter: alpha(opacity=0); opacity: 0; background: transparent; z-index: 1111; } </style>

 

使用:

1.引入和注冊

const LayoutDrag = () => import('./LayoutDrag/index.vue') components: { LayoutDrag }

2.使用:iframeIsHave為true表示右側區域內有iframe,默認不傳則為false,這個的判定就是為了解決當有iframe(比如富文本)拖拽時卡頓問題

 <LayoutDrag :iframeIsHave="true">
    <template v-slot:left-content>
        // 你的左側盒子的盛放區域
    </template>

    <template v-slot:right-content>
      // 你的右側盒子盛放區域
    </template>
</LayoutDrag>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM