Skip to content
目录

低代码平台的拖拽效果

简介

低代码平台是一种开发工具,它可以让开发人员使用简单的拖拽和配置来创建应用程序,而不需要编写大量的代码。低代码平台通常包括一个可视化的界面编辑器,可以让开发人员通过拖拽和配置来创建应用程序的用户界面和业务逻辑。

0 代码平台

低代码平台

拖拽作用

拖拽效果是低代码平台的一个重要功能,它可以让开发人员通过拖拽组件来快速创建应用程序的用户界面。拖拽效果可以提高开发效率,减少开发成本,同时还可以让开发人员更加专注于应用程序的业务逻辑。

拖拽排序

拖拽效果的实现方式通常包括以下几个步骤:

  • 拖拽开始 dragstart
  • 拖拽移动 dragover
  • 拖拽结束 dragend

代码实现

  • 优化:为了提高用户体验,在拖拽过程中添加动画效果。
vue
<script setup lang="ts">
import { ref } from 'vue'

// 高亮下标
const activeIndex = ref(-1)
// 列表数据
const list = ref([
  { id: 3, name: '张三' },
  { id: 4, name: '李四' },
  { id: 5, name: '王五' },
  { id: 6, name: '赵六' },
  { id: 7, name: '田七' },
])

// 拖拽开始
const onDragStart = (index: number) => {
  // 更新下标
  activeIndex.value = index
}

const onDragOver = (index: number) => {
  // 提取数据
  const draggingItem = list.value.splice(activeIndex.value, 1)
  // 添加数据
  list.value.splice(index, 0, ...draggingItem)
  // 更新下标
  activeIndex.value = index
}

const onDragEnd = () => {
  // 恢复下标
  activeIndex.value = -1
}
</script>

<template>
  <div class="list">
    <div
      class="item"
      v-for="(item, index) in list"
      :key="item.id"
      :draggable="true"
      @dragstart="onDragStart(index)"
      @dragover="onDragOver(index)"
      @dragend="onDragEnd"
    >
      {{ item.name }}
    </div>
  </div>
  <pre class="data">{{ list }}</pre>
</template>

<style scoped lang="scss">
.list {
  width: 500px;
  border: 1px solid #000;
  .item {
    box-sizing: border-box;
    width: 100%;
    height: 40px;
    display: flex;
    justify-content: center;
    align-items: center;
    // 隔行变色
    &:nth-child(even) {
      background: #c7edcc;
    }
    &:nth-child(odd) {
      background: pink;
    }
  }
}

.data {
  box-sizing: border-box;
  padding: 20px;
  width: 500px;
  border: 1px solid #000;
  font-family: serif;
}
</style>

vuedraggable 组件

快速上手

  1. 安装依赖 npm i vuedraggable@next
  2. 使用 draggable 组件

官方文档

官方例子

vue
<script setup lang="ts">
import { ref } from 'vue'
import draggable from 'vuedraggable'

// 列表数据
const list = ref([
  { id: 3, name: '张三' },
  { id: 4, name: '李四' },
  { id: 5, name: '王五' },
  { id: 6, name: '赵六' },
  { id: 7, name: '田七' },
])
</script>

<template>
  <draggable class="list" v-model="list" item-key="id">
    <template #item="{ element }">
      <div class="item">{{ element.name }}</div>
    </template>
  </draggable>
  <pre class="data">{{ list }}</pre>
</template>

<style scoped lang="scss">
.list {
  width: 500px;
  border: 1px solid #000;
  .item {
    box-sizing: border-box;
    width: 100%;
    height: 40px;
    display: flex;
    justify-content: center;
    align-items: center;
    // 隔行变色
    &:nth-child(even) {
      background: #c7edcc;
    }
    &:nth-child(odd) {
      background: pink;
    }
  }
}

.data {
  box-sizing: border-box;
  padding: 20px;
  width: 500px;
  border: 1px solid #000;
  font-family: serif;
}
</style>

任务列表-拖拽编组

编组配置

  • group 编组
vue
<script setup lang="ts">
import { ref } from 'vue'
import draggable from 'vuedraggable'

// 任务分配,需要对任务实现编组

