perf: 👌表格代码优化

This commit is contained in:
wanglihui 2023-09-09 17:08:20 +08:00
parent 2930beb265
commit a31763cd2b
23 changed files with 337 additions and 60 deletions

View File

@ -0,0 +1,19 @@
import request from '@/utils/axios';
// 获取分类
export function categoryGet(params?: any) {
return request({
url: '/manager/workplace/category',
method: 'get',
params
});
}
// 新增分类
export function categoryPost(data: any) {
return request({
url: '/manager/workplace/category',
method: 'post',
data
});
}

View File

@ -35,8 +35,8 @@
<template v-else-if="item.formatter">
<slot :name="item.prop" :row="scope.row">{{ item.formatter(scope.row) }}</slot>
</template>
<template v-else>
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop] }}</slot>
<template v-else-if="item.prop">
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop!] }}</slot>
</template>
</template>
</el-table-column>

View File

@ -32,8 +32,8 @@
<template v-else-if="item.formatter">
<slot :name="item.prop" :row="scope.row">{{ item.formatter(scope.row) }}</slot>
</template>
<template v-else>
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop] }}</slot>
<template v-else-if="item.prop">
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop!] }}</slot>
</template>
</template>
</el-table-column>

View File

@ -33,7 +33,7 @@
<slot :name="item.prop" :row="scope.row">{{ item.formatter(scope.row) }}</slot>
</template>
<template v-else>
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop] }}</slot>
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop!] }}</slot>
</template>
</template>
</el-table-column>

View File

@ -35,8 +35,8 @@
<template v-else-if="item.formatter">
<slot :name="item.prop" :row="scope.row">{{ item.formatter(scope.row) }}</slot>
</template>
<template v-else>
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop] }}</slot>
<template v-else-if="item.prop">
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop!] }}</slot>
</template>
</template>
</el-table-column>

View File

@ -34,7 +34,7 @@
<slot :name="item.prop" :row="scope.row">{{ item.formatter(scope.row) }}</slot>
</template>
<template v-else>
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop] }}</slot>
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop!] }}</slot>
</template>
</template>
</el-table-column>

View File

@ -36,7 +36,7 @@
<slot :name="item.prop" :row="scope.row">{{ item.formatter(scope.row) }}</slot>
</template>
<template v-else>
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop] }}</slot>
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop!] }}</slot>
</template>
</template>
</el-table-column>

View File

@ -39,7 +39,7 @@
<slot :name="item.prop" :row="scope.row">{{ item.formatter(scope.row) }}</slot>
</template>
<template v-else>
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop] }}</slot>
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop!] }}</slot>
</template>
</template>
</el-table-column>

View File

@ -30,7 +30,7 @@
<slot :name="item.prop" :row="scope.row">{{ item.formatter(scope.row) }}</slot>
</template>
<template v-else>
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop] }}</slot>
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop!] }}</slot>
</template>
</template>
</el-table-column>

View File

@ -32,8 +32,8 @@
<template v-else-if="item.formatter">
<slot :name="item.prop" :row="scope.row">{{ item.formatter(scope.row) }}</slot>
</template>
<template v-else>
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop] }}</slot>
<template v-else-if="item.prop">
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop!] }}</slot>
</template>
</template>
</el-table-column>

View File

@ -23,8 +23,8 @@
<template v-else-if="item.formatter">
<slot :name="item.prop" :row="scope.row">{{ item.formatter(scope.row) }}</slot>
</template>
<template v-else>
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop] }}</slot>
<template v-else-if="item.prop">
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop!] }}</slot>
</template>
</template>
</el-table-column>

View File

@ -23,8 +23,8 @@
<template v-else-if="item.formatter">
<slot :name="item.prop" :row="scope.row">{{ item.formatter(scope.row) }}</slot>
</template>
<template v-else>
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop] }}</slot>
<template v-else-if="item.prop">
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop!] }}</slot>
</template>
</template>
</el-table-column>

View File

