vue如何使用vuedraggable实现不同面板之间的拖拽排序,拖拽复制功能?【vuedraggable】

vuedraggable官方文档链接使用说明https://www.itxst.com/vue-draggable/re7vfyfe.htmlicon-default.png?t=N7T8https://www.itxst.com/vue-draggable/re7vfyfe.html

 效果图:

 使用vuedraggable拖动左边的字段和逻辑到右边形成不同的规则校验

<!--
****--@date     2024-02-01 11:34
  ****--@author   MGD
****--@describe 新增 编辑规则
-->
<template>
  <div class="MeetingListAdd">
    <template v-if="$route.name==='meetingListTest'">
      <el-scrollbar>
        <el-container>
          <el-aside width="20%" style="overflow-y: auto;height: calc(100vh - 200px)">
            <div class="col-field-box">
              <el-divider content-position="left">
                <div class="title">字段</div>
              </el-divider>
              <draggable
                  v-model="arr1"
                  :group="dragGroup"
                  :disabled="dragBox"
                  animation="300"
                  drag-class="dragClass"
                  ghost-class="ghostClass"
                  chosen-class="chosenClass"
                  @start="onStart"
                  @end="onEnd"
              >
                <transition-group>
                  <div v-for="(item,key) in arr1" :key="key" class="draggable-item">
                    {{ item.value }}
                  </div>
                </transition-group>
              </draggable>
              <el-divider content-position="left">
                <div class="title">逻辑</div>
              </el-divider>
              <draggable
                  v-model="arr3"
                  :group="dragGroup"
                  :disabled="dragBox"
                  animation="300"
                  drag-class="dragClass"
                  ghost-class="ghostClass"
                  chosen-class="chosenClass"
                  @start="onStart"
                  @end="onEnd"
              >
                <transition-group>
                  <div v-for="(item,key) in arr3" :key="key" class="draggable-item">
                    {{ item.value }}
                  </div>
                </transition-group>
              </draggable>
              <el-divider content-position="left">
                <div class="title">扩展</div>
              </el-divider>
              <draggable
                  v-model="extendVariableArr"
                  :group="dragGroup"
                  :disabled="dragBox"
                  animation="300"
                  drag-class="dragClass"
                  ghost-class="ghostClass"
                  chosen-class="chosenClass"
                  @start="onStart"
                  @end="onEnd"
              >
                <transition-group>
                  <div v-for="(item,key) in extendVariableArr" :key="key" class="draggable-item">
                    {{ item.value }}
                  </div>
                </transition-group>
              </draggable>
              <div style="padding: 20px 0">
                <el-form ref="ruleForm" :model="ruleForm" status-icon :rules="rules" label-width="60px" size="mini">
                  <el-form-item label="key" prop="key">
                    <el-input v-model="ruleForm.key" placeholder="请输入" />
                  </el-form-item>
                  <el-form-item label="value" prop="value">
                    <el-input v-model="ruleForm.value" placeholder="请输入" />
                  </el-form-item>
                  <el-form-item>
                    <el-button size="mini" icon="el-icon-refresh-right" @click="resetForm('ruleForm')">重置</el-button>
                    <el-button type="primary" size="mini" icon="el-icon-plus" @click="submitForm('ruleForm')">保存</el-button>
                  </el-form-item>
                </el-form>
              </div>
            </div>
          </el-aside>
          <el-container>
            <el-main width="80%">
              <div class="rule-field-box">
                <el-divider content-position="left">
                  <div class="title">规则<span>(向左边拖入对应字段进行规则添加)</span></div>
                </el-divider>
                <draggable
                    v-model="saveRuleArr"
                    group="sameDraggable"
                    animation="300"
                    drag-class="dragClass"
                    ghost-class="ghostClass"
                    chosen-class="chosenClass"
                    :scroll="true"
                >
                  <transition-group class="transition-box">
                    <div v-for="(item, index) in saveRuleArr" :key="index" class="rule-item">
                      {{ item.value }}
                      <div class="close-box" @click="handleDel(index)">
                        <i class="el-icon-error" />
                      </div>
                    </div>
                  </transition-group>
                </draggable>
                <div v-if="!saveRuleArr.length" class="empty-box">
                  <el-empty :image-size="150" description="向左边拖入对应字段进行规则添加" />
                </div>
              </div>
            </el-main>
            <el-footer>
              <div class="button-box">
                <el-button class="resetting" type="danger" icon="el-icon-refresh-right" @click="saveRuleArr = []">重置</el-button>
                <el-button class="submit" type="primary" icon="el-icon-edit-outline" :loading="buttonLoading" :disabled="!saveRuleArr.length" @click="handleSave()">保存</el-button>
              </div>
            </el-footer>
          </el-container>
        </el-container>
      </el-scrollbar>
    </template>
    <template v-else>
      <router-view />
    </template>
  </div>
</template>

