Draggable拖拽
由于目前所在的公司做的是学校管理的项目,功能中就包含课程表定制,学生排序,邮箱回执插入等,都需要用到拖拽的功能,以下就介绍下项目中用的draggable实现的拖拽排序
实现效果图
功能描述:搜索框输入首字母或者姓名可快速定位到该学生,根据键盘上键和下键可进行学生的选择,enter键或者鼠标点击即选中学生(选中后定位到该学生,该学生变色,方便查找),点击学生即可进行拖拽排序
以下为一个弹窗
下拉框列表选择学生
选中学生定位到该学生并变色
拖拽效果
1.安装
npm install vuedraggable复制代码
2.引入
import draggable from 'vuedraggable'复制代码
3.根据vuetify的v-menu来做一个点击输入框,下拉显示列表的功能
具体函数功能会在下面附上完整代码,太多了就不截图了~~~
根据输入框的内容对下拉列表的内容进行筛选,后台返回的数据如下
4.拖拽的基本用法
布局
参数配置
以上就是大体的结构,下面附上所有代码,注释的很详细了哦
5.所有代码
<template> <div class="draggable-roster"> <my-dialog ref="draggable_roster_dialog" :width="studentInfo.length > 63 ? 1012 : 1005" @handle="changeMuster"> <div class="draggable-title" slot="title">自定义排序</div> <div class="draggable-content" slot="content"> <!-- 下拉框搜索内容 --> <v-menu offset-y v-model="show" fixed max-height="240" class="search-student"> <header slot="activator" class="select-header"> <input ref="input" type="text" v-model.trim="inputValue" placeholder="请输入学生姓名或者首字母" @keydown.delete="deleteInputVal" @keydown="onKeyDown" @keyup.enter="onKeyEnter"> </header> <main class="select-wrap"> <ul v-if="filterList && filterList.length > 0" ref="content"> <li v-for="(item, i) in filterList" :key="i" @click="selectListOne(item)" @keydown.delete="deleteInputVal" :class="{'key-down-select': i === listIndex}"> <span>{{item.name}}</span> </li> </ul> <div v-else class="empty-data">没有符合条件的结果</div> </main> </v-menu> <ul class="studentContainer clear"> <!-- 拖拽内容 --> <draggable :options="studentTable" v-model="studentInfo"> <li v-for="(student,stIndex) in studentInfo" :key="stIndex" :class="{selected: student.id === inputValueId}"> <i></i> <div> <span>{{student.name}}</span> <var>{{student.id}}</var> </div> </li> </draggable> </ul> </div> </my-dialog> </div>
</template>
<script>import myDialog from '@/components/myDialog'import draggable from 'vuedraggable'import {mapState} from 'vuex'export default { name: 'draggableRoster', props: { // 学生列表 studentList: { type: Array, default: ()=>{ return [] } } }, components: { draggable, myDialog }, data(){ return { kSchoolId: this.$common.getSession("userData").school.id, kSchoolYearId: this.$common.getSession("userData").schoolYear.id, studentInfo: [], //学生信息 studentTable: { group: {name: 'draggableRoster'}, sort: true, animation: 150, // ghostClass: 'rosterDraggableGhost', // 拖动影子元素class chosenClass: 'rosterDraggableChosen', // 选中的元素class dragClass: 'rosterDrag', //拖动过程class },//拖拽参数设置 show: false, //一开始隐藏搜索框列表 inputValue: '', //搜索框内容 inputValueId: '', //选中的学生id courseInfomation: {}, //班级信息 listIndex: 0, // 当前keydown的项 } }, computed: { // 下拉列表内的数据 (根据输入框的内容进行筛选) filterList() { if (this.inputValue === '') return this.studentInfo let filterList = []; filterList = this.studentInfo.filter(val => { let {name, firstName} = val; if (name.includes(this.inputValue) || firstName.includes(this.inputValue)) { return true } }) return filterList }, ...mapState('semester',['newSemester']) }, methods: { //打开vuetify的v-dialog弹窗 open(courseInfo) { this.studentInfo = this.studentList; //学生信息赋值 this.courseInfomation = courseInfo; //班级信息赋值 this.$refs.draggable_roster_dialog.open(); //打开vuetify的v-dialog弹窗 }, // 选择下拉列表的一个名字 selectListOne(item) { this.inputValue = item.name; this.inputValueId = item.id; this.show = false; }, // 删除输入框中的内容 deleteInputVal() { this.inputValueId = ''; this.show = true; }, // 列表向下向上键 onKeyDown (e) { const keyCodes = Object.freeze({ enter: 13, up: 38, down: 40, }) if (e.keyCode === keyCodes.down && this.listIndex < this.filterList.length - 1) { this.listIndex++ } else if (e.keyCode === keyCodes.up && this.listIndex > 0) { this.listIndex-- } }, // enter键选中 onKeyEnter(){ let item = this.filterList[this.listIndex] if (!item) { // 没有选择项,点击enter提示 this.$message.warning('请选择学生'); return } else { // 有选择项,点击enter则选择此项 this.selectListOne(item); return } }, // 更改排序 changeMuster() { let studentArr = []; this.studentInfo.forEach(item=>{ studentArr.push(item.id) }) let params = { kSchoolId: this.kSchoolId, kSchoolYearId: this.kSchoolYearId, kSemesterId: this.newSemester.id, kGradeId: this.courseInfomation.kGradeId, classType: this.courseInfomation.classType, studentIdList: studentArr } if(this.courseInfomation.classType === 0) { params.kClassesGroupId = this.courseInfomation.kClassesGroupId; }else{ params.kCourseId = this.courseInfomation.kCourseId; if(this.courseInfomation.classType === 1 || this.courseInfomation.classType === 6) { params.kClassesGroupId = this.courseInfomation.kClassesGroupId; }else{ params.kClassId = this.courseInfomation.kClassId; } } this.$ajax.post(this.$api.SAVE_MUSTER, params).then(res => { if (res.code == 200) { this.$refs.draggable_roster_dialog.close(); //关闭弹窗 this.$message.success('自定义排序成功!'); this.$emit('refreshRoster'); //给父级发送请求,告知父级重新渲染列表 } }); }
},
watch: { // 输入搜索词,index重置为0 inputValue (next, prev) { this.listIndex = 0; //输入框变化时置0.默认选中第一个 }
}}
</script>
<style lang="less" scoped> @import '~@/style/common'; .draggable-content { .search-student { margin-bottom: 20px; input { width: 215px; height: 24px; border-bottom: 1px solid #BEBEBE; color: #4A4A4A; cursor: text; } } .studentContainer { overflow: auto; width: 100%; max-height: 335px; border: 1px solid #C1D4D8; li { float: left; width: 107px; height: 46px; cursor: pointer; border-right: 1px solid #d8d8d8; border-bottom: 2px solid #BDCBB3; i { float: left; width: 16px; height: 44px; margin-right: 1px; } div { float: right; width: 89px; padding-top: 5px; font-size: 14px; line-height: 18px; span { display: block; color: #4A4A4A; .ellipsis1; } var { display: block; color: #A2A2A2; font-style: normal; .ellipsis1; } } } li:nth-child(9n){ border-right: 0; } //拖拽列表鼠标移入时的灰色样式 li:hover { i { background: #D8D8D8 url('~@/assets/yidong.png') center center no-repeat; } } //拖拽列表学生被选中的样式 li.selected { background: #E4F2F3; } //拖拽的绿色样式 .rosterDraggableChosen, .rosterDrag { i { background: #9EC583 url('~@/assets/yidong.png') center center no-repeat !important; } } } } //搜索下拉框的样式.select-wrap { background: #fff; >ul { >li { cursor: pointer; padding-left: 10px; height: 36px; line-height: 36px; &:hover { background: #F5FAFB; } } .key-down-select { background: #F5FAFB; color: #0E858E; } } .empty-data { text-align: center; color: #8C8C8C;; padding-top: 10px; padding-bottom: 10px; } }
</style>复制代码
6.基本配置
option配置项
option配置项
group: string or array 分组用的,同一组的不同list可以相互拖动
sort: boolean 定义是否可以拖拽
delay:number 定义鼠标选中列表单元可以开始拖动的延迟时间
disabled: boolean 定义是否此sortable对象是否可用,为true时sortable对象不能拖放排序等功能
animation: umber 单位:ms 动画时间
handle: selector 格式为简单css选择器的字符串,使列表单元中符合选择器的元素成为拖动的手柄,只有按住拖动手柄才能使列表单元进行拖动
filter: selector 格式为简单css选择器的字符串,定义哪些列表单元不能进行拖放,可设置为多个选择器,中间用“,”分隔
preventOnFilter: 当拖动filter时是否触发event.preventDefault()默认触发
draggable: selector 格式为简单css选择器的字符串,定义哪些列表单元可以进行拖放
ghostClass: selector 格式为简单css选择器的字符串,当拖动列表单元时会生成一个副本作为影子单元来模拟被拖动单元排序的情况,此配置项就是来给这个影子单元添加一个class,我们可以通过这种方式来给影子元素进行编辑样式
chosenClass: selector 格式为简单css选择器的字符串,目标被选中时添加
dragClass:selector 格式为简单css选择器的字符串,目标拖动过程中添加
forceFallback: boolean 如果设置为true时,将不使用原生的html5的拖放,可以修改一些拖放中元素的样式等
fallbackClass: string 当forceFallback设置为true时,拖放过程中鼠标附着单元的样式
dataIdAttr: data-id
scroll:boolean当排序的容器是个可滚动的区域,拖放可以引起区域滚动
scrollFn:function(offsetX, offsetY, originalEvent, touchEvt, hoverTargetEl) { … } 用于自定义滚动条的适配
scrollSensitivity: number 就是鼠标靠近边缘多远开始滚动默认30
scrollSpeed: number 滚动速度复制代码
函数配置
setData: 设置值时的回调函数
onChoose: 选择单元时的回调函数
onStart: 开始拖动时的回调函数
onEnd: 拖动结束时的回调函数
onAdd: 添加单元时的回调函数
onUpdate: 排序发生变化时的回调函数
onRemove: 单元被移动到另一个列表时的回调函数
onFilter: 尝试选择一个被filter过滤的单元的回调函数
onMove: 移动单元时的回调函数
onClone: clone时的回调函数
以上函数对象的属性:
to: 移动到的列表的容器
from:来源列表容器
item: 被移动的单元
clone: 副本的单元
oldIndex:移动前的序号
newIndex:移动后的序号复制代码
7.参考
这篇文章中有更详细的draggable参数配置,需要的可以参考下:
blog.csdn.net/zjiang1994/…
转载于:https://juejin.im/post/5cb59293e51d456e336cd48d
Draggable拖拽相关推荐
- vue.draggable 拖拽 ant 组件布局
vue.draggable 拖拽 项目需求中,需要支持拖拽,即找到了vue.draggable,下面来说一下基本使用方法 1.首先需要安装它,官网地址 https://www.itxst.com/vu ...
- vuedraggable自由拖拽html,vue中draggable拖拽列表的使用
1.安装 npm install vuedraggable 或者使用镜像安装 cnpm install vuedraggable 2.使用 首先在使用的组件中引入 import draggable f ...
- Draggable拖拽+Collapse使用(不一样的手风琴)
插件地址:vuedraggable - npm npm-Draggable插件:vuedraggable 领导前两天给了一个数据结构,根据根据这个数据结构来构建界面. 效果图 现有数据结构 data: ...
- vue3 draggable拖拽
!!首先安装 vuedraggable npm i -S vuedraggable@next 一定要带上@next,不然就会报错 很恶心!使用建议看官网. 官网:vue.draggable中文文档 ...
- draggable拖拽组件使用
项目开发中需要用到拖拽组件,因为前端技术框架是vue,这里就使用了vue的一款拖拽插件vue.draggable,一般基本的需求都能满足,这里使用了多个draggable嵌套,达到两级之前相互拖拽的功 ...
- draggable拖拽组件的使用
背景:左右两个数据栏,左侧为数据源,右侧为组建的目标数据.要实现左侧和右侧可以互相拖拽,但是左侧拖拽到右侧后源数据不变,右侧拖拽到左侧时,无论丢在左侧哪里都回到源数据原来的分组下:并且,左侧和右侧内部 ...
- HTML5 draggable 拖拽实例
HTML5 draggable <!DOCTYPE html> <html lang="en"> <head><meta charset= ...
- vue.draggable拖拽生成课程表
需求 根据数据源提供的科目及教师信息,拖拽至空白课表内,生成一份课表. 需求分析 数据源 首先科目有多个,教师也有多个.数据源部分做一个切换选择科目的效果,选取科目后,提供科目及授课人名字. 课表 课 ...
- Vue.Draggable拖拽功能的配置和使用方法
使用cmd命令在项目根目录下下载安装Vue.Draggable npm install vuedraggable 在组件中需要使用的引入 import draggable from 'vuedragg ...
最新文章
- Dockerfile创建自定义Docker镜像以及CMD与ENTRYPOINT指令的比较
- multiselect多选下拉框
- open表和closed表_excel工作表合并,多文件数据一键合成
- jquery.uploadify flash IE6上传无效
- 美企调查华为设备安全性,华为发长文质疑;摩根大通预计苹果2020年将推5G iPhone;谷歌拟联手Dish成立美国第四大运营商...
- 常见损失函数及正则项
- 基础排序算法···1
- [bzoj 3110] [ZJOI2013] K大数查询
- 外挂(目前看不懂_转帖不要怪我抄袭只是想学习而已)
- 网站安全之为Web项目添加验证码功能(一)
- MAC地址克隆 破解共享上网限制
- 逻辑思维题 微信18954274246 答案
- 想在社会上混 就记住这20句
- Linux - #!/bin/bash 和 #!/usr/bin/env bash 的区别
- OpenOCD-JTAG调试
- goland dlv调试正在运行的程序
- 为什么我的u盘计算机无法识别u盘启动,电脑无法识别u盘怎么办 无法读取u盘解决方法...
- 工时表软件在项目中的作用 帮助企业管理项目成员的工时
- 西门子s7300 C MATLAB,卡尔曼滤波器在s7-300系列plc中的实现方法
- ELK下kibana安装Metricbeat工具