@ -29,8 +29,8 @@
<template v-else-if="item.formatter">
<slot :name="item.prop" :row="scope.row">{{ item.formatter(scope.row) }}</slot>
</template>
<template v-else>
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop] }}</slot>
<template v-else-if="item.prop">
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop!] }}</slot>
</template>
</template>
</el-table-column>

View File

@ -23,8 +23,8 @@
<template v-else-if="item.formatter">
<slot :name="item.prop" :row="scope.row">{{ item.formatter(scope.row) }}</slot>
</template>
<template v-else>
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop] }}</slot>
<template v-else-if="item.prop">
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop!] }}</slot>
</template>
</template>
</el-table-column>

View File

@ -32,8 +32,8 @@
<template v-else-if="item.formatter">
<slot :name="item.prop" :row="scope.row">{{ item.formatter(scope.row) }}</slot>
</template>
<template v-else>
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop] }}</slot>
<template v-else-if="item.prop">
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop!] }}</slot>
</template>
</template>
</el-table-column>

View File

@ -36,8 +36,8 @@
<template v-else-if="item.formatter">
<slot :name="item.prop" :row="scope.row">{{ item.formatter(scope.row) }}</slot>
</template>
<template v-else>
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop] }}</slot>
<template v-else-if="item.prop">
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop!] }}</slot>
</template>
</template>
</el-table-column>

View File

@ -35,8 +35,8 @@
<template v-else-if="item.formatter">
<slot :name="item.prop" :row="scope.row">{{ item.formatter(scope.row) }}</slot>
</template>
<template v-else>
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop] }}</slot>
<template v-else-if="item.prop">
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop!] }}</slot>
</template>
</template>
</el-table-column>

View File

@ -33,8 +33,8 @@
<template v-else-if="item.formatter">
<slot :name="item.prop" :row="scope.row">{{ item.formatter(scope.row) }}</slot>
</template>
<template v-else>
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop] }}</slot>
<template v-else-if="item.prop">
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop!] }}</slot>
</template>
</template>
</el-table-column>

View File

@ -0,0 +1,131 @@
<template>
<el-dialog
:model-value="value"
:width="600"
:align-center="true"
:close-on-click-modal="false"
:close-on-press-escape="false"
:draggable="true"
:z-index="99"
title="添加应用"
@close="onClose"
>
<div class="h-540px flex-col">
<el-input v-model="content" placeholder="请输入应用名称" />
<!-- 表格 -->
<div class="flex-1 overflow-hidden p-12px">
<el-table v-loading="loadTable" :data="tableData" :show-header="false" style="width: 100%; height: 100%">
<el-table-column v-for="(col, index) in column" v-bind="col" :key="index">
<template #default="{ row }">
<template v-if="col.render">
<component :is="col.render" :row="row"> </component>
</template>
<template v-else-if="col.formatter">
<slot :name="col.prop" :row="row">{{ col.formatter(row) }}</slot>
</template>
<template v-else-if="col.prop">
<slot :name="col.prop" :row="row">{{ row[col.prop] }}</slot>
</template>
</template>
</el-table-column>
</el-table>
</div>
</div>
<template #footer>
<el-space>
<el-button @click="onClose">取消</el-button>
<el-button type="primary" :loading="loaging" @click="onSend">确定</el-button>
</el-space>
</template>
</el-dialog>
</template>
<script lang="ts" name="AppDialog" setup>
import { ref } from 'vue';
import { ElMessage } from 'element-plus';
// API
import { categoryPost } from '@/api/workplace/category';
import { appGet } from '@/api/workplace/app';
interface IProps {
value: boolean;
}
const props = withDefaults(defineProps<IProps>(), {
value: false
});
const content = ref('');
const loaging = ref<boolean>(false);
const emits = defineEmits<{
(e: 'update:value', item: boolean): void;
(e: 'ok', item: any): void;
}>();
watch(
() => props.value,
(n, _o) => {
props.value = n;
if (n) {
getTableList();
}
}
);
/**
* 表格
*/
const column = reactive<Column.ColumnOptions[]>([
{
prop: 'name',
label: '名称'
},
{
prop: 'description',
label: '描述'
},
{
type: 'selection'
}
]);
const tableData = ref<any[]>([]);
const loadTable = ref<boolean>(false);
const queryFrom = reactive({
keyword: '',
page_size: 15,
page_index: 1
});
const getTableList = () => {
appGet(queryFrom).then((res: any) => {
tableData.value = res;
});
};
const onClose = () => {
emits('update:value', false);
};
//
const onSend = () => {
if (!content.value) {
return ElMessage.info('请输入分类!');
}
const fromData = {
name: content.value
};
loaging.value = true;
categoryPost(fromData)
.then((res: any) => {
loaging.value = false;
if (res.status == 200) {
ElMessage.success('新增分类成功!');
content.value = '';
onClose();
emits('ok', true);
}
})
.catch(err => {
loaging.value = false;
if (err.status == 400) {
ElMessage.error(err.msg);
}
});
};
</script>

