用Vue3造个轮子吧:拖拽缩放组件,支持吸附对齐,实时参考线

7,450 阅读2分钟

前言

这篇文章主要来分享下我以前用 Vue3 写的一个组件,

项目地址 : Vue3DraggableResizable

logo (2).png

组件功能

  • 支持拖拽和缩放,可分别定义开启或关闭

  • 自定义缩放句柄(缩放时共有八个方位可操作,可分别定义开启或关闭)

  • 可将组件的拖动和缩放限制在其父节点内

  • 可自定义组件内各种类名

  • 可配合内置的DraggableContainer组件方便地实现参考线以及自动吸附功能。

该组件所支持的参数和事件加起来有几十种,可进行各种配置,具体可查看Github的详细文档。

下面我来介绍下使用方式。

基本功能

首先要注册组件:

// main.js
import { createApp } from 'vue'
import App from './App.vue'
import Vue3DraggableResizable from 'vue3-draggable-resizable'
//需引入默认样式
import 'vue3-draggable-resizable/dist/Vue3DraggableResizable.css'

// 你将会获得一个名为Vue3DraggableResizable的全局组件
createApp(App).use(Vue3DraggableResizable).mount('#app')

执行use(Vue3DraggableResizable)后将会全局注册两个组件:Vue3DraggableResizableDraggableContainerVue3DraggableResizable是拖拽缩放用的组件,DraggableContainer可用来实现参考线和自动吸附。

注册后就可以使用了:

<template>
  <div id="app">
    <div class="parent">
      <Vue3DraggableResizable> {{ msg }} </Vue3DraggableResizable>
    </div>
  </div>
</template>

<script>
  import { defineComponent } from 'vue'

  export default defineComponent({
    data() {
      return {
        msg: 'Hello World. Hello World. Hello World.'
      }
    }
  })
</script>
<style lang="less" scoped>
  .parent {
    width: 300px;
    height: 300px;
    position: absolute;
    top: 100px;
    left: 200px;
    position: relative;
    border: 1px solid #000;
  }
</style>

很简单,直接使用即可,可以在Vue3DraggableResizable内放任何东西。

1.gif

也可以锁定比例,只需要传入:lockAspectRatio="true"参数就可以了:

<Vue3DraggableResizable :lockAspectRatio="true">
  {{ msg }}
</Vue3DraggableResizable>

也可以让组件只在 X 轴上移动或只在 Y 轴上移动,传入disabledXdisabledY即可:

<Vue3DraggableResizable :disabledX="true"> {{ msg }} </Vue3DraggableResizable>

可通过parent属性控制组件是否只能在其父节点内移动:

<Vue3DraggableResizable :parent="true"> {{ msg }} </Vue3DraggableResizable>

2.gif

除了我介绍的这几个,还有其他很多功能,感兴趣的话可以去 GitHub 上看详细的文档。

下面我介绍下参考线和吸附对齐的功能。

参考线、吸附对齐

这个功能需要配合DraggableContainer组件一起使用。

<template>
  <div id="app">
    <div class="parent">
      <DraggableContainer>
        <Vue3DraggableResizable> {{ msg }} </Vue3DraggableResizable>
        <Vue3DraggableResizable> {{ msg }} </Vue3DraggableResizable>
      </DraggableContainer>
    </div>
  </div>
</template>

<script>
  import { defineComponent } from 'vue'

  export default defineComponent({
    data() {
      return {
        msg: 'Hello World. Hello World. Hello World.'
      }
    }
  })
</script>
<style lang="less" scoped>
  .parent {
    width: 300px;
    height: 300px;
    position: absolute;
    top: 100px;
    left: 200px;
    position: relative;
    border: 1px solid #000;
    .vdr-container {
      background-color: #999;
    }
  }
</style>

在刚才的基础上,直接用DraggableContainer组件套一下就可以了。其子组件Vue3DraggableResizable在移动时候就会自动吸附。

3.gif

可以使用adsorbParent属性,该属性用来控制靠近父元素边缘时,是否自动吸附对齐,默认为true

<template>
  <div id="app">
    <div class="parent">
      <DraggableContainer :adsorbParent="true">
        <Vue3DraggableResizable> {{ msg }} </Vue3DraggableResizable>
      </DraggableContainer>
    </div>
  </div>
</template>

4.gif

你也可以通过adsorbColsadsorbRows自定义列或行的校准线,元素在靠近这些线时,会产生吸附,

<DraggableContainer :adsorbCols="[10, 50, 100]" :adsorbParent="false">
  <Vue3DraggableResizable> {{ msg }} </Vue3DraggableResizable>
</DraggableContainer>

5.gif

也可以修改参考线颜色:

<DraggableContainer :referenceLineColor="#0f0">
  <Vue3DraggableResizable> {{ msg }} </Vue3DraggableResizable>
</DraggableContainer>

当然也可以不显示参考线:

<DraggableContainer :referenceLineVisible="false">
  <Vue3DraggableResizable> {{ msg }} </Vue3DraggableResizable>
</DraggableContainer>

参考线虽然不显示,但是自动吸附仍然生效。

最后

这是去年写的一个项目,现在拿出来分享下,如果在使用中有什么问题的话,欢迎在评论区或者 GitHub 上和我交流。


看到这里就点个赞吧,感谢~~