表格行配置项
边框
默认情况下,是不具有竖直方向的边框的,如果需要,可以使用border属性,它接受一个Boolean,设置为true即可启用。
<template>
<avue-crud :data="data"
:option="option"></avue-crud>
</template>
<script setup>
import { ref } from 'vue';
const data = ref([
{ name: '张三', sex: '男' },
{ name: '李四', sex: '女' }
]);
const option = ref({
border: true,
align: 'center',
menuAlign: 'center',
column: [
{ label: '姓名', prop: 'name' },
{ label: '性别', prop: 'sex' }
]
});
</script>
条纹
默认情况下,是不具有行彩色条纹的,如果需要,可以使用stripe属性,它接受一个Boolean,设置为true即可启用。
<template>
<avue-crud :data="data"
:option="option"></avue-crud>
</template>
<script setup>
import { ref } from 'vue';
const data = ref([
{
name: '张三',
sex: '男'
}, {
name: '李四',
sex: '女'
}
])
const option = ref({
stripe: true,
column: [
{
label: '姓名',
prop: 'name'
}, {
label: '性别',
prop: 'sex'
}
]
})
</script>行和单元格样式
对开开放了cell-style和row-style方法
<template>
<avue-crud :data="data"
:option="option"
:cell-style="cellStyle"
:row-style="rowStyle"></avue-crud>
</template>
<script setup>
import { ref } from 'vue';
const data = ref([
{ id: 1, name: '张三', money: 3000 },
{ id: 2, name: '李四', sex: false, money: 4000 },
{ id: 3, name: '王五', sex: false, money: 2000 }
]);
const option = ref({
column: [
{ label: '姓名', prop: 'name' },
{ label: '工资', prop: 'money' }
]
});
function rowStyle ({ row, column, rowIndex }) {
if (rowIndex % 2 === 0) {
return { backgroundColor: '#eee', color: '#fff' };
}
return {};
}
function cellStyle ({ row, column, rowIndex, columnIndex }) {
if (columnIndex === 1) {
if (row.money <= 3000) {
return {
color: 'green',
fontWeight: 'bold',
fontSize: '20px'
};
} else {
return {
color: 'red',
fontWeight: 'bold',
fontSize: '20px'
};
}
}
return {};
}
</script>
自定义行样式
.warning-row {
background-color: #f56c6c !important;
color: #fff;
}
.success-row {
background-color: #67c23a !important;
color: #fff;
}
.warning-row.hover-row td,
.success-row.hover-row td {
background-color: initial !important;
}可以通过指定 组件的 row-class-name 属性来为 crud 中的某一行添加 class,表明该行处于某种状态,返回当前行的row数据和行的序号index
<template>
<avue-crud :data="data"
:option="option"
:row-class-name="tableRowClassName"></avue-crud>
</template>
<script setup>
import { ref } from 'vue';
const data = ref([
{
name: '张三',
sex: '男'
},
{
name: '李四',
sex: '女'
}
]);
const option = ref({
column: [
{
label: '姓名',
prop: 'name'
},
{
label: '性别',
prop: 'sex'
}
]
});
const tableRowClassName = ({ row, rowIndex }) => {
if (rowIndex === 0) {
return 'warning-row';
} else if (rowIndex === 1) {
return 'success-row';
}
return '';
};
</script>
行多选
设selection属性为true即可;勾选的同时会回调selectionChange方法返回当前选中的数据,toggleRowSelection方法设置行勾选,toggleAllSelection方法设置全部勾选
<template>
<avue-crud ref="crud"
:data="data"
:option="option"
@selection-change="selectionChange">
<template #menu-left="{ size }">
<el-button type="success"
icon="el-icon-check"
:size="size"
@click="toggleAllSelection">选中全部</el-button>
<el-button type="success"
icon="el-icon-check"
:size="size"
@click="toggleRowSelection(data[0])">选中第一行</el-button>
<el-button type="success"
icon="el-icon-check"
:size="size"
@click="toggleSelection([data[1]])">选中第二行</el-button>
<el-button type="danger"
icon="el-icon-delete"
:size="size"
@click="toggleSelection()">取消选择</el-button>
</template>
</avue-crud>
</template>
<script setup>
import { ref } from 'vue';
import { ElMessage } from 'element-plus';
const crud = ref(null)
const data = ref([
{ id: 1, name: '张三', sex: '男' },
{ id: 2, name: '李四', sex: '女' }
]);
const option = ref({
selection: true,
align: 'center',
menuAlign: 'center',
column: [
{ label: '姓名', prop: 'name' },
{ label: '性别', prop: 'sex' }
]
});
const toggleAllSelection = () => {
crud.value.toggleAllSelection();
};
const toggleSelection = (data) => {
crud.value.toggleSelection(data);
};
const toggleRowSelection = (row) => {
crud.value.toggleRowSelection(row, true);
};
const selectionChange = (list) => {
ElMessage.success('选中的数据: ' + JSON.stringify(list));
};
</script>
树表半选行
提示
3.9.2+
树形表格开启多选后,可通过getHalfSelectionRows获取半选状态的行
<template>
<div>
<div class="demo-actions">
<el-button type="primary"
@click="selectChild">选中子节点</el-button>
<el-button @click="refreshHalfRows">获取半选行</el-button>
<el-button @click="clearSelection">清空选择</el-button>
</div>
<avue-crud ref="crud"
:option="option"
:data="data"
@selection-change="refreshHalfRows"></avue-crud>
<pre class="state-preview">{{ halfRowsText }}</pre>
</div>
</template>
<script setup>
import { nextTick, ref } from 'vue';
const crud = ref(null);
const halfRowsText = ref('点击“选中子节点”后查看半选行');
const data = ref([
{
id: 1,
event: '项目启动',
owner: '张三',
children: [
{
id: 11,
parentId: 1,
event: '需求评审',
owner: '李四'
},
{
id: 12,
parentId: 1,
event: '原型确认',
owner: '王五'
}
]
},
{
id: 2,
event: '开发阶段',
owner: '赵六',
children: [
{
id: 21,
parentId: 2,
event: '接口联调',
owner: '钱七'
}
]
}
]);
const option = ref({
border: true,
selection: true,
defaultExpandAll: true,
rowKey: 'id',
rowParentKey: 'parentId',
align: 'center',
menu: false,
column: [
{
label: '事件',
prop: 'event',
align: 'left',
width: 200
},
{
label: '负责人',
prop: 'owner'
}
]
});
const refreshHalfRows = () => {
const rows = crud.value?.getHalfSelectionRows?.() || [];
halfRowsText.value = rows.length
? JSON.stringify(rows, null, 2)
: '暂无半选行';
};
const selectChild = () => {
crud.value.toggleRowSelection(data.value[0].children[0], true);
nextTick(refreshHalfRows);
};
const clearSelection = () => {
crud.value.clearSelection();
nextTick(refreshHalfRows);
};
</script>
<style scoped>
.demo-actions {
margin-bottom: 12px;
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.state-preview {
margin-top: 12px;
max-height: 180px;
padding: 12px;
overflow: auto;
color: #e5e7eb;
background: #111827;
font-family: Consolas, 'Courier New', monospace;
font-size: 12px;
line-height: 1.5;
}
</style>
禁止某个项选择
selectable函数决定该行是否可以勾选
<template>
<avue-crud ref="crud"
:data="data"
:option="option"
@selection-change="selectionChange" />
</template>
<script setup>
import { ref } from 'vue';
import { ElMessage } from 'element-plus'
const data = ref([
{ id: 1, name: '张三', sex: '男' },
{ id: 2, name: '李四', sex: '女' }
]);
const option = ref({
selection: true,
selectable: (row, index) => index === 1,
tip: false,
align: 'center',
menuAlign: 'center',
column: [
{ label: '姓名', prop: 'name' },
{ label: '性别', prop: 'sex' }
]
});
const selectionChange = (list) => {
ElMessage.success('选中的数据', JSON.stringify(list));
};
</script>
翻页多选
设置reserveSelection为true保留之前的勾选
<template>
<avue-crud v-model:page="page"
:data="data"
:option="option"
@selection-change="selectionChange"
@on-load="onLoad" />
</template>
<script setup>
import { ref } from 'vue';
import { ElMessage } from 'element-plus';
const page = ref({
pageSize: 2,
pageSizes: [2],
total: 4,
});
const data = ref([]);
const option = ref({
selection: true,
reserveSelection: true,
align: 'center',
menuAlign: 'center',
column: [
{ label: '姓名', prop: 'name' },
{ label: '性别', prop: 'sex' },
],
});
const onLoad = (page) => {
if (page.currentPage === 1) {
data.value = [
{ id: 1, name: '张三', sex: '男' },
{ id: 2, name: '李四', sex: '女' },
];
} else if (page.currentPage === 2) {
data.value = [
{ id: 3, name: '王五', sex: '女' },
{ id: 4, name: '赵六', sex: '女' },
];
}
};
const selectionChange = (list) => {
ElMessage.success('选中的数据' + JSON.stringify(list));
};
</script>
多选提示
设置tip为false可以取消表格上方显示的提示,同时支持对应的卡槽自定义
<template>
<avue-crud :data="data"
:option="option">
<template #tip>
<el-tag type="danger">自定义内容</el-tag>
</template>
</avue-crud>
</template>
<script setup>
import { ref } from 'vue';
const data = ref([{
id: 1,
name: '张三',
sex: '男'
}, {
id: 2,
name: '李四',
sex: '女'
}])
const option = ref({
selection: true,
align: 'center',
menuAlign: 'center',
column: [
{
label: '姓名',
prop: 'name'
}, {
label: '性别',
prop: 'sex'
}
]
})
</script>行单选
单选一行数据时需要设置highlightCurrentRow属性为true,回调current-row-change方法,同时返回当前行的row数据,
<template>
<avue-crud ref="crud"
:data="data"
:option="option"
@current-row-change="handleCurrentRowChange"></avue-crud>
<div style="margin-top: 20px">
<el-button @click="setCurrent(data[1])">选中第二行</el-button>
<el-button @click="setCurrent()">取消选择</el-button>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { ElNotification } from 'element-plus';
const crud = ref(null);
const data = ref([
{
name: '张三',
sex: '男'
},
{
name: '李四',
sex: '女'
}
]);
const option = ref({
highlightCurrentRow: true,
column: [
{
label: '姓名',
prop: 'name'
},
{
label: '性别',
prop: 'sex'
}
]
});
const setCurrent = (row) => {
crud.value.setCurrentRow(row);
};
const handleCurrentRowChange = (val) => {
ElNotification({
showClose: true,
message: '单选' + JSON.stringify(val),
type: 'success'
});
};
</script>
行单选(利用卡槽)
这里利用了列自定义卡槽方式去实现行单选
<template>
<avue-crud ref="crud"
:data="data"
:option="option"
@row-click="rowClick">
<template #radio="{ row }">
<el-radio v-model="selectRow"
:label="row.$index">-</el-radio>
</template>
</avue-crud>
</template>
<script setup>
import { ref } from 'vue';
import { ElMessage } from 'element-plus'
const selectRow = ref('');
const data = ref([
{ id: 1, name: '张三', sex: '男' },
{ id: 2, name: '李四', sex: '女' }
]);
const option = ref({
align: 'center',
menuAlign: 'center',
column: [
{ label: '', prop: 'radio', width: 60, hide: false },
{ label: '姓名', prop: 'name' },
{ label: '性别', prop: 'sex' }
]
});
const rowClick = (row) => {
selectRow.value = row.$index;
ElMessage.success(`选择序号 ${row.$index}`);
};
</script>
展开行
使用expand属性时必须配置rowKey属性为你行数据的主键,不能重复, defaultExpandAll属性默认展开全部,expandRowKeys为展开指定rowKey主键的数组,同时你也可以调用toggleRowExpansion方法传入你要展开的row
<template>
<avue-crud ref="crud"
:option="option"
:data="data"
@expand-change="expandChange">
<template #expand="{ row }">
{{ row }}
</template>
</avue-crud>
</template>
<script setup>
import { ref } from 'vue';
import { ElMessage } from 'element-plus';
const option = ref({
expand: true,
expandRowKeys: [1],
rowKey: 'id',
column: [
{
label: '姓名',
prop: 'name'
},
{
label: '年龄',
prop: 'sex'
}
]
});
const data = ref([
{
id: 1,
name: '张三',
sex: 12
},
{
id: 2,
name: '李四',
sex: 20
}
]);
const expandChange = (row, expendList) => {
ElMessage.success('展开回调');
};
</script>
展开行(手风琴模式)
expand-change配置expandRowKeys去使用
<template>
<avue-crud ref="crud"
:option="option1"
:data="data"
@expand-change="expandChanges">
<template #expand="{ row }">
{{ row }}
</template>
</avue-crud>
</template>
<script setup>
import { ref } from 'vue';
import { ElMessage } from 'element-plus'; // 根据实际使用的库导入消息组件
const data = ref([
{ id: 1, name: '张三', sex: 12 },
{ id: 2, name: '李四', sex: 20 }
]);
const option1 = ref({
expand: true,
expandRowKeys: [],
rowKey: 'id',
column: [
{ label: '姓名', prop: 'name' },
{ label: '年龄', prop: 'sex' }
]
});
function expandChanges (row, expandList) {
if (expandList.length) {
option1.value.expandRowKeys = [];
if (row) {
option1.value.expandRowKeys.push(row.id);
}
} else {
option1.value.expandRowKeys = [];
}
ElMessage.success('展开回调');
}
</script>
行单击方法
单击一行数据时回调row-click方法,同时返回当前行的row数据,event当前的操作对象,column当前列的属性
<template>
<avue-crud :data="data"
:option="option"
@row-click="handleRowClick"></avue-crud>
</template>
<script setup>
import { ref } from 'vue';
import { ElNotification } from 'element-plus';
const data = ref([
{ name: '张三', sex: '男' },
{ name: '李四', sex: '女' }
]);
const option = ref({
column: [
{ label: '姓名', prop: 'name' },
{ label: '性别', prop: 'sex' }
]
});
const handleRowClick = (row, event, column) => {
ElNotification({
showClose: true,
message: JSON.stringify(row),
type: 'success',
});
};
</script>
行双击方法
双击一行触发 row-dblclick。当前普通表格包装器只转发 (row, column),不会转发第三个鼠标事件;卡片模式返回 (row, index)。若只需定位记录,直接使用第一个 row 参数。
<template>
<avue-crud :data="data"
:option="option"
@row-dblclick="handleRowDBLClick"></avue-crud>
</template>
<script setup>
import { ref } from 'vue';
import { ElNotification } from 'element-plus';
const data = ref([
{ name: '张三', sex: '男' },
{ name: '李四', sex: '女' }
]);
const option = ref({
column: [
{ label: '姓名', prop: 'name' },
{ label: '性别', prop: 'sex' }
]
});
const handleRowDBLClick = (row, event) => {
ElNotification({
showClose: true,
message: JSON.stringify(row),
type: 'success',
});
};
</script>
行拖拽排序
<!-- 导入需要的包 (一定要放到index.html中的head标签里) -->
<script src="https://cdn.staticfile.net/Sortable/1.10.0-rc2/Sortable.min.js"></script>rowSort: true 开启行拖拽,数据需要稳定主键(默认 id)。3.9.5 自动同步数组;事件参数为 (oldIndex, newIndex, row, sortedList)。完整数据预览和边界见「拖拽排序」页面。
<template>
<avue-crud :option="option"
:data="data"
@sortable-change="sortableChange"></avue-crud>
</template>
<script setup>
import { ref } from 'vue';
import { ElMessage } from 'element-plus'; // 或根据实际使用的库导入消息组件
const data = ref([
{ id: 1, text1: '内容1-1', text2: '内容1-2' },
{ id: 2, text1: '内容2-1', text2: '内容2-2' },
{ id: 3, text1: '内容3-1', text2: '内容3-2' },
{ id: 4, text1: '内容4-1', text2: '内容4-2' },
{ id: 5, text1: '内容5-1', text2: '内容5-2' }
]);
const option = ref({
rowKey: 'id',
addBtn: false,
menu: false,
rowSort: true,
column: [
{ label: '列内容1', prop: 'text1' },
{ label: '列内容2', prop: 'text2' }
]
});
function sortableChange (oldIndex, newIndex, row, sortedList) {
ElMessage.success(`记录 ${row.id}:下标 ${oldIndex} → ${newIndex};新顺序 ${sortedList.map(item => item.id).join(', ')}`);
}
</script>
行合并
提示
如果数据不确定参考动态数据行和列合并
通过给传入spanMethod方法可以实现合并行或列,方法的参数是一个对象,里面包含当前行row、当前列column、当前行号rowIndex、当前列号columnIndex四个属性。该函数可以返回一个包含两个元素的数组,第一个元素代表rowspan,第二个元素代表colspan。 也可以返回一个键名为rowspan和colspan的对象。
<template>
<avue-crud :data="data"
:option="option"
:span-method="spanMethod"></avue-crud>
</template>
<script setup>
import { ref } from 'vue';
const data = ref([
{
id: '12987122',
name: '王小虎',
amount1: '234',
amount2: '3.2',
amount3: 10
},
{
id: '12987123',
name: '王小虎',
amount1: '165',
amount2: '4.43',
amount3: 12
},
{
id: '12987124',
name: '王小虎',
amount1: '324',
amount2: '1.9',
amount3: 9
},
{
id: '12987125',
name: '王小虎',
amount1: '621',
amount2: '2.2',
amount3: 17
},
{
id: '12987126',
name: '王小虎',
amount1: '539',
amount2: '4.1',
amount3: 15
}
])
const option = ref({
border: true,
menu: false,
column: [
{
label: 'ID',
prop: 'id'
},
{
label: '姓名',
prop: 'name'
},
{
label: '数值 1',
prop: 'amount1'
},
{
label: '数值 2',
prop: 'amount2'
},
{
label: '数值 3',
prop: 'amount3'
}
]
})
function spanMethod ({ row, column, rowIndex, columnIndex }) {
if (rowIndex % 2 === 0) {
if (columnIndex === 0) {
return [1, 2]
} else if (columnIndex === 1) {
return [0, 0]
}
}
}
</script>