vue 弹窗翻页多选
程序员文章站
2024-02-18 23:57:58
...
最终效果
点选择按钮后,弹出选择用户弹窗,可翻页勾多个用户
完整代码
<template>
<div>
<el-button size="small" type="primary" @click="choose">选择</el-button>
<p>
<el-tag v-for="(item,index) in allSelectedUserList" :key="index"
@close="removeUser(index)"
style="margin-right: 10px"
closable>
{{item.name}}
</el-tag>
</p>
<el-dialog :visible.sync="dialogVisible" title="选择用户" v-if="dialogVisible" width="40%" append-to-body>
<s-table ref="table" @selectionChange="selectionChange" @loadData="loadData" :data="tableData"
:config="tableConfig"></s-table>
<span slot="footer">
<el-button @click="dialogVisible = false" size="mini">取 消</el-button>
<el-button @click="chooseConfirm" size="mini" type="primary">确 定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
export default {
data() {
return {
dialogVisible: false,
// 最终选中的所有数据
allSelectedUserList: [],
// 最终选中的全部唯一字段列表
allUniquePropList: [],
// 唯一字段
uniqueProp: 'id',
// 每次弹窗中选中的所有数据
allSelectedList: [],
tableData: [],
tableConfig: {
showSelect: true,
selectable: (row, rowIndex) => {
if (this.allUniquePropList.indexOf(row[this.uniqueProp]) === -1) {
if (rowIndex === row.index) {
return false
} else {
return true
}
}
},
pageConfig: {
pageSizeList: [3, 5, 10],
pageSize: 3,
currentPage: 1,
total: 0
},
itemList: [
{
label: 'id',
prop: 'id'
},
{
label: '姓名',
prop: 'name'
},
{
label: '年龄',
prop: 'age'
},
],
}
}
},
mounted() {
this.loadData()
},
methods: {
// 点击选择按钮
choose() {
this.allUniquePropList = []
this.allSelectedUserList.forEach(
item => {
this.allUniquePropList.push(item[this.uniqueProp])
}
)
this.allSelectedList = []
this.dialogVisible = true
},
// 点击选择弹窗的确定按钮
chooseConfirm() {
this.allSelectedUserList = this.allSelectedUserList.concat(this.allSelectedList)
this.dialogVisible = false
},
// 加载数据
loadData(newPageConfig) {
if (newPageConfig && newPageConfig.currentPage) {
this.tableConfig.pageConfig.currentPage = newPageConfig.currentPage
}
if (newPageConfig && newPageConfig.pageSize) {
this.tableConfig.pageConfig.pageSize = newPageConfig.pageSize
}
this.$http.get("/user/pages", {
params: {
currentPage: this.tableConfig.pageConfig.currentPage,
pageSize: this.tableConfig.pageConfig.pageSize
}
})
.then(res => {
let data = res.data
this.tableData = data.records;
this.tableConfig.pageConfig.total = data.total
this.updateSelectedMark()
})
},
// 改变多选列的选中状态时,更新选中列表
selectionChange(pageSelectedList) {
// 当页唯一字段组成的列表
let uniquePropList = []
this.tableData.forEach(row => {
uniquePropList.push(row[this.uniqueProp])
})
// 从全部选中的数据中,过滤掉当前页的数据,再添加当前页选中的数据
this.allSelectedList = this.allSelectedList.filter(row =>
!uniquePropList.includes(row[this.uniqueProp])
).concat(pageSelectedList)
},
// 更新选中标记--选中数据与当页数据的交集,标记为选中状态
updateSelectedMark() {
this.$nextTick(
() => {
let pageSelectedList = []
this.allSelectedList.forEach(row1 => {
this.tableData.forEach(row2 => {
if (row1[this.uniqueProp] === row2[this.uniqueProp]) {
pageSelectedList.push(row2)
}
})
})
pageSelectedList.forEach(row => {
this.$refs.table.toggleRowSelection(row);
})
}
)
},
// 移除选择的用户
removeUser(index) {
this.allSelectedUserList.splice(index, 1);
},
}
}
</script>
<style scoped>
</style>
s-table全局表格组件
<template>
<div>
<el-table
ref="table"
@select="rowSelectChange"
@select-all="pageSelectChange"
@row-click="getCurrentRow"
:data="data"
border
:highlight-current-row="!config.closeHighlightRow"
empty-text="暂无数据">
<el-table-column
:selectable="config.selectable"
v-if="config.showSelect"
type="selection"
width="55">
</el-table-column>
<el-table-column
:align="item.align?item.align:'center'"
:label=item.label
:prop=item.prop
:min-width="item.minWidth?item.minWidth:'120'"
:formatter="item.formatter"
v-for="(item,index) in config.itemList"
:key="index"
>
</el-table-column>
<slot name="操作">
</slot>
</el-table>
<!-- 分页 -->
<div style="text-align: right">
<el-pagination
:current-page="config.pageConfig.currentPage"
:page-size="config.pageConfig.pageSize"
:page-sizes="config.pageConfig.pageSizeList"
:total="config.pageConfig.total"
@current-change="currentPageChange"
@size-change="pageSizeChange"
layout="total, sizes, prev, pager, next, jumper"
style="margin: 20px 0px"
></el-pagination>
</div>
</div>
</template>
<script>
export default {
props: {
data: Array,
config: Object,
selectable: Function
},
data() {
return {}
},
methods: {
rowSelectChange(pageSelected, row) {
this.$emit('selectionChange',
pageSelected,
)
},
pageSelectChange(pageSelected) {
this.$emit('selectionChange', pageSelected)
},
toggleRowSelection(row) {
this.$refs.table.toggleRowSelection(row);
},
selectionChange(pageSelected) {
this.$emit('selectionChange', pageSelected)
},
currentPageChange(newPage) {
this.$emit('loadData',
{
currentPage: newPage
}
)
},
pageSizeChange(newPageSize) {
this.$emit('loadData',
{
pageSize: newPageSize
}
)
},
getCurrentRow(row) {
this.$emit('getCurrentRow', row)
}
}
}
</script>
<style scoped>
</style>