一、界面展示
二、功能描述
- 添加:实现在表格头部添加一行记录,工号会自动生成,其他数据为空。
- 修改:点击表格单元格,可以实现修改指定字段内容,失焦自动保存修改后的数据。
- 删除:弹出确认对话框,点击 yes 后,删除当前行。
- 排序:年龄
- 筛选:性别、年龄、省份 >> 实现都不一样
- 操作列右固定:由于表格宽度是指定的,所以表格列信息显示不全。这里采用了操作列右固定的形式,左右拖拽滚动条即可显示隐藏列数据。
- 省份对话框:点击省份单元格,会弹出对话框,在对话框内显示省份树信息,选择某个节点,点击确定,省份自动填写到点击的单元格内。
- 城市对话框:点击城市单元格,会先进行此行省份数据是否为空。当省份为空时,弹出提示信息。省份不为空时,显示城市对话框,选择某行,点击确定,城市自动填写到点击的单元格内。
三、代码实现
1. 代码
<template>
<div>
<div class="box">
<!-- 添加行数据按钮 -->
<div @click="add" class="addBtn">
<a-icon type="plus" />添加
</div>
<!-- 表格 -->
<vxe-table
ref="xTable"
auto-resize
show-overflow
header-align="center"
row-id="id"
:data="tableData"
:row-config="{isHover:true}"
:edit-config="{ trigger: 'click', mode: 'cell', showIcon: false }"
@cell-click="cellClick"
>
<vxe-column field="id" title="工号" width="100" align="center"></vxe-column>
<vxe-column
field="name"
title="姓名"
width="100"
align="center"
:edit-render="{ name: 'input' }"
:filters="[]"
:filter-method="filterName"
></vxe-column>
<vxe-column
field="age"
title="年龄"
width="100"
align="center"
sortable
:edit-render="{ name: 'input' }"
></vxe-column>
<vxe-column
field="sex"
title="性别"
width="100"
align="center"
:edit-render="{}"
:filters="[{label: '男', value: 1}, {label: '女', value: 0}]"
:filter-multiple="false"
>
<template #default="{ row }">
<span>{{ formatSex(row.sex) }}</span>
</template>
<template #edit="{ row }">
<vxe-select v-model="row.sex" transfer>
<vxe-option
v-for="item in sexList"
:key="item.key"
:value="item.key"
:label="item.value"
></vxe-option>
</vxe-select>
</template>
</vxe-column>
<vxe-column
field="province"
title="省份"
width="100"
:edit-render="{ name: 'input' }"
:filters="[{ data: '' }]"
:filter-method="filterProvince"
>
<template #filter="{ $panel, column }">
<input
type="type"
v-for="(option, index) in column.filters"
:key="index"
v-model="option.data"
@input="$panel.changeOption($event, !!option.data, option)"
/>
</template>
</vxe-column>
<vxe-column field="city" title="城市" width="100" :edit-render="{ name: 'input' }"></vxe-column>
<vxe-column field="quit" title="离职" width="100">
<template #default="{ row }">
<a-checkbox :checked="row.quit" @change="quitChange(row)"></a-checkbox>
</template>
</vxe-column>
<vxe-column title="操作" fixed="right" width="100">
<template #default="{ row }">
<a-popconfirm
title="你确定要删除此条数据吗?"
ok-text="Yes"
cancel-text="No"
@confirm="confirmDelete(row)"
>
<vxe-button type="text" status="primary" content="删除"></vxe-button>
</a-popconfirm>
</template>
</vxe-column>
</vxe-table>
<!-- 省份对话框 -->
<a-modal
v-model="provinceModal"
title="省份"
@ok="provinceModalClose"
ok-text="确定"
cancel-text="取消"
destroy-on-close
>
<a-tree :treeData="provinceTree" @select="provinceTreeSelect" defaultExpandAll></a-tree>
</a-modal>
<!-- 城市对话框 -->
<a-modal
v-model="cityModal"
title="省份"
@ok="cityModalClose"
ok-text="确定"
cancel-text="取消"
destroy-on-close
>
<vxe-table
border
ref="xTable1"
:data="cityTable"
:radio-config="{highlight: true}"
@radio-change="radioChange"
>
<vxe-column type="radio" width="60"></vxe-column>
<vxe-column field="city" title="城市"></vxe-column>
</vxe-table>
</a-modal>
</div>
</div>
</template>
<script>
export default {
data() {
return {
tableData: [
{
id: 1001,
name: '小红',
age: 23,
sex: 0,
province: '广东省',
city: '广州',
quit: false
},
{
id: 1002,
name: '小白',
age: 26,
sex: 1,
province: '山东省',
city: '青岛',
quit: true
}
],
sexList: [{ key: 0, value: '女' }, { key: 1, value: '男' }],
selectRow: {}, // 选中某行
provinceModal: false, // 省份对话框
provinceTree: [], // 省份树数据
cityModal: false, // 城市对话框
treeSelect: '', // 省份树节点选择
cityTable: [], // 城市表格数据
cityData: [
{
province: '广东省',
city: ['广州', '珠海'],
}, {
province: '山东省',
city: ['青岛', '济南'],
}, {
province: '北京',
city: ['海淀区', '朝阳区', '昌平区'],
}, {
province: '黑龙江',
city: ['哈尔滨', '七台河', '佳木斯'],
},
],
citySelect: '' // 城市表格选择
}
},
mounted() {
// 异步加载筛选数据
setTimeout(() => {
const $table = this.$refs.xTable
if ($table) {
const nameColumn = $table.getColumnByField('name')
if (nameColumn) {
$table.setFilter(nameColumn, [
{ label: 'id大于1000', value: 1000 },
{ label: 'id大于1004', value: 1004 }
])
}
}
}, 500)
},
methods: {
/* 功能:格式化性别 */
formatSex(value) {
let result = this.sexList.filter(item => item.key === value)
return result[0].value
},
/* 功能:离职多选框变化 */
quitChange(row) {
row.quit = !row.quit
},
/* 功能:姓名列筛选 */
filterName({ value, row }) {
return row.id >= value
},
/* 功能:省份列筛选 */
filterProvince({ option, row }) {
return row.province.includes(option.data)
},
/* 功能:点击表格的单元格 */
cellClick({ row, column }) {
this.selectRow = row
if (column.property === 'province') {
this.getprovinceTree()
this.provinceModal = true
} else if (column.property === 'city') {
if (this.selectRow.province === '') {
this.$message.warning('请先选择省份!');
} else {
this.getCityTable()
this.cityModal = true
}
}
},
/* 功能:省份对话框确认 */
provinceModalClose() {
this.selectRow.province = this.treeSelect
this.treeSelect = ''
this.provinceModal = false
},
/* 功能:城市对话框确认 */
cityModalClose() {
this.selectRow.city = this.citySelect
this.citySelect = ''
this.cityModal = false
},
/* 功能:获取省份树数据 - 为了模拟调接口 */
getprovinceTree() {
this.provinceTree = []
let data = {
title: '中国',
key: 'china',
children: [
{
title: '广东省',
key: 'gd',
}, {
title: '山东省',
key: 'sd',
}, {
title: '北京',
key: 'bj',
}, {
title: '黑龙江省',
key: 'hlj',
},
]
}
this.provinceTree.push(data)
},
/* 功能:省份树节点选择 */
provinceTreeSelect(selectedKeys, info) {
// 将选中的省份赋值给表格
this.treeSelect = info.node.dataRef.title
// 此处不做城市清空操作(自行优化)
},
/* 功能:获取城市表格数据 */
getCityTable() {
// 获取对应城市的数据
let data = this.cityData.filter(item => item.province === this.selectRow.province)
// 修改数据格式
this.cityTable = data[0].city.map(item => {
let obj = {}
obj['city'] = item
return obj
})
},
/* 功能:城市表格单选变化 */
radioChange({ row }) {
this.citySelect = row.city
},
/* 功能:添加行记录 */
add() {
let newId = 1001 + this.tableData.length
let newData = {
id: newId,
name: '',
age: '',
sex: 0,
province: '',
city: '',
quit: false
}
this.tableData.unshift(newData)
this.$message.success('新增成功!');
},
/* 功能:删除一行记录 */
confirmDelete(row) {
let newData = this.tableData.filter(item => item.id !== row.id)
this.tableData = newData
this.$message.success('删除成功!');
},
}
}
</script>
<style>
.box {
margin: 50px;
width: 700px;
}
.addBtn {
margin: 5px;
cursor: pointer;
}
</style>
2.参数解释
1)vxe-table
属性名 | 说明 | 默认值 / 类型 |
---|---|---|
height | 表格的高度;支持铺满父容器或者固定高度,如果设置 auto 为铺满父容器(如果设置为 auto,则必须确保存在父节点且不允许存在相邻元素) | number |
max-height | 表格的最大高度 | number |
auto-resize | 自动监听父元素的变化去重新计算表格(对于父元素可能存在动态变化、显示隐藏的容器中、列宽异常等场景中的可能会用到) | false |
header-align | 所有的表头列的对齐方式 | left, center, right |
radio-change | 只对 type=radio 有效,当手动勾选并且值发生改变时触发的事件 | { newValue, oldValue, row, rowIndex, $rowIndex, column, columnIndex, $columnIndex, $event } |
cell-click | 单元格被点击时会触发该事件 | { row, rowIndex, $rowIndex, column, columnIndex, $columnIndex, triggerRadio, triggerCheckbox, triggerTreeNode, triggerExpandNode, $event } |
sortable | 是否允许列排序 | false |
2)column-config:列的默认参数
属性名 | 说明 | 默认值 / 类型 |
---|---|---|
isHover | 当鼠标移到列头时,是否要高亮当前列头 | false |
resizable | 每一列是否启用列宽调整 | false |
isCurrent | 当鼠标点击列头时,是否要高亮当前列 | false |
useKey | 是否需要为每一列的 VNode 设置 key 属性(非特殊情况下不需要使用) | false |
width | 每一列的宽度 | number, string |
minWidth | 每一列的最小宽度 | number, string |
3)edit-config:可编辑配置项
属性名 | 说明 | 默认值 / 类型 |
---|---|---|
trigger | 触发方式 | manual(手动触发方式,只能用于 mode=row),click(默认,点击触发编辑),dblclick(双击触发编辑) |
mode | 编辑模式 | cell(默认,单元格编辑模式),row(行编辑模式) |
4)row-config:行配置信息
属性名 | 说明 | 默认值 / 类型 |
---|---|---|
isHover | 当鼠标移到行时,是否要高亮当前行 | false |
isCurrent | 当鼠标点击行时,是否要高亮当前行 | false |