主题切换
基于组合函数计算表格滚动高度
版本
- vue:3.4.27
- vueuse/core:14.1.0
- ant-design-vue:4.2.5
- mitt:3.0.1
源码
组合函数useComputeTableHeight
javascript
import { ref, onMounted, onUnmounted, watch, nextTick, computed } from 'vue';
import { useElementBounding, useElementSize, useRafFn } from '@vueuse/core';
import emits from '/@/utils/emits';
// 按照惯例,组合式函数名以“use”开头
export function useComputeTableHeight() {
const subtractHeight = ref(32); // 表格与footer元素的距离,这个值默认导出,可以修改。
const appHeight = ref(window.innerHeight); // 整个显示区域的高度
const tableTop = ref(0); // 表格距离顶部距离
const tableHeaderHeight = ref(0); // 表格表头高度
const footerHeight = ref(0); // 底部分页栏目高度
const tableRef = ref();
const tableHight = computed(() => {
// 整个显示区域的高度 - 表格距离顶部距离 - 表格表头高度 - 底部分页栏目高度 - 表格需要减去的高度
return appHeight.value - tableTop.value - tableHeaderHeight.value - footerHeight.value - subtractHeight.value;
});
// 一个组合式函数也可以挂靠在所属组件的生命周期上
// 来启动和卸载副作用
onMounted(() => {
initAppHeight();
initTableTop();
// 如果表头的宽度可以调整,需要监听表头的高度
initTableHeader();
// footer元素的高度,可以放分页组件等,根据业务要求来
initFooterHeight();
});
const initAppHeight = () => {
const appEl = document.getElementById('app');
if (appEl) {
const { height } = useElementSize(appEl as any);
watch(
height,
(newVal: number, oldVal: number) => {
// console.log('app元素的高度:', newVal);
appHeight.value = newVal;
},
{
immediate: true,
deep: true,
}
);
}
};
const initTableTop = () => {
const tableEl = document.getElementById('xy-ant-table');
if (tableEl) {
const { top, update } = useElementBounding(tableEl as any, {
windowResize: true, // 窗口大小变化时更新
windowScroll: true, // 滚动时更新
immediate: true, // 立即计算
});
// 如果表格的高度宽度没有变化的话,top不可以变化,所以需要用到update来更新
// 举例:如果表格上方存在的筛选区域可以展开收起,展开收起因为不涉及表格宽度高度变化,所以表格的top不会变化
emits.on('updateTableTop', () => {
update();
});
watch(
top,
(newVal: number, oldVal: number) => {
console.log('表格距离顶部:', newVal);
tableTop.value = newVal;
},
{
immediate: true,
deep: true,
}
);
}
};
const initTableHeader = () => {
const tableHeaderEl = document.querySelector('#my-ant-table .ant-table-header');
if (tableHeaderEl) {
const { height } = useElementSize(tableHeaderEl as any);
watch(
height,
(newVal: number, oldVal: number) => {
console.log('表格表头的高度:', newVal);
tableHeaderHeight.value = newVal;
},
{
immediate: true,
deep: true,
}
);
}
};
const initFooterHeight = () => {
const footerEl = document.querySelector('.smart-query-table-page');
if (footerEl) {
const { height } = useElementSize(footerEl as any);
watch(
height,
(newVal: number, oldVal: number) => {
// console.log('底部的高度:', newVal);
footerHeight.value = newVal;
},
{
immediate: true,
}
);
}
};
onUnmounted(() => {
});
// 通过返回值暴露所管理的状态
return { tableHight, subtractHeight, tableRef };
}emits文件
javascript
import mitt, { Emitter } from 'mitt'
export default mitt() as Emitter<any>使用
vue
import { useComputeTableHeight } from '/@/composables/useComputeTableHeight';
const { tableHight } = useComputeTableHeight();
<a-table id="my-ant-table" size="small">
</a-table>