一、使用方式
<select ref="select" :limit="3" @change="change"></select>
function (){
this.$refs.select.open(selectedList, disabledList);
}
二、弹窗实现
<template>
<Modal v-model="showModal" class="select-modal" title="选择" @on-visible-change="changeVisible" width="700"
:mask-closable="false">
<div class="table-box">
<Table ref="table" border :columns="tableColumns" :loading="loading" :data="tableData" no-data-text="暂无数据"
size="small" :height="tableHeight" disabled-hover highlight-row @on-select-all="selectDataAll"
@on-select-all-cancel="selectDataAllCancel" @on-select="selectData" @on-select-cancel="selectCancel">
</Table>
<Page ref="page" class="ivu-page" :total="total" size="small" show-total :current="pageNum"
:page-size-opts="[10, 20, 50, 100]" :page-size="pageSize" @on-change="pageChange"
@on-page-size-change="pageSizeChange" show-elevator show-sizer />
</div>
<Form :model="{}" :rules="{}" label-position="right">
<FormItem label="已选项:">
<span class="select-item" v-for="(item, index) in tableSelectList" :key="index">
<Icon class="select-item-icon" type="ios-close-circle-outline" @click="handleDelete(index)" />
<span class="select-item-val">
<span v-if="cacheObj[item] && cacheObj[item].account">{{ cacheObj[item].account }}</span>
<span v-if="cacheObj[item] && cacheObj[item].userName">{{ `[${cacheObj[item].userName}]`
}}</span>
</span>
</span>
</FormItem>
</Form>
<div slot="footer" class="modal-footer">
<Button size="small" @click="submit">确认</Button>
<Button size="small" @click="close">关闭</Button>
</div>
</Modal>
</template>
<script>
import { accountList } from '@/api/api_select.js';
const cacheObj = {};
export default {
props: {
limit: {
type: Number,
default: () => 9999
}
},
data() {
return {
cacheObj,
showModal: false,
tableColumns: [
{
type: 'selection',
width: 30,
align: 'center',
key: "account",
},
{
title: '序号',
type: 'index',
align: 'center',
width: 35
},
{
title: '账号',
key: 'account',
ellipsis: true,
tooltip: true,
align: 'center',
minWidth: 60
},
{
title: '用户名',
key: 'userName',
align: 'center',
ellipsis: true,
tooltip: true,
minWidth: 60
}
],
tableHeight: 300,
tableData: [],
tableSelectList: [],
tableDisableList: [],
total: 0,
pageNum: 1,
pageSize: 10,
loading: false,
};
},
computed: {
// 剩余的可选数量
leftCount() {
return this.limit - this.tableSelectList.length;
}
},
watch: {
leftCount(val) {
this.filterTableData(val);
}
},
methods: {
open(selected = [], disabled = []) { // 选中项、禁选项
if (selected && selected.length) {
let arr = [];
selected.forEach(it => {
arr.push(it.account);
cacheObj[it.account] = { ...it };
});
this.tableSelectList = arr;
} else {
this.tableSelectList = [];
}
if (disabled && disabled.length) {
let arr = [];
disabled.forEach(it => {
arr.push(it.account);
});
this.tableDisableList = arr;
} else {
this.tableDisableList = [];
}
this.search();
this.showModal = true;
},
changeVisible(val) {
if (!val) {
this.close();
}
},
close() {
this.showModal = false;
},
submit() {
let list = [];
this.tableSelectList.forEach(it => {
let tmp = cacheObj[it];
if (tmp) {
list.push({
...tmp
});
}
});
this.$emit('change', list);
this.changeVisible();
},
selectDataAll() {
this.tableData.forEach(row => {
if (!this.tableSelectList.includes(row.account) && this.leftCount > 0) {
this.tableSelectList.push(row.account);
cacheObj[row.account] = { ...row };
}
});
},
selectDataAllCancel() {
this.tableData.forEach(row => {
var _index = this.tableSelectList.indexOf(row.account);
if (_index != -1) {
this.tableSelectList.splice(_index, 1);
}
});
},
selectData(selection, row) {
if (!this.tableSelectList.includes(row.account) && this.leftCount > 0) {
this.tableSelectList.push(row.account);
cacheObj[row.account] = { ...row };
}
},
selectCancel(selection, row) {
var _index = this.tableSelectList.indexOf(row.account);
if (_index != -1) {
this.tableSelectList.splice(_index, 1);
}
},
handleDelete(index) {
this.tableSelectList.splice(index, 1);
this.tableData.forEach((ele) => {
if (!this.tableSelectList.includes(ele.account) && ele._checked) {
this.$set(ele, '_checked', false);
}
if (this.tableSelectList.includes(ele.account)) {
this.$set(ele, '_checked', true);
}
});
},
pageChange(val) {
this.pageNum = val;
this.getTableData();
},
pageSizeChange(val) {
this.pageNum = 1;
this.pageSize = val;
this.getTableData();
},
search() {
this.pageNum = 1;
this.getTableData();
},
async getTableData() {
this.loading = true;
accountList({})
.then((data) => {
this.loading = false;
this.total = data.total || 0;
let tableData = data.rows || [];
if (this.tableSelectList.length || this.tableDisableList.length || this.leftCount <= 0) {
tableData.forEach((ele) => {
// 选中
if (this.tableSelectList.includes(ele.account)) {
ele._checked = true;
}
// 禁用
if (this.tableDisableList.includes(ele.account)) {
ele._disabled = true;
}
// 可选择数量不足的时候禁用其余项
if (!this.tableSelectList.includes(ele.account) && this.leftCount <= 0) {
ele._disabled = true;
}
});
}
this.tableData = tableData;
})
.catch((Err) => {
this.loading = false;
this.total = 0;
this.tableData = [];
});
},
filterTableData(val) {
this.tableData.forEach((ele) => {
if (this.tableSelectList.includes(ele.account)) {
// 选中
this.$set(ele, '_checked', true);
} else {
// 取消选中
this.$set(ele, '_checked', false);
}
if (val > 0) {
// 可选择数量剩余取消禁用
if (!this.tableDisableList.includes(ele.account)) {
this.$set(ele, '_disabled', false);
}
} else {
// 可选择数量不足的时候禁用其余项
if (!this.tableSelectList.includes(ele.account)) {
this.$set(ele, '_disabled', true);
}
}
});
}
}
};
</script>
<style lang="less" scoped>
.select-modal {
.select-item {
display: inline-block;
position: relative;
padding: 0 5px;
box-sizing: border-box;
background-color: #eee;
margin-right: 20px;
color: #333;
margin-top: 4px;
margin-bottom: 4px;
.select-item-icon {
cursor: pointer;
position: absolute;
right: -12px;
top: -12px;
font-size: 18px;
z-index: 1;
}
}
}
</style>