场景需求:选中列表中的某一项拖动到目标中
- 使用工具vue-selecto进行框选
- 使用H5的draggable属性进行拖拽放置
使用工具vue-selecto进行框选
git地址:https://github.com/daybrush/selecto
demo地址: https://daybrush.com/selecto/storybook/?path=/story/selecto–select-in-real-time
以下是代码,来源是vue-selecto插件
说明:HTML中vue-selecto主要使用依据是class名称进行使用,dragContainer,bind:selectableTargets属性中引用均为操作框选对象的css名称,在项目中使用时对应原有即可
hitRate属性是框选对象选中多大范围算选中,例:100为全部框选为选中
HTML
<!-- 这里是html代码 -->
<div class="container">
<vue-selecto
dragContainer=".elements"
v-bind:selectableTargets='[".selecto-area .cube"]'
v-bind:hitRate='100'
v-bind:selectByClick='true'
v-bind:selectFromInside='true'
v-bind:ratio='0'
@select="onSelect"
@selectEnd="selectEnd"
></vue-selecto>
<div class="elements selecto-area" id="selecto1">
<div class="cube" v-for="(cube,index) in cubes" :key="index" :id="index+1" @mousedown.stop>{{index+1}}</div>
</div>
<div class="empty elements"></div>
</div>
JS
// 这里是js代码
import { VueSelecto } from 'vue-selecto'
export default {
components: {
VueSelecto
},
data () {
return {
cubes: [],
selected: [],
}
},
mounted () {
for (let i = 0; i < 60; ++i) {
this.cubes.push(i)
}
},
methods: {
onSelect (e) {
e.added.forEach(el => {
el.classList.add('selected')
})
e.removed.forEach(el => {
el.classList.remove('selected')
this.selected = []
})
},
// 框选结束存储数据
selectEnd (e) {
e.selected.map(item => {
this.selected.push(item.id)
})
},
}
}
css
/* 这里是css样式 */
.container {
max-width: 800px;
}
.cube {
display: inline-block;
border-radius: 5px;
width: 40px;
height: 40px;
margin: 4px;
background: #eee;
--color: #4af;
}
h1, .description {
text-align: center;
}
.elements {
margin-top: 40px;
border: 2px solid #eee;
}
.selecto-area {
padding: 20px;
}
#selecto1 .cube {
transition: all ease 0.2s;
}
.moveable #selecto1 .cube {
transition: none;
}
.selecto-area .selected {
color: #fff;
background: var(--color);
}
.empty.elements {
border: none;
}
使用H5的draggable属性进行拖拽放置
菜鸟教程地址:https://www.runoob.com/html/html5-draganddrop.html
说明:可以使用多个目的地元素,例如:a,b,c 拖动到1号目的地,e,f,g拖动到二号目的地
有坑!!!框选元素与拖拽元素操作冲突导致框选与拖拽失效
解决办法:给框选元素加上@mousedown.stop,防止操作冲突
HTML
<!-- 拖拽后的目的地元素 -->
<div id="droptarget" @dragover.prevent="allowDrop" @drop.prevent="drop">
{{selectEndList}}
</div>
<!-- 展示当前状态文本 -->
<p id="text"></p>
<!-- 给元素添加拖拽属性 @dragstart="dragStart" draggable="true" -->
<div class="cube" v-for="(cube,index) in cubes" @dragstart="dragStart" draggable="true" :key="index" :id="index+1" @mousedown.stop>{{index+1}}</div>
JS
// 这里是js代码
data () {
return {
selectEndList: [] // 展示拖拽到目的地后的数据
}
},
methods: {
// 拖拽开始将数据给目标元素
dragStart () {
console.log('start')
},
// 拖拽元素放置到了目的地元素上面
allowDrop () {
document.getElementById('demo').innerHTML = '元素在放置目标上'
},
// 拖拽元素结束了操作
drop () {
this.selectEndList = this.selected
this.selected = []
document.getElementById('demo').innerHTML = '元素被拖动'
}
}
下面是展示效果:
总结: 项目实现是多个目的地和多个框选元素,项目开始前花了很长的时间去找插件实现这两种功能,直到后面发现拖拽H5中有属性可以直接使用。这里学到的就是及时去了解已有的新属性,就算当时不会记住,至少在脑子里有印象,后期需要用的时候可以凭借印象去定位一定范围搜索合适的技术,避免后续海底捞针似的寻找;当多种功能重叠时,若找不到所有功能都使用的插件时,应及时分解功能去找对应的技术。