Vue拖拽组件列表实现动态页面配置

需求描述

最近在做一个后台系统,有一个功能产品需求是页面分为左右两部分,通过右边的组件列表来动态配置左边的页面视图,并且左边由组件拼装起来的视图,可以实现上下拖拽改变顺序,也可以删除。

根据这个需求我做了下面这个demo。

功能分解

  • 右边的组件列表,可以通过拖拽克隆到左边,拖拽结束后右边组件列表数量不会减少
  • 左边的组件可以展开或收起
  • 左边的组件可以上下拖拽,删除,但不可向右边拖拽
  • 左边组件拖拽过程中不改变其展开和收起状态

demo截图

代码地址

vue-draggable-list

代码预览

<template>
  <div class="row">
    <div class="col-5">
      <h3>组件配置页面展示</h3>
      <draggable
        tag="el-collapse"
        class="dragArea list-group"
        :list="list2"
        group="comp"
        @change="log"
      >
        <el-collapse
          class="list-group-item left"
          v-for="(element,index) in list2"
          :key="index"
          v-model="activeNames"
          @change="handleChange"
        >
          <el-collapse-item :name="element.id">
            <template slot="title">
              <span>{{element.name}}</span>
              <i class="el-icon-circle-close" @click.stop="deleteItem(index)"></i>
            </template>
            <div>{{ element.content }}</div>
          </el-collapse-item>
        </el-collapse>
      </draggable>
    </div>

    <div class="col-5">
      <h3>可用组件列表</h3>
      <draggable
        class="dragArea list-group"
        :list="list1"
        :group="{ name: 'comp', pull: 'clone', put: false }"
        @change="log"
      >
        <div class="list-group-item" v-for="element in list1" :key="element.id">{{ element.name }}</div>
      </draggable>
    </div>
  </div>
</template>
<script>
import draggable from "vuedraggable";
export default {
  name: "clone",
  display: "Clone",
  order: 2,
  components: {
    draggable
  },
  data() {
    return {
      list1: [
        { name: "组件1", id: 1, content: "内容内容内容。。。。" },
        { name: "组件2", id: 2, content: "内容内容内容。。。。" },
        { name: "组件3", id: 3, content: "内容内容内容。。。。" },
        { name: "组件4", id: 4, content: "内容内容内容。。。。" },
        { name: "组件5", id: 5, content: "内容内容内容。。。。" },
        { name: "组件6", id: 6, content: "内容内容内容。。。。" },
        { name: "组件7", id: 7, content: "内容内容内容。。。。" }
      ],
      list2: [],
      activeNames: [],
      count: 0
    };
  },

  methods: {
    log: function(evt) {
      console.log(evt);
      if (evt.added) {
        this.count += 1;
        const item = evt.added.element;
        const idx = this.list2.findIndex(e => e.id === item.id);
        let temp = JSON.parse(JSON.stringify(this.list2));
        temp[idx].id = this.count;
        this.list2 = temp;
      }
    },
    handleChange: function() {},
    deleteItem: function(index) {
      this.list2.splice(index, 1);
    }
  }
};
</script>
posted @ 2019-06-16 16:06  dora_zc  阅读(22126)  评论(1编辑  收藏  举报