vue3+elementplus选择弹出表格框demo
vue
<template>
<el-main>
<el-alert
title="表格选择器演示 —— 数据写死,无请求"
type="success"
style="margin-bottom: 20px"
/>
<!-- ====== 单选 ====== -->
<el-card shadow="never" header="单选">
<el-select
ref="singleSelect"
v-model="singleKey"
placeholder="请选择(单选)"
clearable
:filter-method="filterMethod"
style="width: 260px"
@visible-change="visibleChange"
>
<template #empty>
<div class="table-box">
<el-table
ref="singleTable"
:data="tableData"
height="245"
highlight-current-row
@row-click="rowClick"
>
<el-table-column type="index" width="45" />
<el-table-column prop="id" label="ID" width="180" />
<el-table-column prop="user" label="姓名" />
</el-table>
<div class="pagination-box">
<el-pagination
small
background
layout="prev, pager, next"
:total="rawData.length"
:page-size="pageSize"
v-model:current-page="currentPage"
@current-change="reload"
/>
</div>
</div>
</template>
</el-select>
</el-card>
<div style="height: 15px" />
<!-- ====== 多选 ====== -->
<el-card shadow="never" header="多选">
<el-select
ref="multiSelect"
v-model="multiKeys"
placeholder="请选择(多选)"
multiple
clearable
collapse-tags
collapse-tags-tooltip
filterable
:filter-method="filterMethod"
style="width: 400px"
@visible-change="visibleChange"
@remove-tag="removeTag"
@clear="clearMulti"
>
<template #empty>
<div class="table-box">
<el-form :inline="true" :model="formData">
<el-form-item>
<el-select v-model="formData.sex" placeholder="性别" clearable>
<el-option label="男" value="1" />
<el-option label="女" value="2" />
</el-select>
</el-form-item>
<el-form-item>
<el-date-picker
v-model="formData.date"
value-format="YYYY-MM-DD"
type="date"
placeholder="注册时间"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="formSubmit">查询</el-button>
</el-form-item>
</el-form>
<el-alert
title="自定义 FORM 插槽:支持性别 / 注册时间筛选"
type="info"
style="margin-bottom: 8px"
/>
<el-table
ref="multiTable"
:data="tableData"
height="245"
@select="select"
@select-all="selectAll"
>
<el-table-column type="selection" width="45" />
<el-table-column prop="id" label="ID" width="180" />
<el-table-column prop="user" label="姓名" width="100" />
<el-table-column prop="cip" label="最后请求IP" width="150" />
<el-table-column prop="time" label="注册时间" />
</el-table>
<div class="pagination-box">
<el-pagination
small
background
layout="prev, pager, next"
:total="rawData.length"
:page-size="pageSize"
v-model:current-page="currentPage"
@current-change="reload"
/>
</div>
</div>
</template>
</el-select>
</el-card>
</el-main>
</template>
<script setup>
import { nextTick, ref, watch } from 'vue'
/* ------------------ 写死数据 ------------------ */
const rawData = ref([
{ id: '410000199512025445', user: '魏磊', sex: '1', time: '2023-01-15', cip: '192.168.1.101' },
{ id: '520000198407304275', user: '史平', sex: '1', time: '2023-02-20', cip: '192.168.1.102' },
{ id: '330000199003034567', user: '王丽', sex: '2', time: '2023-03-10', cip: '192.168.1.103' },
{ id: '110000198801012233', user: '李强', sex: '1', time: '2023-04-05', cip: '192.168.1.104' },
{ id: '440000199212126666', user: '赵敏', sex: '2', time: '2023-05-18', cip: '192.168.1.105' },
{ id: '310000198505059999', user: '张三', sex: '1', time: '2023-06-22', cip: '192.168.1.106' },
{ id: '220000199111114444', user: '李四', sex: '1', time: '2023-07-30', cip: '192.168.1.107' },
{ id: '150000198707077777', user: '周五', sex: '2', time: '2023-08-11', cip: '192.168.1.108' },
{ id: '640000199404048888', user: '吴六', sex: '1', time: '2023-09-03', cip: '192.168.1.109' },
{ id: '510000198909093333', user: '郑七', sex: '2', time: '2023-10-14', cip: '192.168.1.110' }
])
/* ------------------ 分页 / 搜索 ------------------ */
const pageSize = 5
const currentPage = ref(1)
const keyword = ref('')
const formData = ref({ sex: '', date: '' })
const tableData = ref([])
const reload = () => {
let list = rawData.value.filter(item => {
const kw = keyword.value
if (kw && !item.user.includes(kw) && !item.id.includes(kw)) return false
if (formData.value.sex && item.sex !== formData.value.sex) return false
if (formData.value.date && item.time !== formData.value.date) return false
return true
})
const start = (currentPage.value - 1) * pageSize
const end = start + pageSize
tableData.value = list.slice(start, end)
nextTick(() => syncChecked())
}
const filterMethod = val => {
keyword.value = val || ''
currentPage.value = 1
reload()
}
const formSubmit = () => {
currentPage.value = 1
reload()
}
/* ------------------ 单选 ------------------ */
const singleKey = ref('')
const singleSel = ref({})
const singleSelect = ref(null)
const rowClick = row => {
singleKey.value = row.id
singleSel.value = row
nextTick(() => {
singleSelect.value.selectedLabel = row.user
console.log(singleSelect.value,'singleSelect.value')
singleSelect.value.blur()
})
}
/* ------------------ 多选 ------------------ */
const multiKeys = ref([])
const multiSel = ref([])
const multiTable = ref(null)
const select = (rows, row) => {
const checked = rows.includes(row)
if (checked) {
if (!multiKeys.value.includes(row.id)) {
multiKeys.value.push(row.id)
multiSel.value.push(row)
}
} else {
multiKeys.value = multiKeys.value.filter(k => k !== row.id)
multiSel.value = multiSel.value.filter(r => r.id !== row.id)
}
}
const selectAll = rows => {
const checked = rows.length > 0
if (checked) {
rows.forEach(r => {
if (!multiKeys.value.includes(r.id)) {
multiKeys.value.push(r.id)
multiSel.value.push(r)
}
})
} else {
const curPageIds = tableData.value.map(i => i.id)
multiKeys.value = multiKeys.value.filter(k => !curPageIds.includes(k))
multiSel.value = multiSel.value.filter(r => !curPageIds.includes(r.id))
}
}
const removeTag = tag => {
multiKeys.value = multiKeys.value.filter(k => k !== tag.id)
multiSel.value = multiSel.value.filter(r => r.id !== tag.id)
const row = tableData.value.find(r => r.id === tag.id)
if (row) multiTable.value.toggleRowSelection(row, false)
}
const clearMulti = () => {
multiKeys.value = []
multiSel.value = []
}
const syncChecked = () => {
if (!multiTable.value) return
multiTable.value.clearSelection()
multiSel.value.forEach(r => {
const r2 = tableData.value.find(i => i.id === r.id)
if (r2) multiTable.value.toggleRowSelection(r2, true)
})
}
/* 统一 visibleChange */
const visibleChange = val => {
if (val) reload()
else {
nextTick(() => {
if (singleSel.value.user) singleSelect.value.selectedLabel = singleSel.value.user
})
}
}
/* 初始值 */
multiKeys.value = ['410000199512025445', '520000198407304275']
multiSel.value = [
{ id: '410000199512025445', user: '魏磊' },
{ id: '520000198407304275', user: '史平' }
]
singleKey.value = '520000198407304275'
singleSel.value = { id: '520000198407304275', user: '史平' }
watch(currentPage, reload)
</script>
<style scoped>
.table-box {
padding: 12px;
width: 700px;
}
.pagination-box {
padding-top: 12px;
text-align: right;
}
</style>