feat: 🎸 Table组件重构完成并给出相应示例
This commit is contained in:
@@ -1,73 +0,0 @@
|
||||
<template>
|
||||
<Button v-bind="getBindValue" :class="[getColor, $attrs.class]">
|
||||
<template #default="data">
|
||||
<slot name="icon" />
|
||||
<slot v-bind="data" />
|
||||
</template>
|
||||
</Button>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { PropType } from 'vue'
|
||||
import { defineComponent, computed, VNodeChild } from 'vue'
|
||||
import { Button } from 'ant-design-vue'
|
||||
export default defineComponent({
|
||||
name: 'AButton',
|
||||
components: { Button },
|
||||
inheritAttrs: false,
|
||||
props: {
|
||||
// 按钮类型
|
||||
type: {
|
||||
type: String as PropType<'primary' | 'default' | 'danger' | 'dashed' | 'link' | 'warning' | 'success' | 'info'>,
|
||||
default: 'default'
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean as PropType<boolean>,
|
||||
default: false
|
||||
},
|
||||
htmlType: {
|
||||
type: String as PropType<'button' | 'submit' | 'reset' | 'menu'>,
|
||||
default: 'button'
|
||||
},
|
||||
icon: {
|
||||
type: Object as PropType<VNodeChild | JSX.Element>,
|
||||
default: () => null
|
||||
},
|
||||
size: {
|
||||
type: String as PropType<'small' | 'large' | 'default'>,
|
||||
default: 'default'
|
||||
},
|
||||
loading: {
|
||||
type: Boolean as PropType<boolean>,
|
||||
default: false
|
||||
},
|
||||
ghost: {
|
||||
type: Boolean as PropType<boolean>,
|
||||
default: false
|
||||
},
|
||||
block: {
|
||||
type: Boolean as PropType<boolean>,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
setup(props, { attrs }) {
|
||||
const getColor = computed(() => {
|
||||
const res: string[] = []
|
||||
const { type, disabled } = props
|
||||
type && res.push(`ant-btn-${type}`)
|
||||
disabled && res.push('is-disabled')
|
||||
return res
|
||||
})
|
||||
|
||||
const getBindValue = computed((): any => {
|
||||
const otherTypes = ['warning', 'success', 'info']
|
||||
const bindValue = { ...attrs, ...props }
|
||||
if (otherTypes.indexOf(props.type) !== -1) {
|
||||
bindValue.type = 'default'
|
||||
}
|
||||
return bindValue
|
||||
})
|
||||
|
||||
return { getBindValue, getColor }
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -1,5 +1,5 @@
|
||||
import { PropType } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { Message } from '_c/Message'
|
||||
import { oneOf } from '@/utils'
|
||||
|
||||
import { Config } from './types'
|
||||
@@ -18,19 +18,19 @@ export const editorProps = {
|
||||
customAlert: (s: string, t: string) => {
|
||||
switch (t) {
|
||||
case 'success':
|
||||
ElMessage.success(s)
|
||||
Message.success(s)
|
||||
break
|
||||
case 'info':
|
||||
ElMessage.info(s)
|
||||
Message.info(s)
|
||||
break
|
||||
case 'warning':
|
||||
ElMessage.warning(s)
|
||||
Message.warning(s)
|
||||
break
|
||||
case 'error':
|
||||
ElMessage.error(s)
|
||||
Message.error(s)
|
||||
break
|
||||
default:
|
||||
ElMessage.info(s)
|
||||
Message.info(s)
|
||||
break
|
||||
}
|
||||
},
|
||||
|
||||
23
src/components/Message/index.ts
Normal file
23
src/components/Message/index.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
let messageInstance: any | null = null
|
||||
|
||||
const resetMessage = (options: any) => {
|
||||
if (messageInstance) {
|
||||
messageInstance.close()
|
||||
}
|
||||
messageInstance = ElMessage(options)
|
||||
}
|
||||
['error', 'success', 'info', 'warning'].forEach((type: string) => {
|
||||
resetMessage[type] = (options: any) => {
|
||||
if (typeof options === 'string') {
|
||||
options = {
|
||||
message: options
|
||||
}
|
||||
}
|
||||
options.type = type
|
||||
return resetMessage(options)
|
||||
}
|
||||
})
|
||||
|
||||
export const Message = resetMessage as any
|
||||
@@ -22,7 +22,7 @@
|
||||
<template v-if="item.itemType === 'switch'">
|
||||
<el-switch
|
||||
v-model="formInline[item.field]"
|
||||
v-bind="{...bindValue(item)}"
|
||||
v-bind="{...getItemBindValue(item)}"
|
||||
@change="((val) => {changeVal(val, item)})"
|
||||
/>
|
||||
</template>
|
||||
@@ -30,7 +30,7 @@
|
||||
<template v-if="item.itemType === 'input'">
|
||||
<el-input
|
||||
v-model="formInline[item.field]"
|
||||
v-bind="{...bindValue(item)}"
|
||||
v-bind="{...getItemBindValue(item)}"
|
||||
@change="((val) => {changeVal(val, item)})"
|
||||
/>
|
||||
</template>
|
||||
@@ -38,7 +38,7 @@
|
||||
<template v-if="item.itemType === 'select'">
|
||||
<el-select
|
||||
v-model="formInline[item.field]"
|
||||
v-bind="{...bindValue(item)}"
|
||||
v-bind="{...getItemBindValue(item)}"
|
||||
@change="((val) => {changeVal(val, item)})"
|
||||
>
|
||||
<el-option
|
||||
@@ -59,7 +59,7 @@
|
||||
<el-radio
|
||||
v-for="v in item.options"
|
||||
:key="item.optionValue ? v[item.optionValue] : v.value"
|
||||
v-bind="{...bindValue(item)}"
|
||||
v-bind="{...getItemBindValue(item)}"
|
||||
:label="item.optionValue ? v[item.optionValue] : v.value"
|
||||
>
|
||||
{{ item.optionLabel ? v[item.optionLabel] : v.label }}
|
||||
@@ -69,7 +69,7 @@
|
||||
<el-radio-button
|
||||
v-for="v in item.options"
|
||||
:key="item.optionValue ? v[item.optionValue] : v.value"
|
||||
v-bind="{...bindValue(item)}"
|
||||
v-bind="{...getItemBindValue(item)}"
|
||||
:label="item.optionValue ? v[item.optionValue] : v.value"
|
||||
>
|
||||
{{ item.optionLabel ? v[item.optionLabel] : v.label }}
|
||||
@@ -102,7 +102,7 @@
|
||||
<template v-if="item.itemType === 'timePicker'">
|
||||
<el-time-picker
|
||||
v-model="formInline[item.field]"
|
||||
v-bind="{...bindValue(item)}"
|
||||
v-bind="{...getItemBindValue(item)}"
|
||||
@change="((val) => {changeVal(val, item)})"
|
||||
/>
|
||||
</template>
|
||||
@@ -110,7 +110,7 @@
|
||||
<template v-if="item.itemType === 'timeSelect'">
|
||||
<el-time-select
|
||||
v-model="formInline[item.field]"
|
||||
v-bind="{...bindValue(item)}"
|
||||
v-bind="{...getItemBindValue(item)}"
|
||||
@change="((val) => {changeVal(val, item)})"
|
||||
/>
|
||||
</template>
|
||||
@@ -118,7 +118,7 @@
|
||||
<template v-if="item.itemType === 'datePicker' || item.itemType === 'dateTimePicker'">
|
||||
<el-date-picker
|
||||
v-model="formInline[item.field]"
|
||||
v-bind="{...bindValue(item)}"
|
||||
v-bind="{...getItemBindValue(item)}"
|
||||
@change="((val) => {changeVal(val, item)})"
|
||||
/>
|
||||
</template>
|
||||
@@ -236,7 +236,7 @@ export default defineComponent({
|
||||
}
|
||||
)
|
||||
|
||||
function bindValue(item: any) {
|
||||
function getItemBindValue(item: any) {
|
||||
const delArr: string[] = ['label', 'itemType', 'value', 'field']
|
||||
const obj = deepClone(item)
|
||||
for (const key in obj) {
|
||||
@@ -288,7 +288,7 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
return {
|
||||
bindValue,
|
||||
getItemBindValue,
|
||||
ruleForm,
|
||||
formInline,
|
||||
submitForm,
|
||||
|
||||
@@ -22,7 +22,7 @@ export default defineComponent({
|
||||
},
|
||||
render(props: any) {
|
||||
const _this: any = inject('tableRoot')
|
||||
return h('div', _this.slots[props.slotName]({
|
||||
return h('span', _this.slots[props.slotName]({
|
||||
row: props.row,
|
||||
column: props.column,
|
||||
index: props.index
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<el-table-column v-bind="{...bindValue(child)}" :prop="child.key">
|
||||
<el-table-column v-bind="{...getItemBindValue(child)}" :prop="child.key">
|
||||
<template v-for="item in child.children">
|
||||
<!-- 树型数据 -->
|
||||
<template v-if="item.children && item.children.length">
|
||||
@@ -12,7 +12,7 @@
|
||||
<template v-else>
|
||||
<el-table-column
|
||||
:key="item[item.key]"
|
||||
v-bind="{...bindValue(item)}"
|
||||
v-bind="{...getItemBindValue(item)}"
|
||||
:prop="item.key"
|
||||
>
|
||||
<!-- 表头插槽 -->
|
||||
@@ -20,25 +20,25 @@
|
||||
<table-slot
|
||||
v-if="item.slots && item.slots.header"
|
||||
:slot-name="item.slots.header"
|
||||
:row="scope.row"
|
||||
:column="item"
|
||||
:index="scope.$index"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<!-- 表格内容插槽自定义 -->
|
||||
<template #default="scope">
|
||||
<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"
|
||||
/>
|
||||
<!-- 不需要插槽 -->
|
||||
<div v-else style="display: inline-block;">
|
||||
{{ scope.row[item.key] }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 不需要插槽 -->
|
||||
<!-- <span v-if="!item.slots || !item.slots.default">
|
||||
{{ scope.row[item.key] }}
|
||||
</span> -->
|
||||
</el-table-column>
|
||||
</template>
|
||||
</template>
|
||||
@@ -62,7 +62,7 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
setup() {
|
||||
function bindValue(item: any) {
|
||||
function getItemBindValue(item: any) {
|
||||
const delArr: string[] = ['children']
|
||||
const obj = deepClone(item)
|
||||
for (const key in obj) {
|
||||
@@ -74,7 +74,7 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
return {
|
||||
bindValue
|
||||
getItemBindValue
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,60 +1,81 @@
|
||||
<template>
|
||||
<el-table ref="elTable" v-bind="getBindValue">
|
||||
<!-- 多选 -->
|
||||
<el-table-column
|
||||
v-if="selection"
|
||||
type="selection"
|
||||
width="55"
|
||||
/>
|
||||
<template v-for="item in columns">
|
||||
<!-- 树型数据 -->
|
||||
<template v-if="item.children && item.children.length">
|
||||
<table-column
|
||||
:key="item[item.key]"
|
||||
:child="item"
|
||||
/>
|
||||
</template>
|
||||
<div>
|
||||
<el-table ref="elTable" :border="true" v-bind="getBindValue" @header-dragend="headerDragend">
|
||||
<!-- 多选 -->
|
||||
<el-table-column
|
||||
v-if="selection"
|
||||
type="selection"
|
||||
width="55"
|
||||
/>
|
||||
<template v-for="item in columns">
|
||||
<!-- 自定义索引 -->
|
||||
<template v-if="item.type === 'index'">
|
||||
<el-table-column
|
||||
:key="item[item.key]"
|
||||
v-bind="{...getItemBindValue(item)}"
|
||||
type="index"
|
||||
:index="item.index"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<el-table-column
|
||||
:key="item[item.key]"
|
||||
v-bind="{...bindValue(item)}"
|
||||
:prop="item.key"
|
||||
>
|
||||
<!-- 表头插槽 -->
|
||||
<template v-if="item.slots && item.slots.header" #header="scope">
|
||||
<table-slot
|
||||
v-if="item.slots && item.slots.header"
|
||||
:slot-name="item.slots.header"
|
||||
:row="scope.row"
|
||||
:column="item"
|
||||
:index="scope.$index"
|
||||
/>
|
||||
</template>
|
||||
<!-- 树型数据 -->
|
||||
<template v-else-if="item.children && item.children.length">
|
||||
<table-column
|
||||
:key="item[item.key]"
|
||||
:child="item"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<!-- 表格内容插槽自定义 -->
|
||||
<template #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 v-else>
|
||||
<el-table-column
|
||||
:key="item[item.key]"
|
||||
v-bind="{...getItemBindValue(item)}"
|
||||
:prop="item.key"
|
||||
>
|
||||
<!-- 表头插槽 -->
|
||||
<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>
|
||||
<!-- 不需要插槽 -->
|
||||
<div v-else style="display: inline-block;">
|
||||
<!-- <span v-if="!item.slots || !item.slots.default">
|
||||
{{ scope.row[item.key] }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</span> -->
|
||||
</el-table-column>
|
||||
</template>
|
||||
</template>
|
||||
</template>
|
||||
</el-table>
|
||||
</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 lang="ts">
|
||||
import { defineComponent, PropType, computed, provide, getCurrentInstance, ref, unref } from 'vue'
|
||||
import { deepClone } from '@/utils'
|
||||
import { isObject } from '@/utils/is'
|
||||
import TableColumn from './components/TableColumn.vue'
|
||||
import TableSlot from './components/Slot.vue'
|
||||
export default defineComponent({
|
||||
@@ -71,6 +92,10 @@ export default defineComponent({
|
||||
selection: {
|
||||
type: Boolean as PropType<boolean>,
|
||||
default: false
|
||||
},
|
||||
pagination: {
|
||||
type: [Boolean, Object] as PropType<boolean | object>,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
setup(props, { attrs, slots }) {
|
||||
@@ -88,7 +113,7 @@ export default defineComponent({
|
||||
return bindValue
|
||||
})
|
||||
|
||||
function bindValue(item: any) {
|
||||
function getItemBindValue(item: any) {
|
||||
const delArr: string[] = []
|
||||
const obj = deepClone(item)
|
||||
for (const key in obj) {
|
||||
@@ -99,15 +124,45 @@ export default defineComponent({
|
||||
return obj
|
||||
}
|
||||
|
||||
const getPaginationBindValue = computed((): any => {
|
||||
const PaginationBindValue = props.pagination && isObject(props.pagination)
|
||||
? { ...(props.pagination as any) }
|
||||
: {}
|
||||
return PaginationBindValue
|
||||
})
|
||||
|
||||
const paginationStyle = computed(() => {
|
||||
return {
|
||||
textAlign: props.pagination && (props.pagination as any).position || 'right'
|
||||
}
|
||||
})
|
||||
|
||||
function headerDragend(newWidth: number, oldWidth: number, column: any, event: any) {
|
||||
// 不懂为啥无法自动计算宽度,只能手动去计算了。。失望ing,到时候看看能不能优化吧。
|
||||
const htmlArr = document.getElementsByClassName(column.id)
|
||||
for (const v of htmlArr) {
|
||||
if (v.firstElementChild) {
|
||||
(v.firstElementChild as any).style.width = newWidth + 'px'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
elTable,
|
||||
getBindValue, bindValue,
|
||||
getBindValue, getItemBindValue,
|
||||
slots,
|
||||
getTableRef
|
||||
getTableRef,
|
||||
getPaginationBindValue, paginationStyle,
|
||||
headerDragend
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style>
|
||||
<style lang="less" scoped>
|
||||
.pagination__wrap {
|
||||
margin-top: 15px;
|
||||
background: #fff;
|
||||
padding: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user