ivue-material-plus
Version:
A high quality UI components Library with Vue.js
104 lines (84 loc) • 2.43 kB
text/typescript
import {
defineComponent,
h,
getCurrentInstance,
inject,
onUnmounted,
onUpdated,
watch,
} from 'vue';
import defaultProps from './defaults';
import useRender from './render';
import useTableLayoutObserver from '../table-layout-observer';
import { removePopper } from '../utils';
import { addClass, removeClass } from '../../../utils/assist';
// ts
import type { VNode } from 'vue';
import type { TableBodyProps } from './defaults';
import { TableContextKey } from '../table/defaults';
const prefixCls = 'ivue-table-body';
export default defineComponent({
name: prefixCls,
props: defaultProps,
setup(props: TableBodyProps) {
// vm
const vm = getCurrentInstance();
// inject
const IvueTable = inject(TableContextKey);
const { wrappedRowRender } = useRender(props);
const { handleColumnsChange, handleScrollableWidthChange } =
useTableLayoutObserver(IvueTable);
// methods
// 渲染行数据
const renderRow = () => {
const list = props.store.states.data.value || [];
return list.reduce((prev: VNode[], row) => {
return prev.concat(wrappedRowRender(row, prev.length));
}, []);
};
// watch
watch(props.store.states.hoverRow, (newVal: number, oldVal: number) => {
// 没有固定列
if (!props.store.states.isFixedColumns.value) {
return;
}
// 延迟执行
let raf = window.requestAnimationFrame;
if (!raf) {
raf = (fn) => window.setTimeout(fn, 16);
}
raf(() => {
const rows = vm?.vnode.el?.querySelectorAll('.ivue-table-row');
const oldRow = rows[oldVal];
const newRow = rows[newVal];
// 删除之前的hover
if (oldRow) {
removeClass(oldRow, 'hover-row');
}
// 添加hover
if (newRow) {
addClass(newRow, 'hover-row');
}
});
});
// onUnmounted
onUnmounted(() => {
// tooltip显示时 删除popper
removePopper?.();
});
// onUpdated
onUpdated(() => {
// tooltip显示时 删除popper
removePopper?.();
});
return {
// methods
renderRow,
handleColumnsChange,
handleScrollableWidthChange,
};
},
render() {
return h('tbody', {}, [this.renderRow()]);
},
});