vue实现边框线拖拽效果(拖动元素边框改变宽度)

5 篇文章 0 订阅

1.封装组件

实现的效果:

在这里插入图片描述

自定义组件代码
<template>
  <div class="x-handle" :style="divStyle" @mousedown="mouseDown">
    <el-header
      style="height: 21px;border-bottom: 1px solid rgb(235, 238, 245);padding: 0px;text-align: center;position:absolute;top:50%; transform:translate(-0%,-0%)"
    >
      <div v-if="shouldCloseWindow=='left'">
        <el-tooltip
          v-if="showTooltip"
          class="item"
          effect="dark"
          content="点击展开/隐藏"
          placement="bottom-end"
        >
          <el-button
            type="text"
            style="margin-left: -2px;float:right;font-size:5px;padding:0;color: #030c14;"
            v-on:click="visibleChange"
            class="btn-collapse"
          >
            <i class="el-icon-arrow-right" v-if="visible"></i>
            <i class="el-icon-arrow-left" v-else></i>
          </el-button>
        </el-tooltip>
        <el-button
          v-if="!showTooltip"
          type="text"
          style="margin-left: -2px;float:right;font-size:5px;padding:0;color: #030c14;"
          v-on:click="visibleChange"
          class="btn-collapse"
        >
          <i class="el-icon-arrow-right" v-if="visible"></i>
          <i class="el-icon-arrow-left" v-else></i>
        </el-button>
      </div>
      <div v-if="shouldCloseWindow=='right'">
        <el-tooltip
          v-if="showTooltip"
          class="item"
          effect="dark"
          content="点击展开/隐藏"
          placement="bottom-end"
        >
          <el-button
            type="text"
            style="margin-left: -2px;float:right;font-size:5px;padding:0;color: #030c14;"
            v-on:click="visibleChange"
            class="btn-collapse"
          >
            <i class="el-icon-arrow-left" v-if="visible"></i>
            <i class="el-icon-arrow-right" v-else></i>
          </el-button>
        </el-tooltip>
        <el-button
          v-if="!showTooltip"
          type="text"
          style="margin-left: -2px;float:right;font-size:5px;padding:0;color: #030c14;"
          v-on:click="visibleChange"
          class="btn-collapse"
        >
          <i class="el-icon-arrow-left" v-if="visible"></i>
          <i class="el-icon-arrow-right" v-else></i>
        </el-button>
      </div>
    </el-header>
  </div>
</template>

<script>
export default {
  name: "XHandle",
  props: ["isShowTooltip", "isCanMove", "closeWindow"],
  data() {
    return {
      lastX: "",
      visible: false,
      canMove: false,
      showTooltip: false,
      shouldCloseWindow: "left"
    };
  },

  created() {
    document.addEventListener("mouseup", this.mouseUp);
    if (this.isShowTooltip != undefined && this.isShowTooltip != "undefined")
      this.showTooltip = this.isShowTooltip;
    if (this.isCanMove != undefined && this.isCanMove != "undefined")
      this.canMove = this.isCanMove;
    if (this.closeWindow != undefined && this.closeWindow != "undefined")
      this.shouldCloseWindow = this.closeWindow;
  },

  destroyed() {
    document.removeEventListener("mouseup", this.mouseUp);
  },
  computed: {
    divStyle: function() {
      if (this.canMove)
        return {
          cursor: "w-resize"
        };
    }
  },
  methods: {
    visibleChange() {
      this.visible = !this.visible;
      this.$emit("visibleChange");
    },
    mouseDown(event) {
      document.addEventListener("mousemove", this.mouseMove);
      this.lastX = event.screenX;
    },
    mouseMove(event) {
      if (this.canMove) {
        this.$emit("widthChange", this.lastX - event.screenX);
        this.lastX = event.screenX;
      }
    },
    mouseUp() {
      this.lastX = "";
      document.removeEventListener("mousemove", this.mouseMove);
    }
  }
};
</script>
<style lang="less">
.x-handle {
  width: 7px;
  z-index: 10;
  background: #ccc;
  -moz-user-select: none;
  -webkit-user-select: none;
  -ms-user-select: none;
}
</style>

2.使用步骤

a.引入并注册组件
<script>
    import XHandle from "@/components/Xhandle";//以你自己目录为准
    components: { XHandle },
