拖拽功能(列表拖拽) vue + 移动端 + vuedraggable
拖拽列表效果图:
1. 安装 yarn add vuedraggable 或者 npm install vuedraggable
2.新建文件夹 tagManage.vue
代码如下:
<template>
<div class="home">
<div class="drag-wrap">
<draggable
v-model="myArray"
chosenClass="chosen"
forceFallback="true"
group="people"
animation="200"
@start="onStart"
@end="onEnd"
:fallbackTolerance="3"
>
<transition-group>
<div
class="card"
v-for="item in myArray"
:key="item.id"
@click.stop="checkFun(item)"
>
<div class="left">
<img
v-if="item.isTrue == false"
src="@/assets/images/34.png"
alt=""
/>
<img v-else src="@/assets/images/35.png" alt="" />
</div>
<div class="min">
<p>{{ item.name }}</p>
<p>
<span @click.stop="editor(item)">编辑</span>
<span @click.stop="deleteTor(item)">删除</span>
</p>
</div>
</div>
</transition-group>
</draggable>
</div>
<div class="inviteWrap">
<div class="left" @click.stop="checkAllFun">
<p>
<img v-if="isCheckAll == false" src="@/assets/images/34.png" alt="" />
<img v-else src="@/assets/images/35.png" alt="" />
<span>全选</span>
</p>
<p>
已选择 <i> {{ checkNum }} </i> 标签
</p>
</div>
<div class="right" @click.stop="signInvitationFun">
<span>删除</span>
</div>
</div>
<img class="fixedImg" @click="addTag" src="@/assets/images/89.png" alt="" />
<van-action-sheet
class="relationshipWrap"
v-model="showRelationship"
:title="title"
>
<div class="wrap">
<textarea
class="textarea"
placeholder="请输入标签名称"
v-model="tagName"
></textarea>
<div class="btn">
<span @click="reset">取消</span>
<span @click="relationshipSure">确定</span>
</div>
<div class="borderBottom"></div>
</div>
</van-action-sheet>
</div>
</template>
<script>
import draggable from "vuedraggable";
import {
defined_tag_query_list,
defined_tag_sort,
defined_tag_add,
update_tag,
delete_tag,
} from "@/request/api/http.js";
import { Toast, Dialog } from "vant";
export default {
components: {
draggable,
},
data() {
return {
currentDingtalk: {},
drag: false,
//定义要被拖拽对象的数组
myArray: [],
isCheckAll: false,
checkNum: 0,
showRelationship: false,
title: "新增标签55",
tagName: "",
tagChange: null,
editorObj: {},
};
},
mounted() {
this.currentDingtalk = JSON.parse(sessionStorage.getItem("userInfo"));
this.init();
},
methods: {
init() {
this.tagQueryListFun();
},
tagQueryListFun() {
let that = this;
that.myArray = [
{
name: "严重精神病障碍",
id: 7,
value: 7,
},
{
name: "高血压",
id: 2,
value: 2,
},
{
name: "阿尔兹海默症",
id: 10,
value: 10,
},
{
name: "心脏病患者",
id: 22,
value: 22,
},
{
name: "慢阻肺",
id: 12,
value: 12,
},
{
name: "65岁以上重点老人",
id: 9,
value: 9,
},
{
name: "二型糖尿病",
id: 3,
value: 3,
},
{
name: "其他",
id: 21,
value: 21,
},
];
for (let i = 0; i < this.myArray.length; i++) {
that.myArray[i].isTrue = false;
}
},
//开始拖拽事件
onStart() {
this.drag = true;
},
//拖拽结束事件
onEnd() {
this.drag = false;
let param = {
organization_id: this.currentDingtalk.organization_id,
doctor_job_number: this.currentDingtalk.doctor_job_number,
doctor_card_number: this.currentDingtalk.doctor_card_number,
list: this.myArray,
};
defined_tag_sort(param).then((res) => {
Toast.clear();
if (res.code == 200) {
console.log(res.data);
} else {
Toast.fail(res.message);
}
});
},
checkFun(item, num) {
let that = this;
item.isTrue = !item.isTrue;
let dataList = [];
for (let i = 0; i < this.myArray.length; i++) {
if (this.myArray[i].isTrue == true) {
dataList.push(this.myArray[i]);
}
}
this.checkNum = dataList.length;
if (dataList.length == this.myArray.length && dataList.length != 0) {
this.isCheckAll = true;
} else {
this.isCheckAll = false;
}
that.$forceUpdate();
},
checkAllFun() {
if (this.isCheckAll == false) {
this.checkNum = this.myArray.length;
this.isCheckAll = true;
for (let i = 0; i < this.myArray.length; i++) {
this.myArray[i].isTrue = true;
}
} else {
this.checkNum = 0;
this.isCheckAll = false;
for (let i = 0; i < this.myArray.length; i++) {
this.myArray[i].isTrue = false;
}
}
},
reset() {
this.showRelationship = false;
},
addTag() {
this.tagName = "";
this.showRelationship = true;
this.title = "新增标签";
this.tagChange = 1;
},
editor(item) {
this.editorObj = {};
this.title = "修改标签";
this.tagName = item.name;
this.showRelationship = true;
this.tagChange = 2;
this.editorObj = item;
},
deleteTor(item) {
let that = this;
Dialog.alert({
title: "提示",
message: "确定要删除此项标签么?",
cancelButtonText: "取消",
confirmButtonText: "确定",
showCancelButton: true,
confirmButtonColor: "#316FFE",
}).then(() => {
let param = {
organization_id: this.currentDingtalk.organization_id,
doctor_job_number: this.currentDingtalk.doctor_job_number,
doctor_card_number: this.currentDingtalk.doctor_card_number,
tag_id: item.id,
};
Toast.loading({
duration: 0, // 持续展示 toast
forbidClick: true,
});
delete_tag(param).then((res) => {
Toast.clear();
if (res.code == 200) {
Toast.success("删除成功");
setTimeout(function () {
that.tagQueryListFun();
}, 500);
} else {
Toast.fail(res.message);
}
});
});
},
relationshipSure() {
let that = this;
if (
(this.tagName == "" && this.tagChange == 1) ||
(this.tagName == "" && this.tagChange == 2)
) {
Toast.fail("请输入标签名称");
return false;
} else if (this.tagName != "" && this.editorObj.name == this.tagName) {
Toast.fail("标签名称重复,请重新输入");
return false;
} else {
if (this.tagChange == 1) {
let param = {
organization_id: this.currentDingtalk.organization_id,
doctor_job_number: this.currentDingtalk.doctor_job_number,
doctor_card_number: this.currentDingtalk.doctor_card_number,
name: this.tagName,
};
Toast.loading({
duration: 0, // 持续展示 toast
forbidClick: true,
});
defined_tag_add(param).then((res) => {
Toast.clear();
if (res.code == 200) {
Toast.success("新增标签成功");
setTimeout(function () {
that.showRelationship = false;
that.tagQueryListFun();
}, 500);
} else {
Toast.fail(res.message);
}
});
} else if (this.tagChange == 2) {
let param = {
organization_id: this.currentDingtalk.organization_id,
doctor_job_number: this.currentDingtalk.doctor_job_number,
doctor_card_number: this.currentDingtalk.doctor_card_number,
name: this.tagName,
id: this.editorObj.id,
};
Toast.loading({
duration: 0, // 持续展示 toast
forbidClick: true,
});
update_tag(param).then((res) => {
Toast.clear();
if (res.code == 200) {
Toast.success("编辑标签成功");
setTimeout(function () {
that.showRelationship = false;
that.tagQueryListFun();
}, 500);
} else {
Toast.fail(res.message);
}
});
}
}
},
signInvitationFun() {
let dataList = [];
for (let i = 0; i < this.myArray.length; i++) {
if (this.myArray[i].isTrue == true) {
dataList.push(this.myArray[i].id);
}
}
if (dataList && dataList.length <= 0) {
Toast.fail("删除标签不能为空");
return false;
}
Dialog.alert({
title: "提示",
message: "确定要删除此" + dataList.length + "项标签么?",
cancelButtonText: "取消",
confirmButtonText: "确定",
showCancelButton: true,
confirmButtonColor: "#316FFE",
}).then(() => {
let param = {
organization_id: this.currentDingtalk.organization_id,
doctor_job_number: this.currentDingtalk.doctor_job_number,
doctor_card_number: this.currentDingtalk.doctor_card_number,
tag_id: item.id,
};
Toast.loading({
duration: 0, // 持续展示 toast
forbidClick: true,
});
delete_tag(param).then((res) => {
Toast.clear();
if (res.code == 200) {
Toast.success("删除成功");
setTimeout(function () {
that.tagQueryListFun();
}, 500);
} else {
Toast.fail(res.message);
}
});
});
},
},
};
</script>
<style lang="scss" scoped>
.home {
padding-bottom: calc(85px + constant(safe-area-inset-bottom));
padding-bottom: calc(85px + env(safe-area-inset-bottom));
/*被拖拽对象的样式*/
// .item {
// padding: 6px;
//
// border: solid 1px #eee;
// margin-bottom: 10px;
// cursor: move;
// }
/*选中样式*/
.drag-wrap {
background: #fff;
display: inline-block;
margin: 15px 15px 0 15px;
width: calc(100% - 30px);
border-radius: 6px;
overflow: hidden;
.card {
border-bottom: 0.5px solid #e5e6eb;
border-left: 0.5px solid #fff;
border-right: 0.5px solid #fff;
border-top: 0.5px solid #fff;
&:nth-last-child(1) {
border-bottom: 0;
}
.left {
display: inline-block;
vertical-align: top;
padding: 18px 15px;
img {
display: block;
width: 20px;
height: 20px;
}
}
.min {
display: inline-block;
vertical-align: top;
width: calc(100% - 50px);
position: relative;
padding: 18px 0;
p {
&:nth-child(1) {
max-width: calc(100% - 150px);
font-size: 15px;
color: #333;
}
&:nth-child(2) {
position: absolute;
top: 19px;
right: 15px;
span {
font-size: 12px;
color: #316ffe;
border: 0.5px solid #316ffe;
font-weight: 700;
padding: 4px 16px;
border-radius: 12px;
margin-right: 10px;
&:nth-child(2) {
color: #ff503d;
border-color: #ff503d;
margin-right: 0;
}
}
}
}
}
&.chosen {
border: 0.5px solid #3089dc !important;
}
}
}
.inviteWrap {
position: fixed;
bottom: 0;
background: #fff;
width: 100%;
left: 0px;
padding: 12px 0;
padding-bottom: calc(10px + constant(safe-area-inset-bottom));
padding-bottom: calc(10px + env(safe-area-inset-bottom));
.left {
position: absolute;
top: calc(50% - 12px);
transform: translateY(-50%);
left: 0px;
padding: 12px 15px;
p {
img {
display: inline-block;
vertical-align: middle;
width: 20px;
height: 20px;
margin-right: 5px;
}
span {
display: inline-block;
vertical-align: middle;
font-size: 15px;
color: #222;
}
&:nth-child(2) {
margin-top: 5px;
font-size: 13px;
color: #999;
i {
font-style: normal;
color: #316ffe;
}
}
}
}
.right {
text-align: right;
span {
display: inline-block;
border: 0.5px solid #ff503d;
color: #ff503d;
font-size: 16px;
font-weight: 700;
padding: 12px 50px;
border-radius: 100px;
margin-right: 15px;
}
}
}
.fixedImg {
position: fixed;
bottom: 100px;
right: 15px;
width: 40px;
height: 40px;
}
::v-deep .van-popup {
&.relationshipWrap {
.van-action-sheet__header {
font-weight: 700;
font-size: 16px;
color: #333;
}
.wrap {
margin-top: 6px;
.textarea {
border: 0.5px solid #e5e6eb;
width: calc(100% - 50px);
margin-left: 15px;
border-radius: 4px;
height: 96px;
padding: 10px;
font-size: 15px;
&::placeholder {
color: #999;
}
}
.btn {
padding: 20px 15px;
span {
display: inline-block;
width: calc(50% - 7px);
font-size: 16px;
color: #999;
text-align: center;
padding: 10px 0;
border-radius: 100px;
border: 0.5px solid #cfcfcf;
&:nth-child(2) {
background: #316ffe;
color: #fff;
margin-left: 10px;
border-color: #316ffe;
}
}
}
}
}
}
}
</style>