vue 拖拽排序组件——Vue.Draggable / 自定义指定的随机拖拽
vue 2017-11-16 14:27:08

参考文档:

已封装的vue第三方扩展组件git:https://github.com/SortableJS/Vue.Draggable 

 

介绍

vuedraggable

 

安装 (安装两个依赖)

通过npm安装

C/C++ Code复制内容到剪贴板
  1. npm install vuedraggable sortable --save  

 

 

插件应用

用draggable包裹被拖拽的元素,options是拖拽效果行为的相关配置,和sortable的配置基本完全一样,start end move是相关事件。 

XML/HTML Code复制内容到剪贴板
  1. <template>  
  2.     <draggable v-model="selectedLessonList" :options="{group:'people'}" @start="dropStart" @end="dropEnd" :move="checkMove">  
  3.   
  4.         <ul v-for="item in selectedLessonList">  
  5.             <li>  
  6.                 <i class="control-icon up-icon"></i><span>{{item.label}}</span>  
  7.             </li>  
  8.         </ul>  
  9.   
  10.     </draggable>  
  11. </template>  
  12. <script>  
  13.     import draggable from 'vuedraggable'  
  14.     export default {  
  15.         name: 'teachPlanForm',  
  16.         data() {  
  17.             return {  
  18.                 selectedLessonList: [], //已选择的课程数组  
  19.             }  
  20.         },  
  21.         components: {  
  22.             draggable  
  23.         },  
  24.         mounted() { // 这个是页面创建的时候,就执行相关的方法    
  25.             this.init()  
  26.         },  
  27.         methods: {  
  28.             dropStart() {  
  29.                 console.log("开始拖动");  
  30.             },  
  31.             dropEnd(evt) {  
  32.                 // 拖动结束  
  33.                 console.log('拖动前的索引 :' + evt.oldIndex);  
  34.                 console.log('拖动后的索引 :' + evt.newIndex);  
  35.                 console.log(this.selectedLessonList);//已被改变后的数组  
  36.             },  
  37.             checkMove() {  
  38.                 console.log("检测移动时状态");  
  39.             },  
  40.         }  
  41.     }  
  42. </script>  

 

 


 

自定义指令的随机拖拽: 

XML/HTML Code复制内容到剪贴板
  1. <!-- 自定义指令v-drag -->  
  2. <div class="study_icon" v-drag="greet"></div>  

 

JavaScript Code复制内容到剪贴板
  1. <script>  
  2.     export default {  
  3.         methods: {  
  4.             greet(val) { // 接受传来的坐标  
  5.                 console.log(val)  
  6.             }  
  7.         },  
  8.         directives: { //自定义拖拽功能  
  9.             drag: {  
  10.                 bind: function(el, binding) {  
  11.                     let oDiv = el; //当前元素  
  12.                     oDiv.addEventListener('touchstart'function(e) {  
  13.                         let footerH = document.getElementsByTagName('footer')[0].clientHeight;  
  14.                         let touches = e.touches[0];  
  15.                         //鼠标按下,计算当前元素距离可视区的距离  
  16.                         let disX = touches.clientX - oDiv.offsetLeft;  
  17.                         let disY = touches.clientY - oDiv.offsetTop;  
  18.   
  19.                         oDiv.addEventListener('touchmove'function(e) {  
  20.                             let touches = e.touches[0];  
  21.                             let widowW = document.body.clientWidth;  
  22.                             let windowH = document.body.clientHeight;  
  23.                             //console.log(widowW);  
  24.                             //通过事件委托,计算移动的距离  
  25.                             let l = touches.clientX - disX;  
  26.                             let t = touches.clientY - disY;  
  27.                             if(l <= 0) {  
  28.                                 l = 0;  
  29.                             } else if(l > document.documentElement.clientWidth - oDiv.offsetWidth) {  
  30.                                 l = document.documentElement.clientWidth - oDiv.offsetWidth;  
  31.                             }  
  32.                             if(t <= 0) {  
  33.                                 t = 0;  
  34.                             } else if(t > document.documentElement.clientHeight - oDiv.offsetHeight - footerH) {  
  35.                                 t = document.documentElement.clientHeight - oDiv.offsetHeight - footerH;  
  36.                             }  
  37.                             //移动当前元素  
  38.                             oDiv.style.left = l + 'px';  
  39.                             oDiv.style.top = t + 'px';  
  40.   
  41.                             event.preventDefault(); //阻止冒泡  
  42.                               
  43.                             // 可注释start  将此时的位置传出去 ,这一段,可以注释,是传输位置坐标的  
  44.                             binding.value({  
  45.                                 x: touches.pageX,  
  46.                                 y: touches.pageY  
  47.                             })  
  48.                             // 可注释end   
  49.   
  50.                         });  
  51.                         oDiv.addEventListener('touchend'function(e) {  
  52.                             document.ontouchmove = null;  
  53.                             document.ontouchend = null;  
  54.                         });  
  55.                     });  
  56.   
  57.                 }  
  58.             }  
  59.         }  
  60.     }  
  61. </script>  

 

 


 实例:拖拽排序 + 上下按键排序

QQ截图20171213175718.png

