效果展示
根据后端接口返回,当前登录用户详情中的页面中el-table组件的显示隐藏等功能。根据菜单id查询该菜单下能后显示的列。
后端返回的数据类型:
接收到后端返回的数据后处理数据结构. Table组件文件
<!-- 自己封装的Table组件文件 -->
onMounted(()=>{
//判断页面传递过来的数据对象:PropTableS中keySrequest是否为true;为true则请求后端的table列数据,否则使用自己定义的。(因为还没有定义所有页面的 列字段权限。所有得区分开来,不然其他页面在后端中不存在数据,table显示都会是空的)
if(props.PropTableS.keySrequest){
tablekey()
}
})
onActivated(() => {
//如果不是第一次进入这个页面,可以直接拿之前第一次进入保存的数据.
if(props.PropTableS.keySrequest && proxy.$router.currentRoute.value.meta.key){
TabKys = proxy.$router.currentRoute.value.meta.key
}
})
//请求后端数据,处理数据格式
function tablekey(){
proxy.$axios.get('/system/user/list_fields', {
permission_id:proxy.$router.currentRoute.value.meta.id
}).then((res) => {
let keycopy = JSON.parse(JSON.stringify(TabKys))
let list = {}
res.data.map(item=>{
list[item.code] = {
title :item.name, //列名
left_fixed:item.left_fixed == 1 ? true : false, //是否固定
fixed:item.left_fixed == 1 ? 'left' : false, //默认固定左侧
id:item.id, //字段id
sort:item.sort, //排序
status:item.status == 1 ? true : false, //显示/隐藏
isshow:item.isshow, //也是显示/隐藏,这个可以在自定义的数据中传递过来,因为之前的页面都是用的isshow,后端用的是status,前面页面太多不想改了。
width:keycopy[item.code].width, //自定义传递过来的列宽度
type:keycopy[item.code].type, //自定义传递过来的列类型,如('text','selelct','input'等等)
permission_id:proxy.$router.currentRoute.value.meta.id//提交给后端的菜单id。
}
})
//TabKys :渲染el-table组件的列对象数据 list:处理后端数据.
TabKys = list
//此处理是将进入页面请求后的数据保存,可以避免切换页面,丢失当前页面的table列。出现问题的场景(进入页面A,table组件列正常显示,切换到页面B后,在回到页面A。页面A没有列的名称了。因为路由设置页页面记住缓存。)
proxy.$router.options.routes[1].children.forEach(route=>{
route.meta.id == proxy.$router.currentRoute.value.meta.id ? route.meta.key == undefined ? route.meta.key = TabKys : '' : ''
})
tablekeyindex.value++
});
}
页面中定义的数据:
页面中定义的table数据
let PropTableS = reactive({
tableStyle: { //table的css
width: "99%",
margin: "auto",
},
keySrequest:true, //是否需要后端数据渲染
//自己定义的列的数据
keyS: proxy.$PublicAPI.SetTableCotentWidth({
//这不是一个完整列对象数据,因为其他值都在后端返回了。这里的意义就是可以自定义列的类型。后端中没有定义当前列类型字段,也可以不需要后端保存,可以自定义,
danjuleixing: {
type:'select' //类型:下拉
widht:'120px' //定义的宽度
},
status: {
type:'select'
},
}),
});
Table组件中右侧定义设置的组件(小齿轮)
<template>
<div class="Drawer">
<el-drawer
z-index="12"
:modal="false"
:before-close="beforeClose"
append-to="el-main"
class="drawerBox"
v-model="Props.DrawerObject.visible"
:close-on-click-modal="false"
:destroy-on-close="true"
:show-close="false"
>
<template #header="{ close, titleId, titleClass }">
<div class="deawerTitle">
<span>表单固定设置</span>
<span>
<Icons @click="close" :theme="'outline'" :size="20" :is="'close'"
/></span>
</div>
</template>
<div class="deawerScanner">
<el-input
v-model="input2"
@input="handelInput"
class="deawerScanner_input"
size="small"
placeholder="搜索关键词"
:prefix-icon="Search"
/>
</div>
<div>
<el-tabs
v-model="TabactiveName"
class="demo-tabs"
@tab-click="handleTableActiveClick"
>
<el-tab-pane label="固定列" name="0"></el-tab-pane>
<el-tab-pane label="隐藏/显示" name="1"></el-tab-pane>
</el-tabs>
</div>
<div class="deawerTop" :style="{ height: TopHeght + 'px' }">
<div class="deawerTop_All">
<el-checkbox
@click="handelCheack"
v-model="checked4"
label="全部固定"
/>
</div>
<div>
<FromData
ref="From"
:key="formkey"
@Drawer_switchChange="Drawer_switchChange"
class="FromDataDom"
:fromlist="fromlist"
style=""
:style="{ 'margin-top': '0px', height: domHeight + 'px' }"
></FromData>
</div>
<div class="botton_but">
<Button
plain
:title="'取消'"
@click="ButtonClick('')"
:pattern="'centre'"
/>
<Button
:plain="fromlist.scannerIsPlain"
:type="'primary'"
:title="'保存'"
@click="ButtonClick('save')"
:pattern="'centre'"
/>
</div>
</div>
</el-drawer>
</div>
</template>
<script lang="ts" setup>
import {
ref,
reactive,
onMounted,
defineProps,
watch,
onActivated,
getCurrentInstance,
onBeforeUnmount,
onUnmounted,
} from "vue";
import { Search } from "@element-plus/icons-vue";
import { FromData, Drawer, Icons, Button } from "@/components";
let Props = defineProps(["DrawerObject", "primarytablelist"]);
import { ElMessage, ElMessageBox } from "element-plus";
const primarytablelist = Props.primarytablelist;
const { proxy } = getCurrentInstance();
const From = ref(null);
let fromlist = reactive({});
let input2 = ref("");
let checked4 = ref(false);
let isEmit = ref(true);
let formkey = ref(0);
let TabactiveName = ref("0");
let domHeight = ref(0);
let TopHeght = ref(0);
onMounted(() => {
GelTableTitleUpdate(Props.DrawerObject.TabKys);
window.addEventListener("resize", resizeFun);
setTimeout(() => {
resizeFun();
}, 1);
});
onUnmounted(() => {
proxy.$bus.emit("addEvent", false);
});
function resizeFun() {
domHeight.value =
document.querySelector(".drawerBox").offsetHeight - 41 - 39 - 54 - 84 - 50;
TopHeght.value =
document.querySelector(".drawerBox").offsetHeight - 41 - 39 - 64;
}
function GelTableTitleUpdate(obj: object) {
let index = 0;
let objlength = 0;
for (const key in obj) {
if (key != "operate" && key != "selection" && key != "index") {
objlength++;
obj[key].type = "switch";
obj[key].icon = "drag";
if (obj[key].fixed) {
index++;
obj[key].value = true;
} else if (obj[key].value == "" || obj[key].value == false) {
delete obj[key].value;
}
} else if (key == "operate" || key == "selection" || key == "index") {
delete obj[key];
}
}
fromlist = {
index: "2",
labelwidth: 130,
formInline: false,
isInput: true,
position: "left",
component: "rigthoptins",
listData: obj,
newListData: JSON.parse(JSON.stringify(obj)),
};
handleTableActiveClick({props:{name:'0'}})
proxy.$bus.emit("addEvent", true);
index == objlength ? (checked4.value = true) : "";
}
function ButtonClick(type: string) {
let keys = Object.keys(fromlist.listData)
let list = {
permission_id:fromlist.listData[keys[0]].permission_id,
details:[]
}
if (type === "save") {
for (const key in fromlist.listData) {
let aa ={
'field_id':fromlist.listData[key].id,
'status':fromlist.listData[key].status,
'left_fixed':fromlist.listData[key].left_fixed
}
list.details.push(aa)
}
proxy.$axios.post('/system/user/list_set_fields', list).then((res) => {
if(res.code == 200){
ElMessage.success(res.message)
proxy.$bus.emit('UpdataTablerowKeys')
}else if(res.code == 500){
ElMessage.error(res.message)
}
})
}
}
function beforeClose() {
Props.DrawerObject.visible = false;
proxy.$bus.emit("addEvent", false);
}
proxy.$bus.on("UpdataRouterPath", (val: boolean) => {
Props.DrawerObject.visible = val;
});
function Drawer_switchChange(
key:string,
TableList:any
) {
fromlist.listData[key][TabactiveName.value == '0' ? 'left_fixed' : 'status'] = TableList[key]
Object.keys(TableList).length == Object.keys(fromlist.listData).length && Object.values(TableList).every(Boolean) ? checked4.value = true : checked4.value = false
}
function handelCheack() {
let bol = !checked4.value
From.value.getUpdataRigthOptions(bol);
for (const key in fromlist.listData) {
fromlist.listData[key][TabactiveName.value == '0' ? 'left_fixed' : 'status'] = From.value.TableList[key]
}
}
let inputval = ref("");
function handelInput(value: string) {
inputval.value = value;
setTimeout(() => {
aa(value);
}, 1000);
}
function aa(val: string) {
if (inputval.value == val) {
let list = JSON.parse(JSON.stringify(fromlist.newListData));
for (const key in list) {
if (val == "") {
fromlist.listData = JSON.parse(JSON.stringify(fromlist.newListData));
}
if (list[key].title.indexOf(val) == -1) {
delete list[key];
}
}
fromlist.listData = list;
formkey.value++;
}
}
function handleTableActiveClick(value: any) {
TabactiveName.value = value.props.name;
for (const key in fromlist.listData) {
fromlist.listData[key].value = fromlist.listData[key][TabactiveName.value == '0' ? 'left_fixed' : 'status']
}
checked4.value = Object.keys(fromlist.listData).every(item => fromlist.listData[item].value == true)
formkey.value++;
}
</script>
<style lang="less" scoped>
::v-deep el-drawer {
background: saddlebrown !important;
}
::v-deep .el-icon {
height: none;
}
::v-deep .drawerBox {
.el-drawer__header {
padding: 0px !important;
margin-bottom: 0px !important;
}
.el-drawer__body {
padding: 0px !important;
}
.el-input__wrapper {
box-shadow: none !important;
}
.deawerScanner {
border: none;
width: 100%;
padding: 0 9px;
border-bottom: 1px solid #e8eaf2;
height: 40px;
.input__wrapper {
box-shadow: none !important;
border: none !important;
}
.deawerScanner_input {
height: 39px !important;
border: none !important;
}
}
.elForm {
max-height: none !important;
}
.FromDataDom {
overflow: hidden;
overflow-y: auto;
scrollbar-width: thin; /* 设置滚动条为细条 */
// scrollbar-color: #888 #f1f1f1; /* 设置滚动条和轨道的颜色 */
}
.deawerTop {
width: 100%;
height: 87%;
padding: 0px 0px 0 12px;
.deawerTop_All {
height: 40px;
display: flex;
align-items: center;
}
}
width: 244px !important;
.deawerTitle {
padding: 0px 15px !important;
color: #5b6070 !important;
font-size: 14px !important;
width: 214px;
height: 40px;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid #e8eaf2;
}
.botton_but {
width: 83%;
height: 84px;
display: flex;
justify-items: center;
align-items: center;
margin-left: 8%;
.ButBox {
display: contents;
background: salmon;
}
}
.bottonMax_but {
position: fixed;
bottom: 0;
}
}
::v-deep.elForm {
padding: 0px !important;
}
::v-deep .el-drawer {
height: 89%;
top: 11% !important;
bottom: 0 !important;
}
// ::v-deep .drawerBox {
// position: absolute !important;
// top: 100 !important;
// right: 0 !important;
// bottom: 0 !important;
// z-index: 12;
// }
::v-deep .drawerDiv {
inset: 100% !important;
position: absolute !important;
top: 0 !important;
right: 0 !important;
bottom: 0 !important;
}
::v-deep .el-switch.is-checked .el-switch__core {
background: var(--Click_Nav_FontColor) !important;
}
::v-deep .el-button--primary {
background: var(--Click_Nav_FontColor) !important;
}
::v-deep .el-form-item__label {
display: block;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
::v-deep .el-tabs__nav-wrap::after {
height: 1px;
}
::v-deep .el-tabs__nav {
width: 100%;
display: flex;
justify-content: center;
}
::v-deep .switchClass {
display: flex;
i {
display: block;
height: 32px;
display: flex;
justify-content: center;
}
}
::v-deep .el-tabs__item:hover,
::v-deep .el-checkbox__input.is-checked + .el-checkbox__label {
color: var(--Click_Nav_FontColor) !important;
}
::v-deep .el-tabs__item.is-active {
color: var(--Click_Nav_FontColor) !important;
}
::cv-deep .el-tabs__active-bar {
background-color: var(--Click_Nav_FontColor) !important;
}
</style>
table组件
<template>
<div class="TableBox" id="TableBox">
<div class="DateilsTitle" v-if="props.PropTableS.title">
{{ props.PropTableS.title }}
</div>
<div v-if="props.PropTableS.headerRemarks" class="headerRemarks">
{{ props.PropTableS.headerRemarks }}
</div>
<el-table
v-if="TabKys"
class="singleTableRef"
ref="singleTableRef"
:data="getTables()"
:key="tablekeyindex"
>
<template v-for="(child, key, index) in TabKys">
<!-- 存在显示隐藏标识的字段 控制显示列 evalRowShow-->
<el-table-column
v-if="props.PropTableS.keySrequest ? evalRowShow(child.status||child.isshow) : true"></el-table-column>
</template>
<!-- 小齿轮在右侧显示 -->
<template v-if="PropTableS.tables" class="aaaaaa">
<el-table-column fixed="right" width="20px">
<template #header>
<Icons
@click="handelRightIcon(TabKys)"
:theme="'outline'"
:size="36"
:is="'config'"
/>
</template>
</el-table-column>
</template>
</el-table>
<!-- 小齿轮组件 -->
<Drawer
v-if="DrawerObject.visible"
:DrawerObject="DrawerObject"
:primarytablelist="TabKys"
></Drawer>
</div>
</template>
<script setup lang="ts">
onMounted(() => {
//判断是否包含keySrequest ,否则去自定义传递过来的table数据对象
if(props.PropTableS.keySrequest){
tablekey()
}
});
onActivated(() => {
//看看列信息是否在路由中有存起来,有值就是代表不是第一次进入该页面
if(props.PropTableS.keySrequest && proxy.$router.currentRoute.value.meta.key){
TabKys = proxy.$router.currentRoute.value.meta.key
}
});
//点击右侧设置按钮
function handelRightIcon(params: object) {
DrawerObject.visible = true;
DrawerObject.TabKys = JSON.parse(JSON.stringify(TabKys));
}
function evalRowShow(params:any){
return eval(params);
}
proxy.$bus.on('UpdataTablerowKeys',()=>{
tablekey()
})
function tablekey(){
proxy.$axios.get('/system/user/list_fields', {
permission_id:proxy.$router.currentRoute.value.meta.id
}).then((res) => {
let keycopy = JSON.parse(JSON.stringify(TabKys))
let list = {}
res.data.map(item=>{
list[item.code] = {
title :item.name,
left_fixed:item.left_fixed == 1 ? true : false,
fixed:item.left_fixed == 1 ? 'left' : false,
id:item.id,
sort:item.sort,
status:item.status == 1 ? true : false,
isshow:item.isshow,
width:keycopy[item.code].width,
type:keycopy[item.code].type,
permission_id:proxy.$router.currentRoute.value.meta.id
}
})
TabKys = list
//进入页面将列值数据保存
proxy.$router.options.routes[1].children.forEach(route=>{
route.meta.id == proxy.$router.currentRoute.value.meta.id ? route.meta.key == undefined ? route.meta.key = TabKys : '' : ''
})
tablekeyindex.value++
});
}