案例1(时间戳排序)
<template>
<view class="">
<text @tap="shijian">打印一下</text>
</view>
</template>
<script>
export default {
data() {
return {
list: [{
"createDate": "12月06日",
"orderNum": "23",
"sales": "631.60"
}, {
"createDate": "12月08日",
"orderNum": "1",
"sales": "0.02"
}, {
"createDate": "12月07日",
"orderNum": "1",
"sales": "12.02"
}, {
"createDate": "12月05日",
"orderNum": "1",
"sales": "2.03"
}]
}
},
methods: {
shijian(){
this.list.sort((a,b)=>{
let aTimeS=a.createDate
let bTimeS=b.createDate
aTimeS=aTimeS.replace(/月/g,'-') //将'月' 替换为 '-' 即12-05
bTimeS=bTimeS.replace(/月/g,'-')
let aTimeSS=aTimeS.replace(/日/g,'')
let bTimeSS=bTimeS.replace(/日/g,'')
let aTime=new Date(aTimeSS).getTime()//转换为距1970年的毫秒
let bTime=new Date(bTimeSS).getTime()
return bTime -aTime //降序排列
})
console.log('this.list.',this.list)
},
}
}
</script>
心得:朋友想对后端返回的数据,按照时间高低的进行排序渲染,由于返回的数据是无序的,所以需要前端做下排序。于是我尝试,forEach将月、日字段去除,生成临时数组做排序,但是过程有点复杂费脑子。方法是网上搜了下,结合自身实际情况实现的。这里的方法,重点在于:new Date(aTimeSS).getTime() 最终放入的 aTimeSS, 你可以放入 如2022-12-05 12:22 或是像我传入12-05。 最终排序是通过转毫秒 实现升降的。
案例2(权重排序)(此案例引入了element库组件,通过插件Sortable实现排序)
<template>
<div class="bg_color">
<div>
<div class="cententReport"><span>手动排序游戏</span></div>
<div class="paixu">
<div class="paixu_left">
<div class="paixu_head">已添加的游戏({{ tableData2.length }})</div>
<div class="paixu_center">
<el-select
v-model="value"
clearable
placeholder="请选择"
style="width: 190px"
>
<el-option
v-for="item in options"
:key="item.gcId"
:label="item.name"
:value="item.gcId"
>
</el-option>
</el-select>
<el-input
v-model="input"
placeholder="请输入游戏名称"
style="margin: 0 20px"
clearable
></el-input>
<el-button type="primary" @click="editing_search('1')"
>查询</el-button
>
</div>
<div>
<el-table
size="small"
style="width: 100%; height: 290px; overflow-y: scroll"
:header-cell-style="{
background: '#F6F8FB',
color: '#333333',
fontSize: '14px',
}"
:data="tableData2"
border
align="left"
>
<template slot="empty">
<img src="../../../assets/img/channel/zwu.png" alt="" />
<div>~暂无数据~</div>
</template>
<el-table-column
show-overflow-tooltip
align="center"
v-for="(item, index) in col"
:key="`col_${index}`"
:prop="col[index].prop"
:label="item.label"
>
<template slot-scope="scope">
<p>{{ scope.row[item.prop] }}</p>
<p v-if="item.label === '操作'">
<el-button
@click="gameDelete(scope.row)"
type="text"
size="small"
>删除</el-button
>
</p>
</template>
</el-table-column>
</el-table>
</div>
</div>
<div class="jiantou">
<i class="el-icon-d-arrow-left"></i>
</div>
<div class="paixu_left">
<div class="paixu_head">所有游戏</div>
<div class="paixu_center">
<el-select
v-model="value2"
clearable
placeholder="请选择"
style="width: 190px"
>
<el-option
v-for="item in options"
:key="item.gcId"
:label="item.name"
:value="item.gcId"
>
</el-option>
</el-select>
<el-input
v-model="input2"
placeholder="请输入游戏名称"
style="margin: 0 20px"
clearable
></el-input>
<el-button type="primary" @click="editing_search('2')"
>查询</el-button
>
</div>
<div>
<el-table
size="small"
style="width: 100%; height: 290px; overflow-y: scroll"
:header-cell-style="{
background: '#F6F8FB',
color: '#333333',
fontSize: '14px',
}"
:data="tableData3"
border
align="left"
>
<template slot="empty">
<img src="../../../assets/img/channel/zwu.png" alt="" />
<div>~暂无数据~</div>
</template>
<el-table-column
show-overflow-tooltip
align="center"
v-for="(item, index) in col"
:key="`col_${index}`"
:prop="col[index].prop"
:label="item.label"
>
<template slot-scope="scope">
<p>{{ scope.row[item.prop] }}</p>
<p v-if="item.label === '操作'">
<el-button
@click="gameAdd(scope.row)"
type="text"
size="small"
>添加</el-button
>
</p>
</template>
</el-table-column>
</el-table>
</div>
</div>
</div>
<div class="footer2">
<el-button type="primary" @click="editing_keep">保存</el-button>
</div>
</div>
<div>
<div class="cententReport"><span>编辑</span></div>
<div class="details_list">
<el-table
border
:data="tableData"
:header-cell-style="{
background: '#F6F8FB',
color: '#333333',
width: '100%',
fontSize: '14px',
}"
>
<template slot="empty">
<div>~暂无数据~</div>
</template>
<el-table-column prop="title" label="栏目名称" align="center">
</el-table-column>
<el-table-column label="栏目状态" align="center" min-width="180">
<template slot-scope="scope">
<el-radio-group v-model="scope.row.isHide">
<el-radio :label="1" v-model="radioel">可见</el-radio>
<el-radio :label="2" v-model="radioel">隐藏</el-radio>
</el-radio-group>
</template>
</el-table-column>
<el-table-column prop="number" label="栏目显示" align="center">
</el-table-column>
</el-table>
</div>
</div>
</div>
</template>
<script>
import {
getInfo,
addedGameList,
getGameList,
update,
gamegetClassList,
} from "../../../service/liangzhuopan";
import Sortable from "sortablejs";
export default {
name: "PromoterDetails",
components: {
Sortable,
},
data() {
return {
token: sessionStorage.getItem("token"),
channelId: this.$route.query.channelId,
tableData: [], //推广员列表数据
tableData2: [],
tableData3: [],
radioel: "", //是否隐藏 1显示 2隐藏
value: "", //已添加,下拉框值
value2: "", //所有游戏,下拉框值
input: "", //已添加,游戏名称
input2: "", //未添加,游戏名称
options: [],
columnId: this.$route.query.id, //路由接收栏目id
gameIds: [],
gameIds2: [],
videoListarr: [],
col: [
{
label: "游戏ID",
prop: "gameId",
},
{
label: "游戏名称",
prop: "gameName",
},
{
label: "游戏类别",
prop: "gameType",
},
{
label: "操作",
prop: "isClick",
},
],
};
},
created() {
this.gamegetClassList();
this.getInfoList();
this.getaddedGameList();
this.getGameListorde();
},
computed: {},
methods: {
// 栏目游戏类型
gamegetClassList() {
let parmas = {
token: this.token,
channelId: this.channelId,
};
gamegetClassList(parmas).then((res) => {
if (res.data.code == 0) {
this.options = Object.values(res.data.data);
}
});
},
// 渠道-栏目信息列表
getInfoList() {
let parmas = {
token: this.token,
channelId: this.channelId,
columnId: this.columnId, //栏目id
};
getInfo(parmas).then((res) => {
if (res.data.code == 0) {
this.tableData.push(res.data.data);
}
});
},
// 栏目已添加游戏列表
getaddedGameList() {
console.log("value", this.value);
let parmas = {
token: this.token,
channelId: this.channelId,
columnId: this.columnId, //栏目id
gameName: this.input,
type: this.value,
};
addedGameList(parmas).then((res) => {
if ((res.data.code == 0) & (res.data.data.length > 0)) {
this.tableData2 = res.data.data;
this.IndexT();
} else {
this.tableData2 = [];
}
});
},
// 栏目待添加游戏列表
getGameListorde() {
let parmas = {
token: this.token,
channelId: this.channelId,
gameName: this.input2,
type: this.value2,
};
getGameList(parmas).then((res) => {
if (res.data.code == 0) {
if (Object.keys(res.data.data).length > 0) {
this.tableData3 = res.data.data;
} else {
this.tableData3 = [];
}
}
});
},
// 编辑选中
gameAdd(val) {
console.log("编辑添加", val);
let index = this.gameIds.indexOf(`${val.gameId}`); //判断这个 字段,是否已经被数组存有
if (index == -1) {
//没存,那么存入它
this.gameIds.unshift(`${val.gameId}`);
}
if (this.tableData2.length > 0) {
try {
//由于forEach不存在跳出循环,所以只能通过抛出异常来实现
this.tableData2.forEach((item, index) => {
let index2 = item.gameId == val.gameId ? "0" : "-1";
if (index2 === "0") {
throw Error();
} else if (index == this.tableData2.length - 1) {
if (index2 === "-1") {
this.tableData2.unshift(val);
}
}
});
} catch (e) {}
} else {
this.tableData2.unshift(val);
}
},
// 编辑删除
gameDelete(val) {
console.log("点击了游戏删除", val);
let index = this.gameIds.indexOf(`${val.gameId}`);
if (index > -1) {
this.gameIds.splice(index, 1);
}
try {
this.tableData2.forEach((item, index) => {
let index2 = item.gameId == val.gameId ? "0" : "-1";
if (index2 === "0") {
this.tableData2.splice(index, 1);
}
});
} catch (e) {}
},
// 生成index和新排序数组
IndexT() {
this.tableData2.forEach((item, index) => {
item.index = this.tableData2.length - 1 - index;
this.gameIds.push(`${item.gameId}`);
});
console.log("就想看下原始权重", this.gameIds);
},
// 查询游戏
editing_search(val) {
console.log("查询游戏");
if (val == "1") {
//已添加
this.getaddedGameList();
} else {
//待添加
this.getGameListorde();
}
},
// 编辑保存
editing_keep() {
console.log("看下保存时", this.gameIds);
let parmas = {
token: this.token,
channelId: this.channelId,
columnId: this.columnId, //栏目ID
title: this.tableData[0].title, //游戏栏目
gameIds: this.gameIds, //游戏id数组集合
isHide: this.radioel == "" ? this.tableData[0].isHide : this.radioel, //栏目可见性 1可见 2 隐藏
};
// return
console.log("看下列表编辑前长啥", this.tableData2);
console.log(parmas, "编辑保存的数据");
update(parmas).then((res) => {
if (res.data.code == 0) {
this.tableData = [];
this.gameIds = [];
this.gamegetClassList();
this.getInfoList();
this.getaddedGameList();
this.getGameListorde();
}
});
},
rowDrop() {
let el = document.querySelectorAll(
".el-table__body-wrapper > table > tbody"
)[0];
const sortable = Sortable.create(el, {
onEnd: (evt) => {
// 监听拖动结束事件
console.log("evt", evt);
let x = evt.item.__vue__._props.row;
console.log("当前这行数据的游戏Id", x);
console.log("这条数据的新下标", evt.newIndex);
this.paixu(x, evt);
},
});
// Sortable.create(tbody);
},
// 排序
paixu(x, evt) {
// 新思路
// 由于获取的新权重位置,改写原始数组时会触动虚拟dom
// 所以,我不再对原始数据做操作
// 而是直接操作事先存储的 权重数组
// 在进行 排序时,拖拽将获取到该行新数据的所有
// 这里存在着坑
// 第一个,当我获取到新数据的gameId和新下标,该怎么排给权重数组
// 最初我 是对原始数据做冒泡,但会触动dom pass
// 现在,我打算换一种形式。不再使用冒泡来实现
// 权重数组由来,通过 原始数据生成的。即,后端返回的真实数据
// 真实数据里,存入了我创建的权重字段 index,而index则是由(数据下标<=0) 高到 (数据下标>0)低形式
// 以此,来展示,其实并没有触动原始数据
// 而遍历时,将gameId+index存入数组gameIds是没有问题的
// 0: "3" //右侧的值是gameId
// 1: "2" //左侧的值是下标(也作权重使用)
// 2: "1"
// 真实拖拽时,获取下标的同时,我将获取到gameId
// 这时只需要对比 右侧的值即可 得到这条数据的最新位置
// 新位置有了,那么插入势必会影响旧的位置
// 故:拖拽后,若gameId的index没有变化,则不做删除操作
// 否则:删除指定位置的gameId 在新的下标位置插入gameId
// 至此,权重数组数据正常
// 隐患:删除某条数据时,是否要原始数组做操作??
// 解决:最初,我的做法是对原始数据做操作,但存在隐患 触动虚拟dom
// 考虑:如何不触动dom的前提下删除??
// (好吧,由于插件的虚拟dom是根据实体数据来渲染的,如果不删除原始数据的该条数据,实际上是不能实现同步的)
// 至少我还做不到...
let newDeta = this.gameIds;
this.gameIds.forEach((item, index, array) => {
if (this.gameIds[index] == x.gameId && index != evt.newIndex) {
let ccc = this.gameIds[evt.newIndex];
// 存在排序往上与往下两种
if (evt.newIndex < index) {
this.gameIds.splice(evt.newIndex, 1, item); //删除旧值
this.gameIds.splice(evt.newIndex + 1, 1, ccc); //改写被替换的那行
for (let i = 0; i < newDeta.length; i++) {
console.log("i", i);
if (index > 0 && i > index + 1) {
this.gameIds[index] = newDeta[i];
}
// if (this.gameIds.length == i + 1) {
// console.log("排序便利上增结束1", this.gameIds);
// }
}
} else {
this.gameIds.splice(evt.newIndex, 1, item); //删除旧值
this.gameIds.splice(evt.newIndex - 1, 1, ccc); //改写被替换的那行
for (let i = 0; i < newDeta.length; i++) {
if (index > 0 && i > index + 1) {
this.gameIds[index] = newDeta[i + 1];
}
// if (this.gameIds.length == i + 1) {
// console.log("排序便利下降结束1", this.gameIds);
// }
}
}
if (this.gameIds.length == index + 1) {
console.log("排序便利结束2", this.gameIds);
}
}
});
},
},
mounted() {
this.rowDrop();
},
watch: {},
};
</script>
<style lang="less" scoped>
.home {
width: 1200px;
margin: 0 auto;
}
.bg_color {
height: 100%;
border-radius: 16px;
box-shadow:none;
background: #fff;
display: flex;
flex-direction: column-reverse; //颠倒排列 将盒子以下上形式排布分列
align-content: end;
justify-content: flex-end;
}
.cententReport {
padding: 30px 24px 40px 24px;
font-size: 20px;
font-weight: 400;
color: #333333;
}
.details_list {
padding: 0px 30px 20px 30px;
}
.paixu {
padding: 0px 30px 20px 30px;
display: flex;
flex-direction: row;
justify-content: space-around;
align-content: center;
.paixu_left {
width: 40%;
text-align: center;
.paixu_head {
background: #f6f8fb;
padding: 10px;
font-size: 16px;
}
.paixu_center {
margin: 10px 0;
display: flex;
flex-direction: row;
}
}
.jiantou {
display: flex;
align-items: center;
i {
font-size: 150px;
align-items: center;
}
}
}
.footer2 {
padding: 20px 0px 30px 20px;
display: flex;
flex-direction: row;
justify-content: center;
}
</style>
代码量还是蛮多的,抽空简化一下,由于是初次使用Sortable,相当生熟。
但不管怎么说,也算取到最新的权重了。在这里,之所以颠倒了某个盒子的排放,是由于该插件只对第一个element 的表格组件生效,存在缺陷。