vue2实现盒子拖拽宽度完整版

 

1,DragBox组件

<template>
    <div ref='dragBoxRef' class="dragBox" >
        <slot></slot>
    </div>
 </template>
 <script>
 export default {
   name:"dragBox",
   props:{
    itemMinWidth:{
        type:Number,
        default:200
    },//孩子盒子的最小宽度
    resizeBoxBg:{
        type:String,
        default:'#818181'
    },//长按拓展条背景色
   },
   componets:{
   },
   data(){
         return{
           fileUrl:'',
           filename:''
         }
   },
   methods:{
	// 如果dragItem 没有定义宽度,则flex=1
    setDragItemFlex () {
      const dragBox = this.$refs.dragBoxRef
    //   console.log(dragBox);
    //   return
      const childsLen = dragBox.children.length

      for (let i = 0; i < childsLen; i++) {
        const node = dragBox.children[i]
        if (!node.style.width) {
          // 如果没有定义宽度,则flex=1
          node.style.flex = 1
        }
      }
    },
    dragControllerDiv () {
        const resize = document.getElementsByClassName('resize') // 拖拽条
        // 循环为每个拖拽条添加事件
        for (let i = 0; i < resize.length; i++) {
            // 鼠标按下事件
            resize[i].addEventListener('mousedown', this.onMouseDown)
        }
    },
    onMouseDown (e) {
        this.resizeBox = e.target
        this.currentBox = this.resizeBox.parentNode// 当前盒子
        this.rightBox = this.getNextElement(this.currentBox)// 当前盒子的下个兄弟节点
        if (!this.rightBox) return
        this.curLen = this.currentBox.clientWidth
        this.otherBoxWidth = this.$refs.dragBoxRef.clientWidth - this.currentBox.clientWidth - this.rightBox.clientWidth // 其他盒子的宽度
        // 颜色改变提醒
        this.resizeBox.style.background = this.resizeBoxBg
        this.startX = e.clientX
        document.addEventListener('mousemove', this.onMousemove)
        document.addEventListener('mouseup', this.onMouseup)
    },
    onMousemove (e) {
        const endX = e.clientX
        const moveLen = endX - this.startX // (endx-startx)= 移动的距离
        const CurBoxLen = this.curLen + moveLen // resize[i].left+移动的距离=左边区域最后的宽度
        const rightBoxLen = this.$refs.dragBoxRef.clientWidth - CurBoxLen - this.otherBoxWidth // 右侧宽度=总宽度-左侧宽度-其它盒子宽度
        // 当最小宽度时,无法继续拖动
        if (CurBoxLen <= this.itemMinWidth || rightBoxLen <= this.itemMinWidth) return
        this.currentBox.style.width = CurBoxLen + 'px'// 当前盒子的宽度
        this.resizeBox.style.left = CurBoxLen // 设置左侧区域的宽度
        this.rightBox.style.width = rightBoxLen + 'px'
    },
    onMouseup () {
        // 颜色恢复
        this.resizeBox.style.background = '#d6d6d6'
        document.removeEventListener('mousedown', this.onMouseDown)
        document.removeEventListener('mousemove', this.onMousemove)
    },

    // 获取下一个兄弟元素的兼容函数
    getNextElement (element) {
        if (element.nextElementSibling) {
            return element.nextElementSibling
        } else {
            var next = element.nextSibling// 下一个兄弟节点
            while (next && next.nodeType !== 1) { // 有 并且 不是我想要的
            next = next.nextSibling
            }
            return next
        }
    }

   },
   beforeCreate(){
 
   },
   created(){
   
   },
   beforeMount(){
 
   },
   mounted(){
    this.setDragItemFlex()
    this.dragControllerDiv()
   }
 }
 </script>
 <style scoped>
 .dragBox{
    display: flex;
    width: 100%;
    height: 100%;
 }
 </style>
 

 2,DragItem组件

<template>
    <div ref="container" class="d-flex" >
        <div style="width: 100%; height: 100%;">
            <slot>默认信息</slot>
        </div>
		<!-- 拖拽条 -->
        <div v-if="resizeShow" :style="{'width':resizeWidth}" class="resize" />
    </div>
</template>
<script>
export default {
  props: {
  // 控制拖拽条的是否显示,默认显示
    resizeShow: {
      type: Boolean,
      default: true
    },
  //拖拽条默认宽度
    resizeWidth:{
        type:String,
        default:"4px"
    }
  }
}
</script>
<style>
.resize {
    position: absolute;
    top: 0;
    right: 0;
    height: 100%;
    cursor: col-resize;
    background-color: #d6d6d6;
}
.resize:hover{
    width: 4px !important;
}
.d-flex{
    position: relative;
}
</style>

3,组件调用

<template>
    <div id="dragDiv" class="dragDiv"  >
      <drag-box :itemMinWidth="100" style="width: 100%; height: 100%;">
        <drag-item style="width: 20%;" resizeWidth="2px" >item1</drag-item>
        <drag-item resizeWidth="2px" >item2</drag-item>
        <drag-item style="width: 20%;" :resizeShow='false'>item3</drag-item>
      </drag-box>
    </div>
  </template>
  
  <script>
  import DragBox from './dragBox/index.vue'
  import DragItem from './dragBox/dragItem.vue'

  export default {
    name: 'dragDiv',
    components: {
      DragBox,
      DragItem
    }
  }
  </script>
   <style scoped>
    .dragDiv{
        width: 100%;
        height: 100vh;
        border:1px solid #ccc;
    }
    </style>
    
  

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于vue实现拖拽宽度的菜单,可以使用vuedraggable插件和vue-resizable插件。 vuedraggable插件可以实现拖拽排序的功能,而vue-resizable插件可以实现拖拽改变元素大小的功能。 以下是一个简单的实现示例: 1. 安装vuedraggable和vue-resizable插件 ``` npm install vuedraggable vue-resizable ``` 2. 在组件中引入插件并初始化 ``` <template> <div class="menu"> <vue-draggable v-model="menuItems"> <div v-for="(item, index) in menuItems" :key="index" class="menu-item"> <vue-resizable :resizable="true" :on-resize-stop="resize" :max-width="200" :min-width="100"> {{ item }} </vue-resizable> </div> </vue-draggable> </div> </template> <script> import draggable from 'vuedraggable' import resizable from 'vue-resizable' export default { components: { 'vue-draggable': draggable, 'vue-resizable': resizable }, data () { return { menuItems: ['Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5'] } }, methods: { resize (event) { console.log(event) } } } </script> ``` 在上面的代码中,使用了vuedraggable组件来包裹菜单项,使用了vue-resizable组件来包裹每个菜单项,并设置了最大和最小宽度,并在on-resize-stop事件中调用了resize方法。 3. 样式设置 为了使菜单项可拖拽和可改变大小,需要为其设置一些基本样式: ``` .menu { display: flex; flex-wrap: wrap; justify-content: flex-start; } .menu-item { display: flex; align-items: center; justify-content: center; margin: 10px; padding: 10px; background-color: #ccc; border: 1px solid #000; cursor: move; } ``` 在上面的样式中,设置了菜单项为flex布局,并设置了一些基本样式,如背景色、边框等。 这样就可以实现一个简单的可拖拽和可改变大小的菜单了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值