</script>
b.代码指定位置增加以下代码(左侧收起)
<template>
	<!--左侧界面,主要是定义 v-show="!visible" :style="{ width: width + 'px' }"-->
 	<el-aside  v-show="!visible" :style="{ width: width + 'px' }">
	</el-aside>
	<!--中间的拉动/收放的组件,用于实现拉动动态改变左右两侧的宽度->
	<!--showTooltip:是否显示展开/收起的提示内容-->
	<!--isCanMove:是否允许拖动改变大小-->
	<!--closeWindow:默认左侧的窗口收起,设置为right时,右侧的窗口收起-->
	<div class="xHandle">
    	<XHandle :showTooltip="false" :isCanMove="true" @widthChange="widthChange" @visibleChange="visibleChange" />
    </div>
	<!--右边侧界面,主要是定义 :style="divStyle"用于动态改变右侧宽度-->
	<el-aside :style="divStyle">
	</el-aside>
</template>
<script>
data() {
    return {
      //定义两个变量
      width: 250,
	  visible:false
    };
  },

  computed: {
    //右侧界面宽度的动态改变
    divStyle: function() {
      return {
        width: "calc(100% - " + this.width + "px)",
        height: "100%"
      };
    }
  },

methods: {
    //相应XHandle子组件的两个方法
    visibleChange() {
      this.visible = !this.visible;
      if (this.visible) {
        this.width = 0;
      } else {
        this.width = 250;
      }
    },
    widthChange(movement) {
      this.visible = false;
      this.width -= movement;//右边收起时,this.width += movement  左边收起时this.width -= movement
      if (this.width < 0) {//这个值的作用为:限制左侧界面能允许接受的最小宽度,例:设为50时,左侧的界面不会被缩小到50px以下
        this.width = 0;
      }
      if (this.width > 250) {//设置为data 中width变量的宽度一致
        this.width = 250;
      }
    }
}
</script>
<style scoped>
/*添加对应样式*/
.xHandle {
  display: flex;
}
</style>
当需要右侧收起和展开时:

调换两处 :style的绑定值;widthChange()方法中的this.width -= movement改为this.width += movement

<template>
	<!--左侧界面,主要是定义 :style="divStyle"用于动态改变右侧宽度 -->
 	<el-aside :style="divStyle">
	</el-aside>
	<!--中间的拉动/收放的组件,用于实现拉动动态改变左右两侧的宽度->
	<!--showTooltip:是否显示展开/收起的提示内容-->
	<!--isCanMove:是否允许拖动改变大小-->
	<!--closeWindow:默认左侧的窗口收起,设置为right时,右侧的窗口收起-->
	<div class="xHandle">
    	<XHandle :showTooltip="false" :isCanMove="true" @widthChange="widthChange" @visibleChange="visibleChange" />
    </div>
	<!--右边侧界面,主要是定义 v-show="!visible" :style="{ width: width + 'px' }"-->
	<el-aside  v-show="!visible" :style="{ width: width + 'px' }">
	</el-aside>
</template>
<script>
methods: {
    widthChange(movement) {
      this.visible = false;
      this.width += movement;//右边收起时:this.width += movement  左边收起时this.width -= movement
      if (this.width < 0) {//这个值的作用为:限制左侧界面能允许接受的最小宽度,例:设为50时,左侧的界面不会被缩小到50px以下
        this.width = 0;
      }
      if (this.width > 250) {//设置为data 中width变量的宽度一致
        this.width = 250;
      }
    }
}
</script>

3.0拓展

为实现收起/展开的动画效果,建议将需要收起/展开的部分用transition包起来,并在对应的样式中增加自己想要的动画效果

例如:

<template>
    <transition name="router-slid">
        <!--左侧界面,主要是定义 v-show="!visible" :style="{ width: width + 'px' }"-->
        <el-aside v-show="!visible" :style="{ width: width + 'px' }">
        </el-aside>
    </transition>
</template>


<style scoped>
/*添加对应样式*/
.router-slid-enter-active,
.router-slid-leave-active {
  transition: all 0.1s;
}
.router-slid-enter,
.router-slid-leave-active {
  transform: translate3d(-3rem, 0, 0);
  opacity: 0;
}
</style>
  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值