vue + muuri的复杂应用(二)

本文展示了如何使用muuri库创建一个可以拖动元素到不同列的页面布局。通过设置拖动功能、定义拖动容器和处理拖放事件,实现了在Todo、Working和Done三个状态列之间自由移动任务卡片的效果。代码示例详细说明了样式和事件监听,确保了在不同设备上的良好交互体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

muuri的复杂应用

创建一个多列组件的页面,使用muuri实现在不同列之间拖动
页面展示:如下图,能够将不同的元素在不同列之间拖动
在这里插入图片描述
代码实现:

<div class="drag-container"></div>
    <div class="board">
      <div class="board-column todo">
        <div class="board-column-container">
          <div class="board-column-header">Todo</div>
          <div class="board-column-content-wrapper">
            <div class="board-column-content">
              <div class="board-item">
                <div class="board-item-content"><span>Item #</span>1</div>
              </div>
              <div class="board-item">
                <div class="board-item-content"><span>Item #</span>2</div>
              </div>
              <div class="board-item">
                <div class="board-item-content"><span>Item #</span>3</div>
              </div>
              <div class="board-item">
                <div class="board-item-content"><span>Item #</span>4</div>
              </div>
              <div class="board-item">
                <div class="board-item-content"><span>Item #</span>5</div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div class="board-column working">
        <div class="board-column-container">
          <div class="board-column-header">Working</div>
          <div class="board-column-content-wrapper">
            <div class="board-column-content">
              <div class="board-item">
                <div class="board-item-content"><span>Item #</span>6</div>
              </div>
              <div class="board-item">
                <div class="board-item-content"><span>Item #</span>7</div>
              </div>
              <div class="board-item">
                <div class="board-item-content"><span>Item #</span>8</div>
              </div>
              <div class="board-item">
                <div class="board-item-content"><span>Item #</span>9</div>
              </div>
              <div class="board-item">
                <div class="board-item-content"><span>Item #</span>10</div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div class="board-column done">
        <div class="board-column-container">
          <div class="board-column-header">Done</div>
          <div class="board-column-content-wrapper">
            <div class="board-column-content">
              <div class="board-item">
                <div class="board-item-content"><span>Item #</span>11</div>
              </div>
              <div class="board-item">
                <div class="board-item-content"><span>Item #</span>12</div>
              </div>
              <div class="board-item">
                <div class="board-item-content"><span>Item #</span>13</div>
              </div>
              <div class="board-item">
                <div class="board-item-content"><span>Item #</span>14</div>
              </div>
              <div class="board-item">
                <div class="board-item-content"><span>Item #</span>15</div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
var dragContainer = document.querySelector(".drag-container");
      var itemContainers = [].slice.call(
        document.querySelectorAll(".board-column-content")
      );
      var columnGrids = [];
      var boardGrid;

      // Init the column grids so we can drag those items around.
      itemContainers.forEach(function (container) {
        var grid: any = new Muuri(container, {
          items: ".board-item",
          dragEnabled: true,
          dragSort: function () {
            return columnGrids
          },
          dragContainer: dragContainer,
          dragAutoScroll: {
            targets: (item: any) => {
              return [
                { element: window, priority: 0 },
                {
                  element: item.getGrid().getElement().parentNode,
                  priority: 1
                }
              ]
            }
          }
        })
          .on('dragInit', function (item: any) {
            item.getElement().style.width = item.getWidth() + 'px'
            item.getElement().style.height = item.getHeight() + 'px'
          })
          .on('dragReleaseEnd', function (item: any) {
            item.getElement().style.width = ''
            item.getElement().style.height = ''
            item.getGrid().refreshItems([item])
          })
          .on('layoutStart', function () {
            boardGrid.refreshItems().layout()
          })
        columnGrids.push(grid);
      });
      // Init board grid so we can drag those columns around.
      boardGrid = new Muuri(".board", {
        dragEnabled: true,
        dragHandle: ".board-column-header",
      });
* {
  box-sizing: border-box;
}
html,
body {
  position: relative;
  width: 100%;
  height: 100%;
  font-family: Helvetica, Arial, sans-serif;
}
body {
  margin: 0;
  padding: 20px 10px;
}
.drag-container {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 1000;
}
.board {
  position: relative;
}
.board-column {
  position: absolute;
  left: 0;
  top: 0;
  padding: 0 10px;
  width: calc(100% / 3);
  z-index: 1;
}
.board-column.muuri-item-releasing {
  z-index: 2;
}
.board-column.muuri-item-dragging {
  z-index: 3;
  cursor: move;
}
.board-column-container {
  position: relative;
  width: 100%;
  height: 100%;
}
.board-column-header {
  position: relative;
  height: 50px;
  line-height: 50px;
  overflow: hidden;
  padding: 0 20px;
  text-align: center;
  background: #333;
  color: #fff;
  border-radius: 5px 5px 0 0;
  font-weight: bold;
  letter-spacing: 0.5px;
  text-transform: uppercase;
}
@media (max-width: 600px) {
  .board-column-header {
    text-indent: -1000px;
  }
}
.board-column.todo .board-column-header {
  background: #4a9ff9;
}
.board-column.working .board-column-header {
  background: #f9944a;
}
.board-column.done .board-column-header {
  background: #2ac06d;
}
.board-column-content-wrapper {
  position: relative;
  padding: 8px;
  background: #f0f0f0;
  height: calc(100vh - 90px);
  overflow-y: auto;
  border-radius: 0 0 5px 5px;
}
.board-column-content {
  position: relative;
  min-height: 100%;
}
.board-item {
  position: absolute;
  width: calc(100% - 16px);
  margin: 8px;
}
.board-item.muuri-item-releasing {
  z-index: 9998;
}
.board-item.muuri-item-dragging {
  z-index: 9999;
  cursor: move;
}
.board-item.muuri-item-hidden {
  z-index: 0;
}
.board-item-content {
  position: relative;
  padding: 20px;
  background: #fff;
  border-radius: 4px;
  font-size: 17px;
  cursor: pointer;
  -webkit-box-shadow: 0px 1px 3px 0 rgba(0, 0, 0, 0.2);
  box-shadow: 0px 1px 3px 0 rgba(0, 0, 0, 0.2);
}
@media (max-width: 600px) {
  .board-item-content {
    text-align: center;
  }
  .board-item-content span {
    display: none;
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值