头图
最近做了一个类似于云盘的 Web文件管理 应用,需要具备一个鼠标框选文件打包下载的功能,这里记录一下前端的实现过程。

应用UI

需要鼠标按下滑动时出现线框,提取被框选的文件id,然后上传给服务端进行打包下载。

正常的网页,按下鼠标左键滑动是不会出现线框的,这里发现了一个好用的库 selection-area

详细内容大家可以参考官方文档。

下面是我写得小demo。

<template>
  <div class="parent">
    <div v-for="(item,index) in list" class="child" :data-id="item.id" :key="index">{{ item.name }}</div>
  </div>
</template>

<script>
import SelectionArea from 'selection-area';

export default {
  name: "selection",
  computed: {
    list() {
      let arr = []
      for(let i =0;i<=10;i++) {
        arr.push({name: `file-${i}`, id: i})
      }
      return arr
    }
  },
  mounted() {
    let config = {
      container: document.querySelector('.parent'),
      area: {
        class: 'custom-area'
      },
      targets: '.child',
      touchable: true,
      autostart: true,
      callback: selection => {
        if (selection.length == 0) alert("empty selection");
        else alert(`${ selection.length } items selected`);

        console.log(selection.map(item => item.dataset.id))
        document.querySelectorAll('.child').forEach(item => {
          item.classList.remove('active')
        })
        selection.forEach(item => {
          item.classList.add('active')
        })
      }
    }

    let selectable = new SelectionArea(config);
  }
}
</script>

<style scoped>
body {
  user-select: none;
}
.parent {
  width: 100%;
  height: 100vh;
  background-color: aliceblue;
  display: flex;
  gap: 10px;
  padding: 20px;
}
.child {
  width: 50px;
  height: 50px;
  background-color: antiquewhite;
}
.child.active {
  box-shadow: 0 0 2px 1px rgba(255,0,0,0.4);
}
.parent>>>.custom-area {
  background: rgba(52, 152, 219, 0.1);
  border: 1px dotted #2980b9;
}
</style>

在线演示地址


来了老弟
508 声望31 粉丝

纸上得来终觉浅,绝知此事要躬行