vue2实现左右布局宽度可拖拽

<template>
  <div id="app">
    <div class="container">
      <div class="left" :style="{ width: leftWidth + 'px' }">

        <el-tree class="tree" :data="treeData" :props="defaultProps" node-key="id">
        </el-tree>
      </div>
      <div class="divider-h" @mousedown="startDragH">
        <span>||</span>
      </div>
      <div class="right" :style="{ width: rightWidth + 'px' }">
        <div class="top" :style="{ height: topHeight + 'px' }">
          <p>这是右边上面的区域</p>
        </div>
        <div class="divider-v" @mousedown="startDragV">
        </div>
        <div class="bottom" :style="{ height: bottomHeight + 'px' }">
          <p>这是右边下面的区域</p>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      containerWidth: 800, // 容器的宽度
      containerHeight: 600, // 容器的高度
      leftWidth: 400, // 左边区域的宽度
      rightWidth: 400, // 右边区域的宽度
      topHeight: 300, // 右边上面区域的高度
      bottomHeight: 300, // 右边下面区域的高度
      draggingH: false, // 是否正在水平拖动
      draggingV: false, // 是否正在垂直拖动
      startX: 0, // 水平拖动开始时的鼠标位置
      startY: 0, // 垂直拖动开始时的鼠标位置
      startLeftWidth: 0, // 水平拖动开始时的左边区域宽度
      startRightWidth: 0,
      startTopHeight: 0, // 垂直拖动开始时的右边上面区域高度
      startBottomHeight: 0,
      treeData: [
        {
          id: 1,
          label: "一级 1",
          children: [
            {
              id: 4,
              label: "二级 1-1",
              children: [
                {
                  id: 9,
                  label: "三级 1-1-1",
                },
                {
                  id: 10,
                  label: "三级 1-1-2",
                },
              ],
            },
          ],
        },
        {
          id: 2,
          label: "一级 2",
          children: [
            {
              id: 5,
              label: "二级 2-1",
            },
            {
              id: 6,
              label: "二级 2-2",
            },
          ],
        },
        {
          id: 3,
          label: "一级 3",
          children: [
            {
              id: 7,
              label: "二级 3-1",
            },
            {
              id: 8,
              label: "二级 3-2",
            },
          ],
        },
      ],
      defaultProps: {
        children: "children",
        label: "label",
      },
    };
  },

  methods: {
    // 开始水平拖动
    startDragH(e) {
      this.draggingH = true;
      this.startX = e.clientX;
      this.startLeftWidth = this.leftWidth;
      this.startRightWidth = this.rightWidth;
    },
    // 开始垂直拖动
    startDragV(e) {
      this.draggingV = true;
      this.startY = e.clientY;
      this.startTopHeight = this.topHeight;
      this.startBottomHeight = this.bottomHeight;
    },
    // 拖动中
    onDrag(e) {
      if (this.draggingH) {
        // 计算水平拖动的距离
        let delta = e.clientX - this.startX;
        // 更新左右区域的宽度
        this.leftWidth = this.startLeftWidth + delta;
        this.rightWidth = this.startRightWidth - delta;
      }
      if (this.draggingV) {
        // 计算垂直拖动的距离
        let delta = e.clientY - this.startY;
        // 更新上下区域的高度
        this.topHeight = this.startTopHeight + delta;
        this.bottomHeight = this.startBottomHeight - delta;
      }
    },
    // 结束拖动
    endDrag() {
      this.draggingH = false;
      this.draggingV = false;
    },
    onresize() {
      this.leftWidth = window.innerWidth * 0.3 - 5
      this.rightWidth = window.innerWidth * 0.7 - 5
      this.topHeight = window.innerHeight * 0.5 - 5
      this.bottomHeight = window.innerHeight * 0.5 - 5
      console.log(window.screen);
    }
  },
  mounted() {

    // 监听鼠标移动和松开事件
    document.addEventListener("mousemove", this.onDrag);
    document.addEventListener("mouseup", this.endDrag);
    window.addEventListener("resize", this.onresize);
    this.leftWidth = window.innerWidth * 0.2 - 5
    this.rightWidth = window.innerWidth * 0.8 - 5
    this.topHeight = window.innerHeight * 0.5 - 5
    this.bottomHeight = window.innerHeight * 0.5 - 5
    // 
  },
  beforeDestroy() {
    // 移除事件监听
    document.removeEventListener("mousemove", this.onDrag);
    document.removeEventListener("mouseup", this.endDrag);
  },
};
</script>

<style>
html,
body {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
}

.container {
  display: flex;
  width: 100%;
  height: 100%;
  /* border: 1px solid black; */
}

.left {
  display: flex;
  flex-direction: column;
  background-color: lightblue;
  height: 100%;
  width: 30%;
}

.right {
  display: flex;
  flex-direction: column;
  background-color: lightgreen;
  height: 100%;
  width: 70%;

}

.top {
  background-color: blueviolet;
}

.bottom {
  background-color: bisque;
}

.divider-h {
  width: 10px;
  cursor: col-resize;
}

.divider-h span {
  display: block;
  margin-top: 290px;
}

.divider-v {
  height: 10px;
  cursor: row-resize;
  background-color: aliceblue;
}

.divider-v span {
  display: block;
  margin-left: 190px;
}

.tree {
  flex: 1;
  overflow: auto;
  cursor: pointer;
}</style>


对于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、付费专栏及课程。

余额充值