ivue-material-plus
Version:
A high quality UI components Library with Vue.js
124 lines (99 loc) • 3.09 kB
text/typescript
import {
getCurrentInstance,
onMounted,
computed,
onUpdated,
onBeforeMount,
onUnmounted,
} from 'vue';
import { throwError } from '../../utils/error';
// ts
import type { Table } from './table/defaults';
import type { TableHeader } from './table-header/types';
import type TableLayout from './table-layout';
function useLayoutObserver(root: Table) {
// vm
const vm = getCurrentInstance() as TableHeader;
// computed
// 表格布局
const tableLayout = computed(() => {
const layout = root.layout as TableLayout;
if (!layout) {
throwError('ivue-table', 'Can not find table layout');
}
return layout;
});
// methods
// 列宽度改变
const handleColumnsChange = (layout: TableLayout) => {
// 获取col
const cols = root.vnode.el?.querySelectorAll('colgroup > col') || [];
if (!cols.length) {
return;
}
// 扁平化列
const flattenColumns = layout.getFlattenColumns();
// 获取列的id
const columnsMap = {};
flattenColumns.forEach((column) => {
columnsMap[column.id] = column;
});
// 设置列的宽度啊
for (let i = 0, j = cols.length; i < j; i++) {
const col = cols[i];
const name = col.getAttribute('name');
const column = columnsMap[name];
if (column) {
col.setAttribute('width', column.columnWidth || column.width);
}
}
};
// 设置滚动宽度
const handleScrollableWidthChange = (layout: TableLayout) => {
const cols =
root.vnode.el?.querySelectorAll('colgroup > col[name=gutter]') || [];
for (let i = 0, j = cols.length; i < j; i++) {
const col = cols[i];
col.setAttribute(
'width',
layout.scrollY.value ? layout.gutterWidth : '0'
);
}
// gutter
const ths = root.vnode.el?.querySelectorAll('th.gutter') || [];
for (let i = 0, j = ths.length; i < j; i++) {
const th = ths[i];
th.style.width = layout.scrollY.value ? `${layout.gutterWidth}px` : '0';
th.style.display = layout.scrollY.value ? '' : 'none';
}
};
// 在实例初始化之后、进行数据侦听和事件/侦听器的配置之前同步调用。
onBeforeMount(() => {
// 吧当前 vm 对象添加到观察者
tableLayout.value.addObserver(vm);
});
// 卸载组件实例后调用
onUnmounted(() => {
tableLayout.value.removeObserver(vm);
});
// onMounted
onMounted(() => {
// 列改变
handleColumnsChange(tableLayout.value);
// 设置滚动宽度
handleScrollableWidthChange(tableLayout.value);
});
// onUpdated
// 在数据更改导致的虚拟 DOM 重新渲染和更新完毕之后被调用
onUpdated(() => {
// 列宽度改变
handleColumnsChange(tableLayout.value);
// 设置滚动宽度
handleScrollableWidthChange(tableLayout.value);
});
return {
handleColumnsChange,
handleScrollableWidthChange,
};
}
export default useLayoutObserver;