// 列表数据
const list = ref([
  { id: 3, name: '开发任务A' },
  { id: 4, name: '开发任务B' },
  { id: 5, name: '开发任务C' },
  { id: 6, name: '开发任务D' },
  { id: 7, name: '开发任务E' },
])

const list2 = ref([
  { id: 11, name: '工作1' },
  { id: 12, name: '工作2' },
  { id: 13, name: '工作3' },
])
</script>

<template>
  <!-- :group="{ name: 'task' }" 编组 -->
  <div class="group">
    <draggable class="list" v-model="list" item-key="id" :group="{ name: 'task' }">
      <template #item="{ element }">
        <div class="item">{{ element.name }}</div>
      </template>
    </draggable>

    <draggable class="list" v-model="list2" item-key="id" :group="{ name: 'task' }">
      <template #item="{ element }">
        <div class="item">{{ element.name }}</div>
      </template>
    </draggable>
  </div>
  <div class="group">
    <pre class="data">{{ list }}</pre>
    <pre class="data">{{ list2 }}</pre>
  </div>
</template>

<style scoped lang="scss">
.group {
  display: flex;
}
.list {
  width: 500px;
  border: 1px solid #000;
  .item {
    box-sizing: border-box;
    width: 100%;
    height: 40px;
    display: flex;
    justify-content: center;
    align-items: center;
    // 隔行变色
    &:nth-child(even) {
      background: #c7edcc;
    }
    &:nth-child(odd) {
      background: pink;
    }
  }
}

.data {
  box-sizing: border-box;
  padding: 20px;
  width: 500px;
  border: 1px solid #000;
  font-family: serif;
}
</style>

低代码原理

进阶配置

  • group 编组
  • :sort="false"
  • pull: 'clone' 克隆
  • put: false

安装组件库

  1. 安装依赖 npm i element-plus
  2. 引入组件库
ts
// main.ts
import { createApp } from 'vue'
import App from './App.vue'
// 导入组件库
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'

const app = createApp(App)
app.use(ElementPlus)   // 使用组件库
app.mount('#app')

参考代码

vue
<script setup lang="ts">
import { ref } from 'vue'
import draggable from 'vuedraggable'

// 需要使用ref
const list1 = ref([
  {
    id: 1,
    tag: 'el-button',
    props: {
      type: 'primary'
    },
    text: '按钮'
  },
  {
    id: 2,
    tag: 'el-input',
    props: {
      placeholder: '请输入内容'
    }
  },
  {
    id: 3,
    tag: 'el-switch'
  }
])

// 组件数据列表
const list2 = ref([])
</script>

<template>
  <el-container class="container">
    <el-aside class="aside" width="200px">
      <draggable
        class="list"
        v-model="list1"
        item-key="id"
        :group="{ name: 'component', pull: 'clone', put: false }"
        :sort="false"
      >
        <template #item="{ element }">
          <div class="item">
            {{ element.tag }}
          </div>
        </template>
      </draggable>
    </el-aside>
    <el-main class="main">
      <draggable v-model="list2" item-key="id" class="content" :group="{ name: 'component' }">
        <template #item="{ element }">
          <div class="component">
            <!-- 
              is: 组件名
              v-bind: 动态 props
            -->
            <component :is="element.tag" v-bind="element.props">
              {{ element.text }}
            </component>
          </div>
        </template>
      </draggable>
    </el-main>
  </el-container>
</template>

<style scoped lang="scss">
.container {
  display: flex;
}
.aside {
  background-color: pink;
}
.main {
  flex: 1;
  height: 100vh;
  background-color: skyblue;
  .content{
    background-color: #fff;
    height: 100%;
  }
}
.list {
  .item {
    border: #0083ee 1px solid;
    margin: 10px;
    padding: 10px;
  }
}
</style>

总结

低代码平台的拖拽效果可以帮助用户快速构建页面,提高开发效率和用户体验。

在实现时时通过 HTML5 的拖放 API 或者 JavaScript 的库来实现,其中 SortableJS 的 vuedraggable 是 Vue 生态最好用的解决方案,并且 SortableJS 支持配合 Vue2/Vue3/React/jQuery 等使用。

  • 拖拽原理实现
  • vuedraggable 快速实现
  • vuedraggable 编组配置
  • 低代码平台原理

拓展阅读

根据 MIT 许可证发布