View File

@ -0,0 +1,82 @@
<template>
<el-dialog
:model-value="value"
:width="400"
:align-center="true"
:close-on-click-modal="false"
:close-on-press-escape="false"
:draggable="true"
:z-index="99"
title="新增分类"
@close="onClose"
>
<div>
<el-input v-model="content" placeholder="请输入分类" />
</div>
<template #footer>
<el-space>
<el-button @click="onClose">取消</el-button>
<el-button type="primary" :loading="loaging" @click="onSend">保存</el-button>
</el-space>
</template>
</el-dialog>
</template>
<script lang="ts" name="CategoryDialog" setup>
import { ref } from 'vue';
import { ElMessage } from 'element-plus';
// API
import { categoryPost } from '@/api/workplace/category';
interface IProps {
value: boolean;
}
const props = withDefaults(defineProps<IProps>(), {
value: false
});
const content = ref('');
const loaging = ref<boolean>(false);
const emits = defineEmits<{
(e: 'update:value', item: boolean): void;
(e: 'ok', item: any): void;
}>();
watch(
() => props.value,
(n, _o) => {
console.log(props.value);
props.value = n;
}
);
//
const onClose = () => {
emits('update:value', false);
};
//
const onSend = () => {
if (!content.value) {
return ElMessage.info('请输入分类!');
}
const fromData = {
name: content.value
};
loaging.value = true;
categoryPost(fromData)
.then((res: any) => {
loaging.value = false;
if (res.status == 200) {
ElMessage.success('新增分类成功!');
content.value = '';
onClose();
emits('ok', true);
}
})
.catch(err => {
loaging.value = false;
if (err.status == 400) {
ElMessage.error(err.msg);
}
});
};
</script>

View File

