• vuedraggable 拖拽组件 封装


    demo:

    <template>
      <div class="fluid container">
        <div class="form-group form-group-lg panel panel-default">
          <div class="panel-heading">
            <h3 class="panel-title">拖拽组件</h3>
          </div>
          <div class="panel-body">
            <div class="checkbox">
              <label><input type="checkbox" v-model="editable">启用拖拽</label>
            </div>
            <button type="button" class="btn btn-default" @click="orderList">恢复初始排序</button>
          </div>
        </div>
        <div class="box">
            <div class="groupBox">
                <div class="col-md-3">
                    <!-- 拖拽元素盒子 -->
                  <draggable class="list-group" element="ul" v-model="list" :options="dragOptions" :move="onMove" @start="isDragging=true" @end="isDragging=false">
                    <transition-group type="transition" :name="'flip-list'">
                      <li class="list-group-item licommon" v-for="element in list" :key="element.order">
                        <i :class="element.fixed? 'fa fa-anchor' : 'glyphicon glyphicon-pushpin'" @click=" element.fixed=! element.fixed" aria-hidden="true"></i>
                        {{element.name}}
                        <span class="badge">{{element.order}}</span>
                      </li>
                    </transition-group>
                  </draggable>
                </div>
             </div>
             <div class="groupBox">
                 <div class="col-md-3">
                     <!-- 目标元素盒子 -->
                   <draggable element="span" v-model="list2" :options="dragOptions" :move="onMove">
                     <transition-group name="no" class="list-group targetUl" tag="ul">
                       <li class="list-group-item" v-for="element in list2" :key="element.order">
                         <i :class="element.fixed? 'fa fa-anchor' : 'glyphicon glyphicon-pushpin'" @click=" element.fixed=! element.fixed" aria-hidden="true"></i>
                         {{element.name}}
                         <span class="badge">{{element.order}}</span>
                       </li>
                     </transition-group>
                   </draggable>
                 </div>
             </div>
        </div>
        <div class="arr">
            <!-- 拖拽数组 -->
            <div class="list-group col-md-3 arrcommon">
              <pre>{{listString}}</pre>
            </div>
            <!-- 目标数组 -->
            <div class="list-group col-md-3 arrcommon">
              <pre>{{list2String}}</pre>
            </div>
        </div>
      </div>
    </template>
     
    <script>
    import draggable from "vuedraggable";
    const message = [
      "詹姆斯",
      "杜兰特",
      "科比",
      "乔丹"
    ];
     
    export default {
      name: "hello",
      components: {
        draggable
      },
      data() {
        return {
          list: message.map((name, index) => {
            return { name, order: index + 1, fixed: false };
          }),
          list2: [],
          editable: true,
          isDragging: false,
          delayedDragging: false
        };
      },
      methods: {
         // 恢复初始排序,已经有拖拽到右边时无法恢复
        orderList() {
          this.list = this.list.sort((one, two) => {
            return one.order - two.order;
          });
        },
        onMove({ relatedContext, draggedContext }) {
          // 关联元素
          const relatedElement = relatedContext.element;
          // 拖拽元素
          const draggedElement = draggedContext.element;
          console.log('拖拽1', relatedElement)
          console.log('拖拽2', draggedElement)
          return (
            (!relatedElement || !relatedElement.fixed) && !draggedElement.fixed
          );
        }
      },
      computed: {
         // 配置项
        dragOptions() {
          return {
            animation: 0,
            group: "description",
            disabled: !this.editable,
            ghostClass: "ghost"
          };
        },
        listString() {
          return JSON.stringify(this.list, null, 2);
        },
        list2String() {
          return JSON.stringify(this.list2, null, 2);
        }
      },
      watch: {
        isDragging(newValue) {
          if (newValue) {
            this.delayedDragging = true;
            return;
          }
          this.$nextTick(() => {
            this.delayedDragging = false;
          });
        }
      }
    };
    </script>
     
    <style>
    .box{
        display:flex;
    }
    .arr{
        display:flex;
    }
    .arr .arrcommon{
        width:50%;
        border:1px solid red;
    }
    .targetUl{
        display:flex;
    }
    .groupBox{
        border:1px solid #00FFFF;
        width:50%;
    }
    .groupBox li{
        list-style: none;
        height:30px;
        border:1px solid #eeeeee;
    }
    .flip-list-move {
      transition: transform 0.5s;
    }
     
    .no-move {
      transition: transform 0s;
    }
     
    .ghost {
      opacity: 0.5;
      background: #c8ebfb;
    }
     
    .list-group {
      min-height: 20px;
    }
     
    .list-group-item {
      cursor: move;
    }
     
    .list-group-item i {
      cursor: pointer;
    }
    </style>
    View Code

    封装后的组件代码:

    <template>
      <div class="board-column">
        <div class="board-column-header">
          {{ headerText }}
        </div>
        <draggable
          :list="list"
          v-bind="$attrs"
          class="board-column-content"
          :set-data="setData"
        >
          <div v-for="element in list" :key="element.id" class="board-item">
            {{ element.name }} {{ element.id }}
          </div>
        </draggable>
      </div>
    </template>
    
    <script>
    import draggable from "vuedraggable";
    export default {
      name: "DragKanbanDemo",
      components: {
        draggable,
      },
      props: {
        headerText: {
          type: String,
          default: "Header",
        },
        options: {
          type: Object,
          default() {
            return {};
          },
        },
        list: {
          type: Array,
          default() {
            return [];
          },
        },
      },
      methods: {
        setData(dataTransfer) {
          // to avoid Firefox bug
          // Detail see : https://github.com/RubaXa/Sortable/issues/1012
          dataTransfer.setData("Text", "");
        },
      },
    };
    </script>
    <style lang="less" scoped>
    .board-column {
      min-width: 300px;
      min-height: 100px;
      height: auto;
      overflow: hidden;
      background: #f0f0f0;
      border-radius: 3px;
      .board-column-header {
        height: 50px;
        line-height: 50px;
        overflow: hidden;
        padding: 0 20px;
        text-align: center;
        background: #333;
        color: #fff;
        border-radius: 3px 3px 0 0;
      }
      .board-column-content {
        height: auto;
        overflow: hidden;
        border: 10px solid transparent;
        min-height: 60px;
        display: flex;
        justify-content: flex-start;
        flex-direction: column;
        align-items: center;
        .board-item {
          cursor: pointer;
          width: 100%;
          height: 64px;
          margin: 5px 0;
          background-color: #fff;
          text-align: left;
          line-height: 54px;
          padding: 5px 10px;
          box-sizing: border-box;
          box-shadow: 0px 1px 3px 0 rgba(0, 0, 0, 0.2);
        }
      }
    }
    </style>
    View Code

    使用封装后的组件:

    <template>
      <div class="components-container board">
        <div class="panel-body">
            <div class="checkbox">
              <label><input type="checkbox" v-model="editable" />启用拖拽</label>
            </div>
        </div>
    
        <Kanban :key="1" :list="list1" :group="group" :disabled="!this.editable" class="kanban todo" header-text="Todo" />
        <Kanban :key="2" :list="list2" :group="group" :disabled="!this.editable" class="kanban working" header-text="Working" />
        <Kanban :key="3" :list="list3" :group="group" :disabled="!this.editable" class="kanban done" header-text="Done" />
      </div>
    </template>
    <script>
    import Kanban from '@/components/Kanban'
    export default {
      name: 'DragKanbanDemo',
      components: {
        Kanban
      },
      data() {
        return {
          editable: true,
          group: 'mission',
          list1: [
            { name: 'Mission', id: 1 },
            { name: 'Mission', id: 2 },
            { name: 'Mission', id: 3 },
            { name: 'Mission', id: 4 }
          ],
          list2: [
            { name: 'Mission', id: 5 },
            { name: 'Mission', id: 6 },
            { name: 'Mission', id: 7 }
          ],
          list3: [
            { name: 'Mission', id: 8 },
            { name: 'Mission', id: 9 },
            { name: 'Mission', id: 10 }
          ]
        }
      },
    }
    </script>
    <style lang="less">
    .board {
      width: 1000px;
      margin-left: 20px;
      display: flex;
      justify-content: space-around;
      flex-direction: row;
      align-items: flex-start;
    }
    .kanban {
      &.todo {
        .board-column-header {
          background: #4A9FF9;
        }
      }
      &.working {
        .board-column-header {
          background: #f9944a;
        }
      }
      &.done {
        .board-column-header {
          background: #2ac06d;
        }
      }
    }
    </style>
    View Code
  • 相关阅读:
    性能测试的感悟
    Web性能测试问题,mysql分析之一
    LoadRunner使用代理远程执行提示找不到“pre_cci.c”文件
    yii widget验证码不实用form验证的方法
    mysql 1449 : The user specified as a definer ('root'@'%') does not exist 解决方法
    (亲测)nginx解决thinkphp中pathinfo的问题
    一个超好用的php header下载函数
    编程中的一些概念,KISS、DRY、MVC、OOP、REST
    8个开发必备的PHP功能(转)
    关于按钮在短时间内多次点击的问题.
  • 原文地址:https://www.cnblogs.com/jervy/p/14303551.html
Copyright © 2020-2023  润新知