sortable使用小知识(vue)-- 使用sortable拖拽插件在初始化循环标签的状态下,如何获取拖拽的数据
废话大家搜索这个基本都知道这个插件是干啥的,那我就不废话了。如果真的有人不晓得的话,点这个: sortable.js中文文档。问题场景当时产品拿着一个示例给我,我就要做成这样的。emmm,我看了下。右边的信号源列表拖拽到左边的显示列表的子元素内。表示那个显示装置接收了哪个信号源。了解后我向产品表达了自己的理解,你给我的这个拖拽过去后没有显示,用户都不知道拖拽成功没,而且也成功了也可能会出现不晓得拖
废话
大家搜索这个基本都知道这个插件是干啥的,那我就不废话了。如果真的有人不晓得的话,点这个: sortable.js中文文档。
问题场景
当时产品拿着一个示例给我,我就要做成这样的。
emmm,我看了下。右边的信号源列表拖拽到左边的显示列表的子元素内。表示那个显示装置接收了哪个信号源。
了解后我向产品表达了自己的理解,你给我的这个拖拽过去后没有显示,用户都不知道拖拽成功没,而且也成功了也可能会出现不晓得拖到哪个去了的情况,要不要拖过去后就显示在显示列表的子元素下面(即投影仪下面)
就像这样
唉,产品却这样回复我
唉,好吧。满足他…
第一步 —— 安装插件
安装
npm install sortablejs --save
引入(这里用的局部引入)
import Sortable from 'sortablejs'
不太清楚的,走这: sortable.js中文文档。
第二步 —— 使用
先讲下使用方法(这里是从官网拖的案例)
<div id="itxst">
<div data-id="1">item 1</div>
<div data-id="2">item 2</div>
<div data-id="3">item 3</div>
</div>
<script>
//获取对象
var el = document.getElementById('itxst');
//设置配置
var ops = {
animation: 1000,
//拖动结束
onEnd: function (evt) {
console.log(evt);
//获取拖动后的排序
var arr = sortable.toArray();
alert(JSON.stringify(arr));
},};
//初始化
var sortable = Sortable.create(el, ops);
</script>
使用起来还是比较简单的,只需要获取节点对象,然后再设置配置,最后进行初始化就完事了。我们用vue的话可以用ref获取节点。关于配置方面我就不细说,不懂得还是走这: sortable.js中文文档。
第三步 —— 分析
根据产品的描述来看,我这里其实需要对三个对象进行配置(添加拖拽)
一个是信号源列表,第二、第三分别是投影仪和投影仪2。但是显示这一块是从接口获取的数据,并不是所有的都是2个。好吧,需要添加拖拽的还不止3个。
那么我们就用循环来解决:先通过for循环循环出显示列表,然后在li里面添加ul标签,这里我用的ref,通过left + id值来进行区分(使用id是因为它具有唯一性,不是非要用id)
<ul ref="left">
<li class="target" :id="item.id" :name="item.name" :value="item.value"
v-for="(item,index) in matrixDetail.outs" :key="index">
<div class="normal-row-flex info-card-child">
<div>{{item.name}}</div>
<div class="normal-row-flex equipment">
<img src="@/assets/images/输出2.png" alt="">
</div>
</div>
<ul :ref="'left' + item.id" :id="item.id">
</ul>
<div class="drag-up" v-if="dragStatus" :id="item.id+'up'" :name="item.name+'up'" :value="item.value+'up'"></div>
</li>
</ul>
再通过forEarch进行循环配置
let this_ = this
var sortables = []// 配置数组
// console.log(this.matrixDetail.outs.length)
this.matrixDetail.outs.forEach((item, index) => {
// console.log(this_.$refs[`left${item.id}`])
sortables[index] = Sortable.create(this_.$refs[`left${item.id}`][0], {
group: {
name: "words",
// pull: 'clone',
put: true
},
animation: 150, //动画参数
// 开始拖拽
onChoose: function (evt) {
this_.$emit("handleIfSwipeabl", false)// 这里是为了解决拖拽操作和滑动切换冲突问题的
},
// 拖拽结束
onEnd: function (evt) {
this_.$emit("handleIfSwipeabl", true)// 这里是为了解决拖拽操作和滑动切换冲突问题的
},
})
});
接下来是信号源的代码:
这里注意:给li标签添加 data-id / id 属性(取值就是唯一值)
<ul ref="right">
<li class="normal-row-flex info-card option" :id="item.id" :name="item.name" :value="item.value" draggable="true"
v-for="(item,index) in matrixDetail.ins" :key="index" :data-id="item.id">
<div>{{item.name}}</div>
<div class="normal-row-flex equipment">
<img src="@/assets/images/输出.png" alt="">
<div>
<div class="normal-row-flex equipment-list" v-for="(itm,idx) in item.showItem" :key="idx">
<span>{{itm}}</span>
<span class="handle" @click="signalOff(itm,index,idx)">断开</span>
</div>
</div>
</div>
</li>
</ul>
js逻辑:
- 通过 evt.clone.id 获取克隆的元素(拖拽的信号源)的id(就是之前要添加的data-id / id )
- 通过 evt.to.id 获取拖拽的目的元素的id(即投影仪)
- 根据产品的要求,删掉拖拽过去的元素(看代码)
- 通过filter和唯一值过滤出目标元素的所有数据,方便传参
- 写好参数,发送请求
Sortable.create(this.$refs.right, {
group: {
name: "words",
pull: 'clone',
put: false
},
animation: 150, //动画参数
// 开始拖拽
onChoose: function (evt) {
this_.$emit("handleIfSwipeabl", false)
},
// 拖拽结束
onEnd: function (evt) {
this_.$emit("handleIfSwipeabl", true)
//console.log(evt.clone.id)//被拖拽的
//console.log(evt.to.id)// 拖拽的目的地
if(evt.to.id){
// 根据产品的要求,删掉拖拽过去的元素
let ul = this_.$refs[`left${evt.to.id}`]
ul[0].children.forEach((item, index) => {
ul[0].removeChild(item);
})
// 通过filter和唯一值过滤出目标元素的所有数据,方便传参
let objItem = this_.matrixDetail.ins.filter(item => {
return item.id == evt.clone.id
})
let outItem = this_.matrixDetail.outs.filter(item => {
return item.id == evt.to.id
})
let obj = {
inId: objItem[0].id,
inName: objItem[0].name,
inValue: objItem[0].value,
outId: outItem[0].id,
outName: outItem[0].name,
outValue: outItem[0].value,
}
// 接口
sendCommandAdd({
equipmentId: this_.matrixDetail.id,
command: "switch",
paramObj: obj
}).then((res) => {
if (res.data.status == 1) {
this_.$dialog.alert({
message: "切换完成!",
})
} else {
this_.$dialog.alert({
message: res.data.message,
})
}
})
}
}
})
这样就满足了产品的需求。
更多推荐
所有评论(0)