XML/HTML Code复制内容到剪贴板
  1. <div class="clear plan-list" v-if="selectedLessonList.length">  
  2.   
  3.     <draggable v-model="selectedLessonList" @end="dropEnd">  
  4.         <ul v-for="(item,index) in selectedLessonList" :data-id="item.value" :key="item.value">  
  5.             <li>  
  6.                 <i class="control-icon up-icon" @click="sort(index,0)"></i>  
  7.                 <i class="control-icon down-icon" @click="sort(index,1)"></i>  
  8.                 <span>{{item.label}}</span>  
  9.                 <i class="fr delete-icon" aria-hidden="true" @click="delSelectedLesson(item.value)"></i>  
  10.             </li>  
  11.         </ul>  
  12.     </draggable>  
  13.   
  14. </div>  

 

 

 

JavaScript Code复制内容到剪贴板
  1. <script>  
  2.     import draggable from 'vuedraggable'  
  3.     import teachPlanChooseLesson from '@/components/common/addCourse/teachPlanChooseLesson.vue'  
  4.   
  5.     export default {  
  6.         name: 'teachPlanForm',  
  7.         data() {  
  8.             return {  
  9.                 popupVisible: false//弹出层默认关闭  
  10.                 teach_title: ''//标题  
  11.                 selectedLessonList: [], //已选择的课程数组  
  12.                 selectedLessonIds: [], //已选择的课程ID数组  
  13.                 linkId: ""//关联ID  
  14.             }  
  15.         },  
  16.         props: ['planId'],  
  17.         components: {  
  18.             chooseLesson: teachPlanChooseLesson,  
  19.             draggable  
  20.         },  
  21.         mounted() { // 这个是页面创建的时候,就执行相关的方法    
  22.             this.init()  
  23.         },  
  24.         methods: {  
  25.             selectedLesson(selected, ids) {  
  26.                 // 监听子层的选择课程库,重新渲染dom,并且存储已选择的id  
  27.                 this.selectedLessonIds = ids;  
  28.                 this.$set(this"selectedLessonList", selected);  
  29.             },  
  30.             delSelectedLesson(id) {  
  31.                 // 删除已选择的课时,同时传输给子层  
  32.                 this.removeByValue(this.selectedLessonList, id); //删除v-for中的其中一组  
  33.                 this.removeByKey(this.selectedLessonIds, id); //删除给子层和接口用的ids  
  34.                 this.$set(this"selectedLessonList"this.selectedLessonList); //重新渲染列表  
  35.             },  
  36.             removeByValue(arr, val) {  
  37.                 // 查询value中是否有这个值,如果有就去除这个数组    
  38.                 for(var i = 0; i < arr.length; i++) {  
  39.                     if(arr[i].value == val) {  
  40.                         arr.splice(i, 1);  
  41.                         break;  
  42.                     }  
  43.                 }  
  44.             },  
  45.             removeByKey(arr, val) {  
  46.                 // 查询key中是否有这个值,如果有就去除这个数组    
  47.                 for(var i = 0; i < arr.length; i++) {  
  48.                     if(arr[i] == val) {  
  49.                         arr.splice(i, 1);  
  50.                         break;  
  51.                     }  
  52.                 }  
  53.             },  
  54.             submitForm() {  
  55.                 //提交表单  
  56.                   
  57.                 let newItems = [];  
  58.                 this.selectedLessonList.forEach(function(item) {  
  59.                     newItems.push(item.value);  
  60.                 });  
  61.                 let lessonList = newItems ? newItems.join(",") : ""// 拖拽排序的那一组数据,抽取它的ID组成新的值给后端  
  62.   
  63.             },  
  64.             dropStart() {  
  65. //              console.log("开始拖动");  
  66.             },  
  67.             dropEnd(evt) {  
  68.                 // 拖动结束后重组 传给接口的id  
  69.                 //console.log(newItems);  
  70.             },  
  71.             //点击排序  
  72.             sort(key, status) {   
  73.                 let allData = this.selectedLessonList;  
  74.                 if(status) {  
  75.                     if(key != (allData.length - 1)) { //index等于最大下不去  
  76.                         let items //临时变量  
  77.                         items = allData[key + 1];  
  78.                         allData[key + 1] = allData[key];  
  79.                         allData[key] = items;  
  80.                         this.$nextTick(function () {  
  81.                             this.selectedLessonList = [];  
  82.                             this.selectedLessonList = allData;  
  83.                         })  
  84.                     }  
  85.                 } else {  
  86.                     if(key) { //key=0上不去  
  87.                         let temp = ""//临时变量  
  88.                         temp = allData[key - 1];  
  89.                         allData[key - 1] = allData[key];  
  90.                         allData[key] = temp;  
  91.                         this.$nextTick(function () {  
  92.                             this.selectedLessonList = [];  
  93.                             this.selectedLessonList = allData;  
  94.                         })  
  95.                           
  96.                     }  
  97.                 }  
  98.             }  
  99.               
  100.         }  
  101.     }  
  102. </script>  

 

 

本文来自于:http://www.yoyo88.cn/study/vue/212.html

下一篇 vue v-if
Powered by yoyo苏ICP备15045725号