效果
image.png
代码
<template>
<div class="lesson-main">
<section class="lesson-body">
<section class="lesson-body-left">
<div class="filter-box">
<span class="search-input-box">
<el-input
v-model="keyword"
placeholder="请输入关键词搜索"
prefix-icon="el-icon-search">
</el-input>
</span>
</div>
<div class="table-wrapper">
<el-table class="table-border"
ref="lessonTableRef"
:data="lessonList"
:row-key="(row)=>{ return row.classId}"
@select="handleSelectionChange"
@select-all="handleAllChange">
<el-table-column
width="80"
type="selection"
:reserve-selection="true">
</el-table-column>
<el-table-column prop="lessonTitle" label="名称" min-width="200">
<template slot-scope="scope">
<div class="lesson-info">
<p class="icon_course"></p>
<p class="title">{{ scope.row.classTitle }}</p>
</div>
</template>
</el-table-column>
<el-table-column prop="duration" label="时长" min-width="120">
<template slot-scope="scope">{{ scope.row.duration | handleDuration }}</template>
</el-table-column>
<el-table-column prop="" label="过期时间" min-width="120">
<template slot-scope="scope">{{scope.row.expireTime ? scope.row.expireTime.slice(0, 10) : '-'}}</template>
</el-table-column>
</el-table>
<div class="table-page">
<p class="all-btn"
:class="{
disabled: !this.count
}"
@click="handleSelectAll()">全部筛选结果</p>
<el-pagination
style="text-align: right"
background
:total="count"
:current-page="page"
:page-size="pageSize"
:page-sizes="pageSizesG"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
layout="sizes, prev, pager, next">
</el-pagination>
</div>
</div>
</section>
<section class="lesson-body-right">
<div class="choose-header">
<p class="text">已选择:{{chooseLessonList.length}}/{{count}}</p>
<p class="close-btn"
@click="handleClearAll()">清除所有</p>
</div>
<div class="choose-wrapper">
<ul class="lesson-list draggable-list">
<li class="lesson-item lesson-drag-btn"
v-for="(info, i) in chooseLessonList"
:key="`lesson${info.classId}`">
<p class="icon_course"></p>
<p class="title">{{info.classTitle}}</p>
<p class="icon_close"
@click.stop="handleClear(i)"></p>
</li>
</ul>
</div>
</section>
</section>
<section class="lesson-footer">
<newElButton
width='80px'
btnType='cancel'
@handleClick='handleLessonCancel()'
>取消</newElButton>
<newElButton
class='ml20'
width='80px'
@handleClick='handleLessonSave()'
>确定</newElButton>
</section>
</div>
</template>
<script>
import { getLessonList } from '@/api'
import Sortable from "sortablejs";
import newElButton from '@/components/elUI/newElButton'
export default {
components: {
newElButton
},
props: {
selectList: {
type: Array
}
},
data () {
return {
keyword: '',
count: 0,
page: 1,
pageSize: 10,
lessonList: [], //
echoList: [], // 收集回显用的数据
chooseLessonList: [], // 实际保存的数据
}
},
methods: {
// 单项选择:打勾或取消
handleSelectionChange (selected, row) {
if (!this.echoList.find(info => info.classId === row.classId)) {
// 回显数据里没有本条,把这条加进来(选中)
this.echoList.push(row)
} else {
// 回显数据里有本条,把这条删除(取消选中)
this.echoList.forEach((info, index) => {
if (info.classId === row.classId) {
this.echoList.splice(index, 1)
}
})
}
// 这里用于收集实际需要的数据数组
this.chooseLessonList = this.echoList;
},
// 全选、取消全选(原理同上面的单选)
handleAllChange (selected) {
if (selected.length > 0) {
// 多页同时选中时,先清除当前页数据
this.lessonList.forEach((item) => {
this.echoList.forEach((info, index) => {
if (info.classId == item.classId) {
this.echoList.splice(index, 1);
}
});
});
// 再记录选中的数据
selected.forEach((item) => {
if (!this.echoList.find(info => info.classId == item.classId)) {
this.echoList.push(item);
}
});
} else {
// 数据为空代表取消全选,清除当前页所有数据
this.lessonList.forEach((item) => {
this.echoList.forEach((info, index) => {
if (info.classId == item.classId) {
this.echoList.splice(index, 1);
}
});
});
}
// 这里用于收集实际需要的数据数组
this.chooseLessonList = this.echoList;
},
// 全选、取消全选
handleSelectAll () {
if (!this.count) {
return
}
this.$refs.lessonTableRef.toggleAllSelection()
},
// 清除所有
handleClearAll () {
this.echoList = []
// 这里用于收集实际需要的数据数组
this.chooseLessonList = this.echoList
this.$refs.lessonTableRef.clearSelection();
},
// 清除单个
handleClear (i) {
let delRow = this.chooseLessonList.splice(i, 1)
// 回显数据也要移除被删数据
this.echoList.forEach((info, index) => {
if (info.classId == delRow[0]?.classId) {
this.echoList.splice(index, 1)
}
})
this.handleSelectTable()
},
handleLessonSave () {
this.$emit('save', this.chooseLessonList)
},
handleLessonCancel () {
this.$emit('cancel')
},
handleSizeChange(val) {
this.page = 1
this.pageSize = val
this.fetchLessonList()
},
handleCurrentChange (val) {
this.page = val
this.fetchLessonList()
},
fetchLessonList() {
let params = {
keyword: this.keyword,
currentPage: this.page,
pageSize: this.pageSize
}
params = this.filterSearchInfo(params)
getLessonList(params).then(res => {
if (res.data.code === 200) {
let data = res.data.data
if (data) {
this.count = +data.total
if (data.list && data.list.length) {
this.lessonList = data.list
} else {
this.lessonList = []
}
this.$nextTick(() => {
this.handleSelectTable()
})
}
}
}).catch(err => {
this.handleError(err)
})
},
handleSelectTable () {
// 所有取消选中
this.$refs.lessonTableRef.clearSelection()
// 表格回显选中
if (this.echoList && this.echoList.length) {
this.echoList.forEach(info => {
this.lessonList.forEach(row => {
if (row.classId == info.classId) {
this.$refs.lessonTableRef.toggleRowSelection(row, true)
}
})
})
}
},
// 开启拖拽(未生效需要找原因)
initRowDrop () {
const tbody = document.querySelector(".draggable-list");
const _this = this;
Sortable.create(tbody, {
handle: ".lesson-drag-btn",
onEnd({ newIndex, oldIndex }) {
if (newIndex === oldIndex) return false;
const currRow = _this.chooseLessonList.splice(oldIndex, 1)[0];
_this.chooseLessonList.splice(newIndex, 0, currRow);
},
});
}
},
filters: {
handleDuration (val) {
if (!val) {
return '--'
}
val = Number(val)
var hour = Math.floor(val / 3600)
var min = Math.ceil((val % 3600) / 60)
if (hour > 0 && min > 0) {
return `${hour}小时${min}分`
} else if (hour > 0 && min === 0) {
return `${hour}小时`
} else {
return `${min}分`
}
}
},
watch: {
chooseLessonList () {
this.$nextTick(() => {
this.initRowDrop()
})
}
},
created () {
this.echoList = JSON.parse(JSON.stringify(this.selectList))
this.chooseLessonList = JSON.parse(JSON.stringify(this.selectList))
this.fetchLessonList()
},
}
</script>
<style lang="stylus" scoped>
.lesson-main
width 100%
height calc(100vh - 55px)
display flex
flex-direction column
position relative
.lesson-body
height calc(100% - 57px)
display: flex
.lesson-body-left
width calc(100% - 258px)
height 100%
border-right 1px solid #E9EAED
padded_box(border-box, 16px 20px)
.filter-box
width 100%
display: flex
align-items: center
.table-wrapper
width 100%
height calc(100% - 48px)
// display flex
// flex-direction: column
// justify-content: space-between
margin-top 16px
// .table-border.el-table
// flex none
.lesson-info
width 100%
display: flex
align-items: center
.icon_course
width 20px
height 20px
background: url('~assets/img/knowledge/icon_course@2x.png') no-repeat center/100%
.title
max-width calc(100% - 48px)
height: 20px;
line-height: 20px
font-family:'PingFangSC-Regular';
font-size: 14px;
color: #5E5F66;
margin:0 8px 0 4px
.table-page
display: flex
justify-content: space-between
align-items center
.all-btn
line-height 20px
font-family: 'PingFangSC-Regular';
font-size: 14px;
color: #3377FE;
padded_box(border-box, 4px 12px)
cursor pointer
margin-top 18px
&.disabled
cursor: not-allowed
.lesson-body-right
width 258px
height 100%
padded_box(border-box, 16px 20px)
.choose-header
width 100%
display: flex
justify-content: space-between
align-items: center
.text
height: 20px;
line-height 20px
font-family: PingFangSC-Regular;
font-size: 12px;
color: #5E5F66;
.close-btn
height: 20px;
line-height 20px
font-family: PingFangSC-Regular;
font-size: 12px;
color: #9B9EA8;
cursor pointer
.choose-wrapper
width 100%
scroll()
scroll-bar()
height calc(100% - 36px)
margin-top 16px
.lesson-list
display: flex
flex-wrap: wrap
.lesson-item
display: flex
align-items center
height 32px
line-height: 20px
background: #F1F6FE
padded_box(border-box, 6px 12px)
border-radius: 4px
margin 0 10px 10px 0
cursor pointer
.icon_course
width 20px
height 20px
background: url('~assets/img/knowledge/icon_course@2x.png') no-repeat center/100%
.title
height: 20px;
line-height: 20px
font-family: 'PingFangSC-Regular';
font-size: 12px;
color: #303544;
margin 0 12px 0 4px
.icon_close
width 16px
height 16px
background: url('~assets/img/icon_close@2x.png') no-repeat center/12px
cursor: pointer
.lesson-footer
flex none
text-align right
padded_box(border-box, 12px 20px)
border-top 1px solid #E9EAED
</style>
参考
原文地址:https://blog.csdn.net/Skty_ywh/article/details/126000082








网友评论