ElementUI Plus
官方文档
文章目录
前言
只是记录自己在使用Element + 的过程中遇到的问题,并不一定适用于全部场景!!!
一、ElementUI Plus之Table
1.基础用法
基础用法及更多用法直接查看官方文档:Element
2.多选框改为单选框的解决办法
需求:单选表格的某一行数据进行操作
解决方案:
😮官方给出的
👍网友提出的
🌂我自己采用的解决方案如下
插槽使用radio
①在表格数据的最前面添加一列
<el-table-column>
</el-table-column>
②往这一列中加入插槽
<el-table-column>
<template #default="scope">
</template>
</el-table-column>
③往插槽中放入 单选框
<el-table-column>
<template #default="scope">
<el-radio v-model="tableData.tableRadio" :label="scope.row" @change="handleSelectionChange">{{""}}</el-radio>
</template>
</el-table-column>
//获取数据
const handleSelectionChange = (val: any) => {
var data = JSON.parse(JSON.stringify(val));
console.log("选中的数据", data);
}
对于单选框的属性去官网查看文档 单选框属性
3.实现手风琴效果(只展开一行)
需求:树形加载的表格数据,只需要展示一行而不是展开多行。
解决方案:
重点关注这两个属性
expand-row-keys:目前的展开行,需要设置 row-key 属性
expand-change:当用户对某一行展开或者关闭的时候会触发该事件
<el-table
:data="filterTableData"
row-key="id"
:expand-row-keys="tableData.expands"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
@expand-change="expndChange"
border>
<el-table-column prop="label" label="部门名称" />
</el-table>
事件函数使用了ts的语法,和Js大体一致只是可以对参数限制类型
//展开的节点
const expndChange = (data: any, index: any) => {
//index 展开属性 true,false
//每次触发前先清空
tableData.expands = [1 + ""]
if (index) {
// 每次push进去的是每行的ID
tableData.expands.push(data.id + "")
} else {
tableData.expands = [1 + ""]
}
}
**注意expand-row-keys绑定的值类型为array,里面存放的字符串是,而不是number,所以你会看到我的tableData.expands = [1 + “”]在后面取到值后在后面加了 +“” 进行处理 **
4.实现表格点击新增和删除效果
需求:需要使用表格来实现表单的效果(数据的新增)。点击按钮,新增一行,在该行写入数据,再点击一行,再写入数据,最后点击保存按钮即可将所有的数据进行保存。
解决方案:上代码,注意注意👉 el-table-column里面使用的时插槽的方法对数据进行了绑定
表格代码:
<el-table :data="tableData.list" ref="table" tooltip-effect="dark" border stripe style="width: 100%"
max-height="250">
<el-table-column label="序号" type="index" align="center"></el-table-column>
<el-table-column prop="driver" label="驾驶员" align="center">
<template #default="scope">
<el-input v-model="scope.row.driver"></el-input>
</template>
</el-table-column>
<el-table-column prop="plateNumber" label="车牌号" align="center">
<template #default="scope">
<el-input v-model="scope.row.plateNumber"></el-input>
</template>
</el-table-column>
<el-table-column fixed="right" label="操作">
<template #default="scope">
<el-button text size="small" @click.prevent="deleteRow(scope.$index)">
移除
</el-button>
</template>
</el-table-column>
</el-table>
<el-button class="mt-4" style="width: 100%" @click="addRow()">新增</el-button>
页面的参数及方法
//list用于存储创建的每一行数据
const tableData = reactive({
list: [] as any
})
//删除行数据
const deleteRow = (index: number) => {
console.log("需要删除的行", index)
//移除数组中下标为index的行
tableData.list.splice(index, 1);
}
//新增一行空数据
const addRow = () => {
var list: any = {
driver: '',
plateNumber: ''
}
tableData.list.push(list);
addData.list = tableData.list;
}
完整代码:
<!-- 新增车辆弹窗 -->
<template>
<SysDialog :title="dialog.title" :width="dialog.width" :height="dialog.height" :visible="dialog.visible"
@onClose="onClose" @onConfirm="confirm">
<template v-slot:content>
<el-table :data="tableData.list" ref="table" tooltip-effect="dark" border stripe style="width: 100%"
max-height="250">
<el-table-column label="序号" type="index" align="center"></el-table-column>
<el-table-column prop="driver" label="驾驶员" align="center">
<template #default="scope">
<el-input v-model="scope.row.driver"></el-input>
</template>
</el-table-column>
<el-table-column prop="plateNumber" label="车牌号" align="center">
<template #default="scope">
<el-input v-model="scope.row.plateNumber"></el-input>
</template>
</el-table-column>
<el-table-column fixed="right" label="操作">
<template #default="scope">
<el-button text size="small" @click.prevent="deleteRow(scope.$index)">
移除
</el-button>
</template>
</el-table-column>
</el-table>
<el-button class="mt-4" style="width: 100%" @click="addRow()">新增</el-button>
</template>
</SysDialog>
</template>
<script setup lang='ts'>
import SysDialog from '@/components/SysDialog.vue';
import useDialog from '@/hooks/useDialog';
import { reactive } from "vue";
//弹框属性
const { dialog, onShow, onClose } = useDialog()
//表格数据
const tableData = reactive({
list: [] as any
})
//录入的车辆信息向父组件传递
const addData = reactive({
list: [] as any
})
//弹窗展示
const show = () => {
//设置弹框的宽度
dialog.width = 650;
dialog.height = 450;
dialog.title = "车辆信息"
//显示弹框
onShow();
}
//删除行数据
const deleteRow = (index: number) => {
console.log("需要删除的行", index)
//移除数组中下标为index的行
tableData.list.splice(index, 1);
}
//新增一行空数据,点击新增一行按钮,创建一条对应的空元素
const addRow = () => {
var list: any = {
driver: '',
plateNumber: ''
}
tableData.list.push(list);
addData.list = tableData.list;
}
//子组件传值给父组件
const emit = defineEmits(['selectData'])
//弹框确定
const confirm = () => {
emit('selectData', addData)
console.log("传出的数据==>", addData)
onClose();
}
//暴露方法给外部使用
defineExpose({
show
})
</script>
5.el-Input框和其他控件宽度不统一的设置技巧
最根本的解决办法:使用style设置统一的宽度!!!
①el-input与el-date-picker长度不一致
原因:因为el-date-picker左侧会有一个icon的图标,而这个图标就回占据一定的宽度。
解决方法:使用占位图标:也就是在input上默认追加一个图标
<el-input disabled suffix-icon="el-icon-date"></el-input>
②el-input与el-select长度不一致
原因:因为el-select右侧有有一个icon的图标,而这个图标就回占据一定的宽度。
解决方法:
Ⅰ、使用占位图标:也就是在input上默认追加一个图标
<el-input disabled suffix-icon="el-icon-date"></el-input>
Ⅱ、有时候会有另外一种情况我这里没有截图,只是之前遇到了记录一下,只需要设置select的宽度为100%即可
<el-select style="width:100%">
6.el-table表格的合计行放到首行
问题描述:element plus 的表格合计默认是放到了表格的末尾,但是现在需要将表格的合计放到表格的头部
解决方案:修改element plus的样式,网上说使用flex后会有样式冲突,目前使用情况没有发现冲突,有的话请评论区指正一下😂草草记录一下避免自己忘记
<style scoped lang='scss'>
:deep(.el-table) {
display: flex;
flex-direction: column;
}
:deep(.el-table .el-table__inner-wrapper) {
order: 1;
}
</style>
7.el-table 表头复选框隐藏
问题描述:需要将表格的表头复选框给隐藏掉
解决方案:修改element Plus的对应样式
<style scoped lang="scss">
//隐藏表头的复选框
:deep(.el-table__header-wrapper .el-checkbox__inner){
//background-color: red !important;
display: none;
}
</style>
8.表格复选将某一行复选框禁用
问题描述:有时候需要将某一行的复选框禁用,比如:需要提交某一行的数据时,只允许用户选中未提交的数据,而已经提交的数据则直接不允许勾选。
解决方案:
找到复选框的那一列,新增一个 :selectable方法事件
<el-table-column type="selection" :selectable="selectable" width="50"></el-table-column>
// 是否禁用当前复选框
const selectable=(row:any, index:any)=>{
if (row.isAudit == 'true') { // 成立的条件:就是什么时候需要禁用
return false;
} else {
return true;
}
}
8.表格前端分页
问题:有时候我们不需要从后台进行数据的分页处理,只需要在前端获取了数据后进行分页
解决方案:
<el-table :height="tableHeigth"
:data="filterTableData.slice((listParm.currentPage - 1) * listParm.pageSize, listParm.currentPage * listParm.pageSize)"
border stripe>
</el-table>
<!-- 分页 -->
<el-pagination @size-change="sizeChange" @current-change="currentChange"
:current-page.sync="listParm.currentPage" :page-sizes="[10, 20, 40, 80, 100]"
:page-size="listParm.pageSize" :total="filterTableData.length"
layout="total, sizes, prev, pager, next, jumper" background></el-pagination>
业务部分
//分页参数
const listParm = reactive<UserListParm>({
deptId: '',
pageSize: 10,
currentPage: 1,
total: 0,
loginName: ''
})
//页容量改变时触发
const sizeChange = (size: number) => {
listParm.pageSize = size;
}
//页数改变时触发
const currentChange = (page: number) => {
listParm.currentPage = page;
}
主要注意一下啊表格data绑定的数据这里
:data="filterTableData.slice((listParm.currentPage - 1) * listParm.pageSize, listParm.currentPage * listParm.pageSize)"
9.表格原样导出
问题描述:需要将制作好的表格数据生成excel直接导出到本地
解决方案:不需要第三方插件库 使用blob 可以直接原样输出
给需要导出的element 表格新增一个 Id 属性,使用元素选择器进行选择导出
const demo = () => {
const tables: any = document.querySelectorAll('tr');
for (let i = 0; i < tables.length; i++) {//给所有的tr标签加边框 不然导出无边框
tables[i].style.border = '0.1px solid black';
}
var html = "<html><head><meta charset='utf-8' /></head><body>" + document.querySelectorAll("#MainTable")[0].outerHTML + "</body></html>";
var blob = new Blob([html], { type: "application/vnd.ms-excel" });
var url = URL.createObjectURL(blob);
var a = document.createElement("a");
a.href = url;
a.download = "报表.xls";
a.click();
URL.revokeObjectURL(url);
}
注意:第一点处理边框已经包含在上面代码里面,看实际情况处理,这里只是做一个记录
1.导出的数据可能在页面上看有边框,但是呢,导出后本地没有???
解决:需要重新给表格设置边框,代码如下,同时还需要对element的表头单独进行设置不然的话表头会没有边框
:header-cell-style="{ border: '1px solid', color: 'black', borderColor: '#EEF0F6' }"
onMounted(async () => {
//寻找所有的tr,并为所有的tr加上边框,不加导出没有边框
const tables: any = document.querySelectorAll('tr');
for (let i = 0; i < tables.length; i++) {
tables[i].style.border = '1px solid #EEF0F6';
//tables[i].style.backgroundColor = '#85A000';
}
})
2.使用官方的合并单元格方法后导出发现错位???
element-ui表格单元格合并后数据出现偏移问题及导出后合计行错位
10.前端简单对表格数据过滤
/**
* menuTable.list 为表格数据
* DataSet.search 为搜索的关键词
* data.title 为被检索的关键词
*/
const filterTableData = computed(() =>
menuTable.list.filter(
(data: any) =>
!DataSet.search || data.title.toLowerCase().includes(DataSet.search.toLowerCase())
)
)
<!---------------------------------------------------->
<el-input v-model="DataSet.search" placeholder="输入一级目录名称" clearable :prefix-icon="Search" />
<!--注意data绑定的是被检索后的值-->
<el-table :data="filterTableData" ></el-table>
二、 ElementUI Plus之From
- element-ui的form表单中,阻止input输入框回车提交
问题:element的form表单中有一个el-input时,在input中回车时会触发表单提交,并且页面会被刷新
解决方法:为Form表单加下面这个属性来阻止事件的触发
@submit.native.prevent
<el-form :model="form" @submit.native.prevent></el-form>
2、el-checkbox如何同时获得value值和label的值
<el-checkbox-group v-model="state.checkList">
<el-checkbox v-for="(item,index) in state.sendList" :key="index" :label="item.id" >{{ item.sendName }}</el-checkbox>
</el-checkbox-group>
直接使用花括号绑定需要显示的值 label标签绑定value值