Skip to content

Commit

Permalink
feat: Table组件重构
Browse files Browse the repository at this point in the history
  • Loading branch information
kailong502431556 committed Oct 21, 2021
1 parent f648424 commit 07adefb
Show file tree
Hide file tree
Showing 21 changed files with 509 additions and 420 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ node_modules
dist
dist-ssr
*.local
components.d.ts
/components.d.ts
16 changes: 6 additions & 10 deletions components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
declare module 'vue' {
export interface GlobalComponents {
404: typeof import('./src/components/Error/404.vue')['default']
Aa: typeof import('E:/HBuilderProjects/element-plus-admin/src/components/aa.vue')['default']
Avatars: typeof import('./src/components/Avatars/index.vue')['default']
ComDetail: typeof import('./src/components/ComDetail/index.vue')['default']
ComDialog: typeof import('./src/components/ComDialog/index.vue')['default']
ComSearch: typeof import('./src/components/ComSearch/index.vue')['default']
ComTable: typeof import('./src/components/ComTable/index.vue')['default']
CountTo: typeof import('./src/components/CountTo/index.vue')['default']
Detail: typeof import('./src/components/Detail/index.vue')['default']
Dialog: typeof import('./src/components/Dialog/index.vue')['default']
Echart: typeof import('./src/components/Echart/index.vue')['default']
Editor: typeof import('./src/components/Editor/index.vue')['default']
ElAlert: typeof import('element-plus/es')['ElAlert']
Expand All @@ -21,8 +22,6 @@ declare module 'vue' {
ElCollapseTransition: typeof import('element-plus/es')['ElCollapseTransition']
ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
ElDescriptions: typeof import('element-plus/es')['ElDescriptions']
ElDescriptionsItem: typeof import('element-plus/es')['ElDescriptionsItem']
ElDialog: typeof import('element-plus/es')['ElDialog']
ElDrawer: typeof import('element-plus/es')['ElDrawer']
ElDropdown: typeof import('element-plus/es')['ElDropdown']
Expand Down Expand Up @@ -52,17 +51,14 @@ declare module 'vue' {
ElTimePicker: typeof import('element-plus/es')['ElTimePicker']
ElTimeSelect: typeof import('element-plus/es')['ElTimeSelect']
ElTooltip: typeof import('element-plus/es')['ElTooltip']
Highlight: typeof import('E:/HBuilderProjects/element-plus-admin/src/components/Highlight/index.vue')['default']
Loading: typeof import('element-plus/es')['ElLoadingDirective']
ParentView: typeof import('./src/components/ParentView/index.vue')['default']
Preview: typeof import('./src/components/Preview/index.vue')['default']
Qrcode: typeof import('./src/components/Qrcode/index.vue')['default']
Redirect: typeof import('./src/components/Redirect/index.vue')['default']
Search: typeof import('./src/components/Search/index.vue')['default']
Slot: typeof import('./src/components/Table/components/Slot.vue')['default']
Slot: typeof import('./src/components/ComTable/components/Slot.vue')['default']
SvgIcon: typeof import('./src/components/SvgIcon/index.vue')['default']
Table: typeof import('./src/components/Table/index.vue')['default']
TableColumn: typeof import('./src/components/Table/components/TableColumn.vue')['default']
TableColumn: typeof import('./src/components/ComTable/components/TableColumn.vue')['default']
}
}

Expand Down
Binary file removed src/assets/logo.png
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
</div>
</template>

<script setup lang="ts" name="Detail">
<script setup lang="ts" name="ComDetail">
import { PropType, ref, computed } from 'vue'
import { SchemaConfig } from './types'
Expand Down Expand Up @@ -65,11 +65,15 @@ const props = defineProps({
// 需要展示的数据
data: {
type: Object as PropType<IObj>,
default: () => {
return {}
},
required: true
},
// 布局展示的数据
schema: {
type: Array as PropType<SchemaConfig[]>,
default: () => [],
required: true
},
// 是否标题和内容各占一行 垂直布局
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
</el-dialog>
</template>

<script setup lang="ts" name="Dialog">
<script setup lang="ts" name="ComDialog">
import { ref, computed, PropType, nextTick, unref, useAttrs, useSlots } from 'vue'
import SvgIcon from '@/components/SvgIcon/index.vue'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@
</div>
</template>

<script setup lang="ts" name="Search">
<script setup lang="ts" name="ComSearch">
import { PropType, watch, ref, unref } from 'vue'
import { deepClone } from '@/utils'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,23 @@ export default defineComponent({
name: 'Slot',
props: {
row: {
type: Object as PropType<object>,
type: Object as PropType<IObj>,
default: () => null
},
index: {
type: Number as PropType<number>,
default: null
},
column: {
type: Object as PropType<object>,
type: Object as PropType<IObj>,
default: () => null
},
slotName: {
type: String as PropType<string>,
default: ''
}
},
render(props: any) {
render(props) {
const _this: any = inject('tableRoot')
return h(
'span',
Expand Down
159 changes: 159 additions & 0 deletions src/components/ComTable/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
<template>
<div>
<el-table ref="tableRef" :border="true" v-bind="getBindValue" @header-dragend="headerDragend">
<!-- 多选 -->
<el-table-column
v-if="selection"
type="selection"
:reserve-selection="reserveSelection"
width="40"
/>
<template v-for="item in columns">
<!-- 自定义索引 -->
<template v-if="item.type === 'index'">
<el-table-column
:key="item[item.field]"
v-bind="{ ...getItemBindValue(item) }"
type="index"
:index="item.index"
/>
</template>

<!-- 树型数据 -->
<template v-else-if="item.children && item.children.length">
<table-column :key="item[item.field]" :child="item" />
</template>

<template v-else>
<el-table-column
:key="item[item.field]"
v-bind="{ ...getItemBindValue(item) }"
:prop="item.field"
>
<!-- 表头插槽 -->
<template v-if="item.slots && item.slots.header" #header="scope">
<table-slot
v-if="item.slots && item.slots.header"
:slot-name="item.slots.header"
:column="item"
:index="scope.$index"
/>
</template>

<!-- 表格内容插槽自定义 -->
<template v-if="item.slots && item.slots.default" #default="scope">
<table-slot
v-if="item.slots && item.slots.default"
:slot-name="item.slots.default"
:row="scope.row"
:column="item"
:index="scope.$index"
/>
</template>
</el-table-column>
</template>
</template>
</el-table>

<div v-if="pagination" class="pagination__wrap">
<el-pagination
:style="paginationStyle"
:page-sizes="[10, 20, 30, 40, 50, 100]"
layout="total, sizes, prev, pager, next, jumper"
v-bind="getPaginationBindValue"
/>
</div>
</div>
</template>

<script setup lang="ts" name="ComTable">
import { PropType, computed, useAttrs, ref, getCurrentInstance, provide } from 'vue'
import { deepClone } from '@/utils'
import { isObject } from '@/utils/validate'
import TableColumn from './components/TableColumn.vue'
import TableSlot from './components/Slot.vue'
const props = defineProps({
// 表头
columns: {
type: Array as PropType<IObj[]>,
default: () => []
},
// 是否多选
selection: {
type: Boolean as PropType<boolean>,
default: false
},
// 是否展示分页
pagination: {
type: [Boolean, Object] as PropType<boolean | IObj>,
default: false
},
// 仅对 type=selection 的列有效,类型为 Boolean,为 true 则会在数据更新之后保留之前选中的数据(需指定 row-key)
reserveSelection: {
type: Boolean as PropType<boolean>,
default: false
}
})
const attrs = useAttrs()
const tableRef = ref<HTMLElement | null>(null)
function getTableRef() {
return tableRef.value as any
}
const _this = getCurrentInstance()
provide('tableRoot', _this)
const getBindValue = computed((): IObj => {
const bindValue = { ...attrs, ...props } as IObj
delete bindValue.columns
return bindValue
})
function getItemBindValue(item: IObj) {
const delArr: string[] = []
const obj = deepClone(item)
for (const key in obj) {
if (delArr.indexOf(key) !== -1) {
delete obj[key]
}
}
return obj
}
const getPaginationBindValue = computed((): IObj => {
const PaginationBindValue =
props.pagination && isObject(props.pagination) ? { ...props.pagination } : {}
return PaginationBindValue
})
const paginationStyle = computed(() => {
return {
textAlign: (props.pagination && (props.pagination as IObj).position) || 'right'
}
})
function headerDragend(newWidth: number, _: number, column: IObj) {
// 不懂为啥无法自动计算宽度,只能手动去计算了。。失望ing,到时候看看能不能优化吧。
const htmlArr = document.getElementsByClassName(column.id)
for (const v of htmlArr as any) {
if (v.firstElementChild) {
;(v.firstElementChild as any).style.width = newWidth + 'px'
}
}
}
defineExpose({
getTableRef
})
</script>

<style lang="less" scoped>
.pagination__wrap {
padding: 10px;
margin-top: 15px;
background: #fff;
}
</style>
2 changes: 1 addition & 1 deletion src/components/Preview/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ import { ref, reactive, computed, watch, nextTick, unref } from 'vue'
import { previewProps } from './props'
import { isFirefox } from '@/utils/validate'
import { on, off } from '@/utils/dom-utils'
import throttle from 'lodash-es/throttle'
import { throttle } from 'lodash-es'
import SvgIcon from '_c/SvgIcon/index.vue'
const mousewheelEventName = isFirefox() ? 'DOMMouseScroll' : 'mousewheel'
Expand Down
Loading

0 comments on commit 07adefb

Please sign in to comment.