@ -5,7 +5,7 @@
<div class="h-50px pl-12px pr-12px box-border flex items-center justify-between bd-title">
<div class="bd-title-left font-500 text-14px">分组</div>
<div class="flex items-center h-50px">
<i-bd-add :size="22" class="cursor-pointer" />
<i-bd-add :size="22" class="cursor-pointer" @click="categoryDialogValue = true" />
</div>
</div>
<div class="m-12px">
@ -13,17 +13,21 @@
</div>
<div class="flex-1 overflow-hidden">
<el-scrollbar>
<el-tree :data="dataTree">
<template #default="{ node }">
<div class="bd-tree-node">
<div>{{ node.label }}</div>
<div class="pr-12px flex items-center bd-opt">
<i-bd-editor :size="16" class="cursor-pointer pr-4px" />
<i-bd-delete :size="16" class="cursor-pointer" />
</div>
<div class="tree-warp p-12px pt-0">
<div
v-for="item in dataTree"
:key="item.category_no"
class="bd-tree-item"
:class="{ 'bd-tree-activate': item.category_no === optTree }"
@click="onOptTreeClick(item.category_no)"
>
<div class="flex-1 text">{{ item.name }}</div>
<div class="bd-opt">
<i-bd-editor :size="16" class="cursor-pointer pr-4px" />
<i-bd-delete :size="16" class="cursor-pointer" />
</div>
</template>
</el-tree>
</div>
</div>
</el-scrollbar>
</div>
</div>
@ -39,7 +43,7 @@
<el-input v-model="queryFrom.keyword" placeholder="名称" clearable />
</el-form-item>
<el-form-item class="mb-0 !mr-0">
<el-button type="primary">新增应用</el-button>
<el-button type="primary" @click="appDialogValue = true">新增应用</el-button>
</el-form-item>
</el-form>
</div>
@ -61,7 +65,7 @@
<slot :name="item.prop" :row="scope.row">{{ item.formatter(scope.row) }}</slot>
</template>
<template v-else>
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop] }}</slot>
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop!] }}</slot>
</template>
</template>
</el-table-column>
@ -83,29 +87,53 @@
</div>
</div>
<!-- E 右侧 表格 -->
<!-- 新增分类 -->
<CategoryDialog v-model:value="categoryDialogValue" />
<!-- 添加应用 -->
<AppDialog v-model:value="appDialogValue" />
</bd-page>
</template>
<script lang="tsx" name="CustomGroup" setup>
import { ElButton, ElSpace } from 'element-plus';
import CategoryDialog from './CategoryDialog.vue';
import AppDialog from './AppDialog.vue';
// API
import { categoryGet } from '@/api/workplace/category';
interface Tree {
id: number;
label: string;
category_no: string;
name: string;
sort_num: number;
}
/**
* 左侧分类
*/
const dataTree = ref<Tree[]>([
{
id: 1,
label: '项目管理'
},
{
id: 2,
label: '开发管理'
}
]);
const categoryDialogValue = ref<boolean>(false);
const dataTree = ref<Tree[]>([]);
const optTree = ref('');
//
const getCategoryData = () => {
categoryGet().then((res: any) => {
if (res.length > 0) {
dataTree.value = res;
optTree.value = res[0].category_no;
}
});
};
//
const onOptTreeClick = (no: string) => {
optTree.value = no;
};
/**
* 添加应用
*/
const appDialogValue = ref(false);
/**
* 表格
@ -169,6 +197,10 @@ const onCurrentChange = (current: number) => {
queryFrom.page_index = current;
getTableList();
};
onMounted(() => {
getCategoryData();
});
</script>
<style lang="scss" scoped>
@ -177,24 +209,37 @@ const onCurrentChange = (current: number) => {
border-right: 1px solid var(--el-card-border-color);
}
.bd-tree-node {
.bd-tree-item {
display: flex;
align-items: center;
justify-content: space-between;
flex: 1;
font-size: 14px;
height: 26px;
padding: 0 4px;
cursor: pointer;
border-radius: 4px;
margin-bottom: 4px;
.bd-opt {
display: none;
}
&:hover {
background-color: var(--el-menu-active-bg-color);
color: var(--el-menu-active-color);
.bd-opt {
display: block;
}
}
}
.bd-tree-activate {
background-color: var(--el-menu-active-bg-color);
.text {
color: var(--el-menu-active-color);
}
}
.bd-title {
border-bottom: 1px solid var(--el-card-border-color);
}

View File

@ -32,8 +32,8 @@
<template v-else-if="item.formatter">
<slot :name="item.prop" :row="scope.row">{{ item.formatter(scope.row) }}</slot>
</template>
<template v-else>
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop] }}</slot>
<template v-else-if="item.prop">
<slot :name="item.prop" :row="scope.row">{{ scope.row[item.prop!] }}</slot>
</template>
</template>
</el-table-column>

View File

@ -80,8 +80,8 @@ type ObjToKeyValArray<T> = {
}[keyof T];
declare namespace Column {
interface ColumnOptions {
prop: string;
label: string;
prop?: string;
label?: string;
type?: 'selection' | 'index' | 'expand';
fixed?: true | 'left' | 'right';
width?: string | number;