feat: 支持多列固定

This commit is contained in:
xuqingkai 2023-10-27 13:57:09 +08:00
parent 1662d1cf9e
commit 68affd2f59
5 changed files with 2222 additions and 35 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,20 @@
type AlignType = 'left' | 'center' | 'right' // 列的对齐方式
type SortDirection = 'asc' | 'desc' // 列的排序方向
export interface TableColumn {
// 列对应字段
prop: string
// 列对应字段标题
label: string
// 列宽度
width: string
// 是否开启列排序
sortable?: boolean
// 是否高亮
lightHigh?: boolean
// 列的对齐方式可选值left,center,right
align?: AlignType
// 列的排序方向
sortDirection?: SortDirection | ''
}

View File

@ -1,7 +1,7 @@
<template>
<view :class="`wd-table-col ${fixed ? 'is-fixed' : ''}`" :style="rootStyle">
<view :class="`wd-table-col`" :style="rootStyle">
<view
:class="`wd-table__cell ${stripe && isOdd(index) ? 'is-stripe' : ''} ${border ? 'is-border' : ''}`"
:class="`wd-table__cell ${stripe && isOdd(index) ? 'is-stripe' : ''} ${border ? 'is-border' : ''} is-${align}`"
v-for="(row, index) in column"
:key="index"
:style="rowStyle"
@ -27,26 +27,28 @@ export default {
import { Ref, computed, inject, onMounted, ref } from 'vue'
import { addUnit, isDef, objToStyle, isOdd } from '../common/util'
type AlignType = 'left' | 'center' | 'right'
interface Props {
//
prop: string
//
label: string
//
width?: string
// true, left, right
fixed?: string | boolean
width?: number
//
sortable?: boolean
//
lightHigh?: boolean
// left,center,right
align?: AlignType
}
const props = withDefaults(defineProps<Props>(), {
fixed: false, // true, left, right
sortable: false, //
lightHigh: false, //
width: '200rpx' //
width: 100, // px
align: 'left'
})
// eslint-disable-next-line @typescript-eslint/ban-types
@ -60,6 +62,9 @@ const stripe = computed(() => {
return $props.value.stripe || false
})
/**
* 是否有边框
*/
const border = computed(() => {
return $props.value.border || false
})
@ -107,17 +112,14 @@ const column = computed(() => {
})
onMounted(() => {
setColumns(
{
setColumns({
prop: props.prop,
label: props.label,
width: props.width,
fixed: props.fixed,
sortable: props.sortable,
sortDirection: '',
lightHigh: props.lightHigh
} // sortDirection
)
lightHigh: props.lightHigh,
align: props.align
})
})
function handleRowClick(index: number) {

View File

@ -3,7 +3,7 @@
<view :class="`wd-table--fixed ${isShadow ? 'is-shadow' : ''}`" :style="fixedStyle">
<view class="wd-table__header" v-if="showHeader">
<view
:class="`wd-table__cell ${column.fixed ? 'is-fixed' : ''} ${border ? 'is-border' : ''} ${stripe ? 'is-stripe' : ''}`"
:class="`wd-table__cell ${border ? 'is-border' : ''} ${stripe ? 'is-stripe' : ''}`"
:style="headerCellStyle(column.width)"
v-for="(column, index) in columns"
:key="index"
@ -13,13 +13,15 @@
</view>
<scroll-view class="wd-table__body" :style="fixedBodyStyle" :enable-flex="true" :scroll-y="true" :scroll-top="scrollTop">
<view id="fixed-body" style="display: inline-block"><slot name="fixed"></slot></view>
<view style="display: inline-flex" id="fixed-body">
<slot name="fixed"></slot>
</view>
</scroll-view>
</view>
<scroll-view :class="`wd-table is-border`" :style="wraperStyle" :scroll-x="true" :throttle="false" @scroll="handleWraperScroll">
<view class="wd-table__header" id="table-header" :style="rowStyle" v-if="showHeader">
<view
:class="`wd-table__cell ${column.fixed ? 'is-fixed' : ''} ${border ? 'is-border' : ''} ${stripe ? 'is-stripe' : ''}`"
:class="`wd-table__cell ${border ? 'is-border' : ''} ${stripe ? 'is-stripe' : ''}`"
:style="headerCellStyle(column.width)"
v-for="(column, index) in columns"
:key="index"
@ -50,7 +52,8 @@ export default {
<script lang="ts" setup>
import { type CSSProperties, computed, getCurrentInstance, nextTick, onMounted, provide, ref, watch } from 'vue'
import { addUnit, debounce, deepClone, getRect, isDef, objToStyle } from '../common/util'
import { addUnit, deepClone, getRect, isDef, objToStyle } from '../common/util'
import type { TableColumn } from '../wd-table-col/types'
interface Props {
//
@ -92,7 +95,7 @@ watch(
const scrollTop = ref<number>(0) // scroll-view
const scrollWidth = ref<number | string>('auto') // scroll-viewsticky
const columns = ref<Array<Record<string, any>>>([]) //
const columns = ref<TableColumn[]>([]) //
const $props = ref<Props>(props)
const fixedWidth = ref<number | string>(0) //
const isShadow = ref<boolean>(false) // shadow
@ -182,7 +185,7 @@ onMounted(() => {
* 设置列
* @param column
*/
function setColumns(column: Record<string, any>) {
function setColumns(column: TableColumn) {
columns.value = deepClone([...columns.value, column])
}
@ -250,12 +253,12 @@ provide('setColumns', setColumns)
<style lang="scss" scoped>
@import './index.scss';
scroll-view::-webkit-scrollbar {
display: none;
width: 0;
height: 0;
border-radius: 0;
background-color: transparent;
color: transparent;
}
// scroll-view::-webkit-scrollbar {
// display: none;
// width: 0;
// height: 0;
// border-radius: 0;
// background-color: transparent;
// color: transparent;
// }
</style>