修改render渲染项的描述方式

This commit is contained in:
huangchenhao 2025-10-30 17:08:19 +08:00
parent 3721a658f8
commit 4e36b54bbc
3 changed files with 84 additions and 64 deletions

View File

@ -29,14 +29,17 @@
>
<!-- 自定义渲染render slot -->
<template v-if="col.render || col.slot" #default="scope">
<component v-if="col.render" :is="col.render(scope.row, scope.column, scope.$index)" />
<component
v-if="col.render"
:is="col.render(scope.row, scope.column, scope.$index)"
/>
<slot v-else-if="col.slot" :name="col.slot" v-bind="scope" />
</template>
</el-table-column>
<!-- 透传所有插槽 -->
<template v-for="(_, name) in $slots" #[name]="slotProps">
<slot :name="name" v-bind="slotProps || {}" />
<template v-for="name in Object.keys($slots)" #[name]="scope">
<slot :name="name" v-bind="typeof scope === 'object' ? scope : {}" />
</template>
</el-table>
@ -55,14 +58,14 @@
</template>
<script setup>
import { ref, computed } from 'vue'
import TableToolbar from './TableToolbar.vue'
import { useAutoHeight } from './useAutoHeight'
import { ref, computed } from "vue";
import TableToolbar from "./TableToolbar.vue";
import { useAutoHeight } from "./useAutoHeight";
defineOptions({
name: 'DynamicTable',
inheritAttrs: false //
})
name: "DynamicTable",
inheritAttrs: false, //
});
const props = defineProps({
/**
@ -70,53 +73,53 @@ const props = defineProps({
*/
dataSource: {
type: Array,
default: () => []
default: () => [],
},
/**
* 列配置
*/
columns: {
type: Array,
default: () => []
default: () => [],
},
/**
* 工具栏配置
*/
toolbar: {
type: Object,
default: null
default: null,
},
/**
* 是否启用自适应高度
*/
autoHeight: {
type: Boolean,
default: false
default: false,
},
/**
* 分页配置false 表示不分页
*/
pagination: {
type: [Object, Boolean],
default: false
}
})
default: false,
},
});
const emit = defineEmits(['selection-change'])
const emit = defineEmits(["selection-change"]);
const containerRef = ref(null)
const tableRef = ref(null)
const selectedRowKeys = ref([])
const containerRef = ref(null);
const tableRef = ref(null);
const selectedRowKeys = ref([]);
// ==================== ====================
const { tableHeight } = useAutoHeight(containerRef, {
enabled: props.autoHeight,
minHeight: 200
})
minHeight: 200,
});
const computedHeight = computed(() => {
return props.autoHeight ? tableHeight.value : undefined
})
return props.autoHeight ? tableHeight.value : undefined;
});
// ==================== ====================
/**
@ -124,28 +127,28 @@ const computedHeight = computed(() => {
* 原则: 仅设置默认值,不改变结构,用户配置优先
*/
const processedColumns = computed(() => {
return props.columns.map(col => {
return props.columns.map((col) => {
// (selection/index/expand),
if (col.type) return col
if (col.type) return col;
//
return {
showOverflowTooltip: true, //
align: 'center', //
showOverflowTooltip: true, //
align: "center", //
minWidth: col.width ? undefined : 100, //
...col //
}
})
})
...col, //
};
});
});
/**
* 获取列的 props用于 v-bind
* 过滤掉自定义属性 (render, slot)
*/
const getColumnProps = (col) => {
const { render, slot, ...restProps } = col
return restProps
}
const { render, slot, ...restProps } = col;
return restProps;
};
// ==================== ====================
/**
@ -153,28 +156,28 @@ const getColumnProps = (col) => {
*/
const handleSelectionChange = (selection) => {
// key
const rowKey = props.$attrs?.rowKey || props.$attrs?.['row-key'] || 'id'
selectedRowKeys.value = selection.map(row =>
typeof rowKey === 'function' ? rowKey(row) : row[rowKey]
)
const rowKey = props.$attrs?.rowKey || props.$attrs?.["row-key"] || "id";
selectedRowKeys.value = selection.map((row) =>
typeof rowKey === "function" ? rowKey(row) : row[rowKey]
);
emit('selection-change', selection)
}
emit("selection-change", selection);
};
/**
* 处理分页页码改变
*/
const handlePageChange = (page) => {
props.pagination?.onChange?.(page, props.pagination.pageSize)
}
props.pagination?.onChange?.(page, props.pagination.pageSize);
};
/**
* 处理每页条数改变
*/
const handleSizeChange = (size) => {
// ,
props.pagination?.onChange?.(1, size)
}
props.pagination?.onChange?.(1, size);
};
// ==================== ====================
defineExpose({
@ -192,11 +195,11 @@ defineExpose({
recalculate: () => {
if (props.autoHeight) {
setTimeout(() => {
tableHeight.recalculate?.()
}, 100)
tableHeight.recalculate?.();
}, 100);
}
}
})
},
});
</script>
<style scoped>

View File

@ -10,8 +10,9 @@
<script lang="ts" setup>
import DynamicTable from "../../component/DynamicTable";
import { h } from "vue";
import { h, onMounted } from "vue";
import { request } from "@/utils/request";
const tableData = [
{
county: "潼南",
@ -114,6 +115,20 @@ const tableData = [
service_station_address: "交通公路部门",
},
];
const getTableData = async () => {
try {
const params = {};
const res = await request({
url: "/api/asdsad/asdasd",
method: "GET",
params: params,
});
} catch (error) {}
};
onMounted(() => {
getTableData();
});
const columns = [
{
prop: "county",
@ -152,20 +167,16 @@ const columns = [
label: "操作",
fixed: "right",
width: 100,
render: (row) => {
return h(
ElButton,
{
type: "text",
on: {
click: () => {
console.log(row);
},
},
render: (row) => () => h(
ElButton,
{
type: "text",
onClick: () => {
console.log(row);
},
"详情"
);
},
},
() => "详情"
),
},
];
</script>

View File

@ -24,7 +24,13 @@ export default defineConfig({
server: {
port: 3000,
open: true,
cors: true
cors: true,
proxy: {
'/api': {
target: '',
changeOrigin: true,
},
}
},
build: {
outDir: 'dist',