Sortable.js官网地址:http://www.sortablejs.com/index.html
1.安装或者引用组件Sortable.js(三选一)
1.1:npm安装 npm install sortablejs --save
1.2:bower安装:bower install --save sortablejs
1.3:也可以引用:<script src="../../js/Sortable.min.js"></script>
2.使用
<template>
<view id="foo" class="use-menu u-flex grid-test box-shadow border-radius5">
<view class="list u-flex list-item" v-for="(item,index) in list" :key="item">
<image :src="item.icon"></image>
<view class="mt5">{{item.label}}</view>
<text class="icon iconfont icon-shanchu del-btn" style="color: #c0c0c0;" @click="delItemMenu(index)"></text>
</view>
</view>
</template>
<script lang="ts">
import {
ref,
reactive,
onMounted,
} from 'vue'
import Sortable from 'sortablejs'
export default {
setup() {
const list = reactive([{
label: '出差申请',
icon: '../../static/logo.png'
},
{
label: '加班申请',
icon: '../../static/images/nav_car_apply.png'
},
{
label: '出差申请',
icon: '../../static/logo.png'
},
{
label: '出差申请',
icon: '../../static/images/nav_car_apply.png'
},
{
label: '出差申请',
icon: '../../static/logo.png'
},
{
label: '出差申请',
icon: '../../static/images/nav_car_apply.png'
},
{
label: '出差申请',
icon: '../../static/logo.png'
}
])
// 手动删除
function delItemMenu(index) {
if (list.length > 1) {
list.splice(index, 1)
} else {
list.splice(index, 1)
}
}
// 生命周期
onMounted(() => {
Sortable.create(document.getElementById("foo"), {
animation: 150, //动画参数
onAdd: function(evt) {
//拖拽时候添加有新的节点的时候发生该事件
console.log("onAdd.foo:", [evt.item, evt.from]);
},
onUpdate: function(evt) {
//拖拽更新节点位置发生该事件
console.log("onUpdate.foo:", [evt.item, evt.from]);
},
onRemove: function(evt) {
//删除拖拽节点的时候促发该事件
console.log("onRemove.foo:", [evt.item, evt.from]);
},
onStart: function(evt) {
//开始拖拽出发该函数
console.log("onStart.foo:", [evt.item, evt.from]);
},
onSort: function(evt) {
//发生排序发生该事件
console.log("onSort.foo:", [evt.item, evt.from]);
// 索引5移到索引4的位置,索引变化
// evt.newDraggableIndex -- 4
// evt.newIndex --4
// evt.oldDraggableIndex --5
// evt.oldIndex --5
},
onEnd: function(evt) {
//拖拽完毕之后发生该事件
console.log("onEnd.foo:", [evt.item, evt.from]);
},
});
})
return {
// value
list,
}
}
}
</script>
<style lang='scss'>
.use-menu {
display: grid;
grid-template-columns: repeat(auto-fill, 25%);
justify-content: center;
margin: 0 20rpx 10rpx;
padding: 20rpx 0 10rpx;
}
.list {
height: auto;
margin: 20rpx 0;
flex-direction: column;
}
.list-item {
position: relative;
.del-btn {
position: absolute;
right: 5rpx;
top: -16rpx;
font-size: 18px;
}
}
.use-menu .list image {
width: 60rpx;
height: 60rpx;
}
.menu-add-btn {
width: 60rpx;
height: 60rpx;
border-radius: 16rpx;
border: 2rpx solid #c0c0c0;
}
.box-shadow{
box-shadow: 5rpx 5rpx 20rpx rgba(0, 0, 0, 0.2);
}
.border-radius5{
border-radius: 10rpx;
}
</style>