問題描述
Sortable.js是一款優秀的js拖拽庫,因為是原生js寫的,所以性能不錯,也支持移動端哦。本文舉兩個案例來學習一下。
案例一 簡單拖拽
效果圖
代碼附上
關於理解看註釋哦,運行的話複製粘貼即可
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>sortable.js拖動例子</title>
<meta name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, minimal-ui">
<!-- 引入插件 -->
<script src="https://www.itxst.com/package/sortable/sortable.min.js"></script>
<style>
#wrapBox {
width: 360px;
/* 拖動容器的高度,由拖動項的高度撐開 */
height: auto;
}
#wrapBox div {
padding: 8px;
background-color: #fdfdfd;
border: solid 1px #eee;
margin-bottom: 10px;
/* 添加鼠標懸浮樣式為移動的樣式,要不然不好看 */
cursor: move;
font-size: 13px;
}
/* 設置鼠標按下時候的樣式,加了好看些 */
#wrapBox div:active {
background-color: #eee;
}
</style>
</head>
<body>
<h2>優先扣款順序:</h2>
<!-- 一般來説,拖動的結構就是:外邊一個拖動容器,裏面是一個又一個的拖動項 -->
<div id="wrapBox">
<div data-id="1工商銀行">工商銀行</div>
<div data-id="2建設銀行">建設銀行</div>
<div data-id="3中國銀行">中國銀行</div>
<div data-id="4農業銀行">農業銀行</div>
<div data-id="5交通銀行">交通銀行</div>
</div>
<script>
//第一步,獲取拖動容器
var wrap = document.getElementById('wrapBox');
//第二步,設置拖動項的拖動規則
var rules = {
animation: 500, // 拖動時的元素的位置變化的動畫時長,
//拖動結束後的回調函數
onEnd: function (event) {
console.log('參數是拖動事件對象', event);
//獲取拖動後容器中的每一項的位置排序
var arr = sortable.toArray();
console.log('位置排序', arr);
},
};
//第三步,初始化 --> 給拖動容器添加拖動規則
var sortable = Sortable.create(wrap, rules);
/**
* 插件自帶的方法:
* 1. sortable.toArray() 獲取序列化後的每個item元素的id屬性的數組
* 2. Sortable.create(wrap, rules) 給拖動容器添加拖動規則
* */
</script>
</body>
</html>
案例二 el-table表格拖拽
這裏有一個細節,就是表頭數據拖動的時候,可能導致渲染數據不對的問題,有的博主是搞兩個表頭數組數據的,其實也是一種解決問題的方案。不過個人愚見略有麻煩,其實一個表頭數組數據即可。只要及時清空,重新賦值即可
效果圖
代碼附上
這裏使用的是vue,所以要下載哦 cnpm install sortablejs --save
代碼直接複製粘貼即可運行看效果圖了,關於使用請看註釋哦
<template>
<div class="myWrap">
<el-table
:data="tableBody"
border
row-key="id"
:header-cell-style="{
height: '48px',
background: '#FAFAFA',
color: '#333333',
fontWeight: 'bold',
fontSize: '14px',
}"
>
<!-- 勾選框列 -->
<el-table-column type="selection" width="48" fixed></el-table-column>
<!-- 序號列 -->
<el-table-column label="序號" type="index" width="50" fixed>
</el-table-column>
<!-- 表頭列 -->
<el-table-column
v-for="(item, index) in tableHeader"
:key="item.index"
:prop="item.prop"
:label="item.label"
>
</el-table-column>
</el-table>
<br />
<h3>表頭數據</h3>
<pre>{{ tableHeader }}</pre>
<br />
<h3>表體數據</h3>
<pre>{{ tableBody }}</pre>
</div>
</template>
<script>
// 引入sortablejs插件,拖拽主要靠的是這個插件
import Sortable from "sortablejs";
export default {
data() {
return {
// 表頭數據
tableHeader: [
{
label: "姓名",
prop: "name",
},
{
label: "年齡",
prop: "age",
},
{
label: "家鄉",
prop: "home",
},
{
label: "愛好",
prop: "hobby",
},
],
// 表體數據
tableBody: [
{
id: "1",
name: "孫悟空",
age: 500,
home: "花果山",
hobby: "吃桃子",
},
{
id: "2",
name: "豬八戒",
age: 88,
home: "高老莊",
hobby: "吃包子",
},
{
id: "3",
name: "沙和尚",
age: 1000,
home: "通天河",
hobby: "游泳",
},
{
id: "4",
name: "唐僧",
age: 99999,
home: "東土大唐",
hobby: "唸經",
},
],
};
},
mounted() {
// 列的拖拽初始化
this.columnDropInit();
// 行的拖拽初始化
this.rowDropInit();
},
methods: {
//列拖拽
columnDropInit() {
// 第一步,獲取列容器
const wrapperColumn = document.querySelector(
".el-table__header-wrapper tr"
);
// 第二步,給列容器指定對應拖拽規則
this.sortable = Sortable.create(wrapperColumn, {
animation: 500,
delay: 0,
onEnd: (event) => {
console.log(
"拖拽完成以後發現表頭數據並沒有改變,所以需要我們手動更新表頭數據",
this.tableHeader
);
console.log(
"根據舊索引和新索引去更新,其實就是交換位置",
event.oldIndex,
event.newIndex
);
// 接下來做索引的交換
let tempHableHeader = [...this.tableHeader]; // 先存一份臨時變量表頭數據
let temp; // 臨時變量用於交換
temp = tempHableHeader[event.oldIndex - 2]; // 注意這裏-2是因為,我在表格的前面加了兩列(勾選框列,和序號列)
tempHableHeader[event.oldIndex - 2] =
tempHableHeader[event.newIndex - 2]; // 如果沒有這兩列,序號就是正常對應的,就不用減2
tempHableHeader[event.newIndex - 2] = temp;
// 重要的事情説三遍!!!
// 這裏一定要先把表頭數據清空,然後再下一輪中去賦值,否則會渲染錯誤
// 這裏一定要先把表頭數據清空,然後再下一輪中去賦值,否則會渲染錯誤
// 這裏一定要先把表頭數據清空,然後再下一輪中去賦值,否則會渲染錯誤
this.tableHeader = []; // 大家可以注掉試試哦
this.$nextTick(() => {
this.tableHeader = tempHableHeader;
});
},
});
},
// 行拖拽
// 個人認為行拖拽不用加,因為加了以後,就不能雙擊選行單元格的文字了,當然還是要聽產品大佬安排
rowDropInit() {
// 第一步,獲取行容器
const wrapperRow = document.querySelector(
".el-table__body-wrapper tbody"
);
const that = this; // 存一份指向
// 第二步,給行容器指定對應拖拽規則
Sortable.create(wrapperRow, {
onEnd({ newIndex, oldIndex }) {
// 這裏是區分上面的列拖拽的另外一種寫法
// 首先刪除原來的那一項,並且保存一份原來的那一項,因為splice返回的是一個數組,數組中的第一項就是刪掉的那一項
const currRow = that.tableBody.splice(oldIndex, 1)[0];
// 然後把這一項加入到新位置上
that.tableBody.splice(newIndex, 0, currRow);
},
});
},
},
};
</script>
<style lang='less' scoped>
.myWrap {
width: 100%;
height: 100%;
box-sizing: border-box;
padding: 25px;
/deep/ .el-table {
.el-table__header-wrapper {
tr {
th {
// 設置拖動樣式,好看一些
cursor: move;
}
}
}
}
}
</style>
好記性不如爛筆頭,記錄一下吧 ^_^
最後附上官網:http://www.sortablejs.com/
或 https://www.itxst.com/sortabl...