<script>
import Draggable from 'vuedraggable'
export default {
  name: 'MeetingListAdd',
  components: { Draggable },
  mixins: [],
  data() {
    return {
      buttonLoading: false,
      dragBox: false,
      dragGroup: {
        name: 'sameDraggable',
        put: false, // true|false|array|function,//是否允许拖入当前组
        pull: 'clone'// true|false| 'clone'|array|function,//是否允许拖出当前组
      },
      ruleForm: {
        value: '',
        key: ''
      },
      rules: {
        value: [{ required: true, message: '请输入', trigger: 'blur' }],
        key: [{ required: true, message: '请输入', trigger: 'blur' }]
      },
      // 定义要被拖拽对象的数组
      arr1: [
        { key: 1, value: '字段1' },
        { key: 2, value: '字段2' },
        { key: 3, value: '字段3' },
        { key: 4, value: '字段4' },
        { key: 5, value: '字段5' }
      ],
      arr3: [
        { key: 1, value: '且' },
        { key: 2, value: '或' },
        { key: 3, value: '非' },
        { key: 4, value: '>' },
        { key: 5, value: '<' },
        { key: 6, value: '=' },
        { key: 7, value: '包含' },
        { key: 8, value: '不包含' }
      ],
      extendVariableArr: [], // 扩展变量
      saveRuleArr: [] // 规则空数组
    }
  },
  computed: {},
  watch: {},
  created() {},
  mounted() {},
  methods: {
    // 开始拖拽事件
    onStart() {
      console.log('=========拖拽开始========')
      this.dragBox = true
    },
    // 拖拽结束事件
    onEnd() {
      console.log('=======拖拽结束==========')
      this.dragBox = false
    },
    // 删除
    handleDel(index) {
      this.saveRuleArr.splice(index, 1)
    },
    submitForm(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          const submitInfo = JSON.parse(JSON.stringify(this.ruleForm))
          this.extendVariableArr.push(submitInfo)
          this.resetForm(formName)
        } else {
          console.log('error submit!!')
          return false
        }
      })
    },
    resetForm(formName) {
      this.$refs[formName].resetFields()
    },
    // 保存
    handleSave() {
      console.log(this.saveRuleArr, '==============================规则数据')
    }
  }
}
</script>

<style lang="scss">
.MeetingListAdd {
  height: 100%;
  padding: 20px;
  .el-scrollbar {
    height: 100%;
    width: 100%;
    overflow-x: hidden;

    .el-scrollbar__view {
      overflow-x: hidden;
    }
    .el-scrollbar__wrap {
      overflow-x: hidden;
    }
  }
  /*定义要拖拽元素的样式*/
  .ghostClass {
    display: inline-block;
    background-color: #CCE4FF !important;
  }

  .chosenClass {
    padding: 12px;
    color: #fff;
    display: inline-block;
    background-color: #7eb8ff !important;
    opacity: 1 !important;
  }

  .dragClass {
    padding: 6px 12px !important;
    display: inline-block;
    background-color: #CCE4FF !important;
    opacity: 1 !important;
    box-shadow: none !important;
    outline: none !important;
    background-image: none !important;
    border-radius: 0 !important;
  }

  .col-field-box {
    .title {
      padding: 12px 0;
      font-size: 18px;
      font-weight: bold;
      color: #333;
    }
    .draggable-item {
      min-width: 60px;
      text-align: center;
      margin: 0 8px 8px;
      padding: 6px 12px;
      display: inline-block;
      border-radius: 20px;
      color: #fff;
      font-size: 14px;
      cursor: pointer;
      background: linear-gradient(180deg, rgb(107, 145, 218) 0%, rgba(24, 144, 242, 1) 100%);
      box-shadow:inset 2px 0 18px  rgba(107, 145, 218, 1),inset 0 5px 10px  rgba(247, 247, 247, 1);
    }
    .draggable-item:hover {
      background-color: #fdfdfd;
      cursor: move;
    }

    .draggable-item+.draggable-item {
      border-top: none;
      margin-top: 6px;
    }
  }

  .rule-field-box {
    position: relative;
    height: calc(100vh - 300px);
    padding: 0 12px;
    border-radius: 20px;
    .title {
      padding: 12px 0;
      font-size: 18px;
      font-weight: bold;
      color: #333;
      span {
        font-weight: normal;
        font-size: 14px;
        color: #FA8C1E;
      }
    }
    .transition-box {
      padding: 12px;
      display: block;
      height: 60vh;
      background: #2b2b2b;
      border-radius: 12px;
      overflow-y: auto;
    }
    .empty-box {
      position: absolute;
      top: 0;
      left: 0;
      bottom: 0;
      right: 0;
      margin: auto;
      display: flex;
      justify-content: center;
      align-items: center;
      .el-empty__description p {
        color: #eee;
        font-size: 16px;
      }
    }
    .rule-item {
      min-width: 35px;
      text-align: center;
      position: relative;
      font-size: 16px;
      display: inline-block;
      padding: 12px 4px;
      color: #fff;
      background: #323232;
      flex-wrap: wrap;
      .close-box {
        display: none;
        position: absolute;
        top: -5px;
        right: -5px;
        cursor: pointer;
      }
    }
    .rule-item:hover .close-box {
      display: inline-block;
      z-index: 1;
    }
    .rule-item:hover {
      background-color: #6b6b6b;
      cursor: move;
    }
    .rule-item+.rule-item {
      border-top: none;
      margin-top: 6px;
    }
  }
  .button-box {
    display: flex;
    justify-content: center;
    align-items: center;
    margin-top: 10px;
    .resetting,.submit {
      padding: 12px 0;
      font-size: 18px;
      width: 160px;
      border-radius: 6px;
      border: none;
      background: #2482ED;
    }
    .resetting {
      background: #fff;
      color: #2482ED;
      border: 1px solid #2482ED;
    }
  }
}
</style>

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值