feat: 拖拽表格
This commit is contained in:
parent
cfb3b3a5ce
commit
b69b8ed1bd
|
@ -1,7 +1,7 @@
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- release
|
||||||
|
|
||||||
name: Release
|
name: Release
|
||||||
|
|
||||||
|
|
|
@ -147,7 +147,15 @@ const adminList = [
|
||||||
component: 'views/Components/Table/TreeTable',
|
component: 'views/Components/Table/TreeTable',
|
||||||
name: 'TreeTable',
|
name: 'TreeTable',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'TreeTable'
|
title: 'router.TreeTable'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'table-image-preview',
|
||||||
|
component: 'views/Components/Table/TableImagePreview',
|
||||||
|
name: 'TableImagePreview',
|
||||||
|
meta: {
|
||||||
|
title: 'router.PicturePreview'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -490,6 +498,7 @@ const testList: string[] = [
|
||||||
'/components/table/default-table',
|
'/components/table/default-table',
|
||||||
'/components/table/use-table',
|
'/components/table/use-table',
|
||||||
'/components/table/tree-table',
|
'/components/table/tree-table',
|
||||||
|
'/components/table/table-image-preview',
|
||||||
'/components/table/ref-table',
|
'/components/table/ref-table',
|
||||||
'/components/editor-demo',
|
'/components/editor-demo',
|
||||||
'/components/editor-demo/editor',
|
'/components/editor-demo/editor',
|
||||||
|
|
|
@ -20,6 +20,7 @@ interface ListProps {
|
||||||
importance: number
|
importance: number
|
||||||
display_time: string
|
display_time: string
|
||||||
pageviews: number
|
pageviews: number
|
||||||
|
image_uri: string
|
||||||
}
|
}
|
||||||
|
|
||||||
interface TreeListProps {
|
interface TreeListProps {
|
||||||
|
@ -45,8 +46,8 @@ for (let i = 0; i < count; i++) {
|
||||||
content: baseContent,
|
content: baseContent,
|
||||||
importance: '@integer(1, 3)',
|
importance: '@integer(1, 3)',
|
||||||
display_time: '@datetime',
|
display_time: '@datetime',
|
||||||
pageviews: '@integer(300, 5000)'
|
pageviews: '@integer(300, 5000)',
|
||||||
// image_uri
|
image_uri: Mock.Random.image('@integer(300, 5000)x@integer(300, 5000)')
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
"pinia-plugin-persist": "^1.0.0",
|
"pinia-plugin-persist": "^1.0.0",
|
||||||
"qrcode": "^1.5.3",
|
"qrcode": "^1.5.3",
|
||||||
"qs": "^6.11.2",
|
"qs": "^6.11.2",
|
||||||
|
"sortablejs": "^1.15.0",
|
||||||
"url": "^0.11.1",
|
"url": "^0.11.1",
|
||||||
"vue": "3.3.4",
|
"vue": "3.3.4",
|
||||||
"vue-i18n": "9.2.2",
|
"vue-i18n": "9.2.2",
|
||||||
|
@ -66,6 +67,7 @@
|
||||||
"@types/nprogress": "^0.2.0",
|
"@types/nprogress": "^0.2.0",
|
||||||
"@types/qrcode": "^1.5.1",
|
"@types/qrcode": "^1.5.1",
|
||||||
"@types/qs": "^6.9.7",
|
"@types/qs": "^6.9.7",
|
||||||
|
"@types/sortablejs": "^1.15.1",
|
||||||
"@typescript-eslint/eslint-plugin": "^6.1.0",
|
"@typescript-eslint/eslint-plugin": "^6.1.0",
|
||||||
"@typescript-eslint/parser": "^6.1.0",
|
"@typescript-eslint/parser": "^6.1.0",
|
||||||
"@unocss/transformer-variant-group": "^0.53.5",
|
"@unocss/transformer-variant-group": "^0.53.5",
|
||||||
|
|
|
@ -78,7 +78,7 @@ export default defineComponent({
|
||||||
validateOnRuleChange: propTypes.bool.def(true),
|
validateOnRuleChange: propTypes.bool.def(true),
|
||||||
size: {
|
size: {
|
||||||
type: String as PropType<ComponentSize>,
|
type: String as PropType<ComponentSize>,
|
||||||
default: 'small'
|
default: undefined
|
||||||
},
|
},
|
||||||
disabled: propTypes.bool.def(false),
|
disabled: propTypes.bool.def(false),
|
||||||
scrollToError: propTypes.bool.def(false),
|
scrollToError: propTypes.bool.def(false),
|
||||||
|
|
|
@ -104,7 +104,9 @@ const getPasswordStrength = computed(() => {
|
||||||
height: inherit;
|
height: inherit;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
border-radius: inherit;
|
border-radius: inherit;
|
||||||
transition: width 0.5s ease-in-out, background 0.25s;
|
transition:
|
||||||
|
width 0.5s ease-in-out,
|
||||||
|
background 0.25s;
|
||||||
|
|
||||||
&[data-score='0'] {
|
&[data-score='0'] {
|
||||||
width: 20%;
|
width: 20%;
|
||||||
|
|
|
@ -1,6 +1,13 @@
|
||||||
<script lang="tsx">
|
<script lang="tsx">
|
||||||
import { ElTable, ElTableColumn, ElPagination, ComponentSize, ElTooltipProps } from 'element-plus'
|
import {
|
||||||
import { defineComponent, PropType, ref, computed, unref, watch, onMounted } from 'vue'
|
ElTable,
|
||||||
|
ElTableColumn,
|
||||||
|
ElPagination,
|
||||||
|
ComponentSize,
|
||||||
|
ElTooltipProps,
|
||||||
|
ElImage
|
||||||
|
} from 'element-plus'
|
||||||
|
import { defineComponent, PropType, ref, computed, unref, watch, onMounted, nextTick } from 'vue'
|
||||||
import { propTypes } from '@/utils/propTypes'
|
import { propTypes } from '@/utils/propTypes'
|
||||||
import { setIndex } from './helper'
|
import { setIndex } from './helper'
|
||||||
import type { TableProps, TableColumn, Pagination, TableSetProps } from './types'
|
import type { TableProps, TableColumn, Pagination, TableSetProps } from './types'
|
||||||
|
@ -8,6 +15,8 @@ import { set } from 'lodash-es'
|
||||||
import { CSSProperties } from 'vue'
|
import { CSSProperties } from 'vue'
|
||||||
import { getSlot } from '@/utils/tsxHelper'
|
import { getSlot } from '@/utils/tsxHelper'
|
||||||
import TableActions from './components/TableActions.vue'
|
import TableActions from './components/TableActions.vue'
|
||||||
|
import Sortable from 'sortablejs'
|
||||||
|
import { Icon } from '@/components/Icon'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'Table',
|
name: 'Table',
|
||||||
|
@ -48,6 +57,12 @@ export default defineComponent({
|
||||||
type: Array as PropType<Recordable[]>,
|
type: Array as PropType<Recordable[]>,
|
||||||
default: () => []
|
default: () => []
|
||||||
},
|
},
|
||||||
|
// 是否自动预览
|
||||||
|
preview: {
|
||||||
|
type: Array as PropType<string[]>,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
sortable: propTypes.bool.def(false),
|
||||||
height: propTypes.oneOfType([Number, String]),
|
height: propTypes.oneOfType([Number, String]),
|
||||||
maxHeight: propTypes.oneOfType([Number, String]),
|
maxHeight: propTypes.oneOfType([Number, String]),
|
||||||
stripe: propTypes.bool.def(false),
|
stripe: propTypes.bool.def(false),
|
||||||
|
@ -173,7 +188,7 @@ export default defineComponent({
|
||||||
scrollbarAlwaysOn: propTypes.bool.def(false),
|
scrollbarAlwaysOn: propTypes.bool.def(false),
|
||||||
flexible: propTypes.bool.def(false)
|
flexible: propTypes.bool.def(false)
|
||||||
},
|
},
|
||||||
emits: ['update:pageSize', 'update:currentPage', 'register', 'refresh'],
|
emits: ['update:pageSize', 'update:currentPage', 'register', 'refresh', 'sortable-change'],
|
||||||
setup(props, { attrs, emit, slots, expose }) {
|
setup(props, { attrs, emit, slots, expose }) {
|
||||||
const elTableRef = ref<ComponentRef<typeof ElTable>>()
|
const elTableRef = ref<ComponentRef<typeof ElTable>>()
|
||||||
|
|
||||||
|
@ -198,6 +213,33 @@ export default defineComponent({
|
||||||
return propsObj
|
return propsObj
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const sortableEl = ref()
|
||||||
|
// 初始化拖拽
|
||||||
|
const initDropTable = () => {
|
||||||
|
const el = unref(elTableRef)?.$el.querySelector('.el-table__body tbody')
|
||||||
|
if (!el) return
|
||||||
|
if (unref(sortableEl)) unref(sortableEl).destroy()
|
||||||
|
|
||||||
|
sortableEl.value = Sortable.create(el, {
|
||||||
|
handle: '.table-move',
|
||||||
|
animation: 180,
|
||||||
|
onEnd(e: any) {
|
||||||
|
emit('sortable-change', e)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => getProps.value.sortable,
|
||||||
|
async (v) => {
|
||||||
|
await nextTick()
|
||||||
|
v && initDropTable()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
const setProps = (props: TableProps = {}) => {
|
const setProps = (props: TableProps = {}) => {
|
||||||
mergeProps.value = Object.assign(unref(mergeProps), props)
|
mergeProps.value = Object.assign(unref(mergeProps), props)
|
||||||
outsideProps.value = { ...props } as any
|
outsideProps.value = { ...props } as any
|
||||||
|
@ -301,7 +343,7 @@ export default defineComponent({
|
||||||
})
|
})
|
||||||
|
|
||||||
const renderTreeTableColumn = (columnsChildren: TableColumn[]) => {
|
const renderTreeTableColumn = (columnsChildren: TableColumn[]) => {
|
||||||
const { align, headerAlign, showOverflowTooltip } = unref(getProps)
|
const { align, headerAlign, showOverflowTooltip, preview } = unref(getProps)
|
||||||
return columnsChildren.map((v) => {
|
return columnsChildren.map((v) => {
|
||||||
if (v.hidden) return null
|
if (v.hidden) return null
|
||||||
const props = { ...v } as any
|
const props = { ...v } as any
|
||||||
|
@ -312,12 +354,20 @@ export default defineComponent({
|
||||||
const slots = {
|
const slots = {
|
||||||
default: (...args: any[]) => {
|
default: (...args: any[]) => {
|
||||||
const data = args[0]
|
const data = args[0]
|
||||||
|
let isImageUrl = false
|
||||||
|
if (preview.length) {
|
||||||
|
isImageUrl = preview.some((item) => (item as string) === v.field)
|
||||||
|
}
|
||||||
|
|
||||||
return children && children.length
|
return children && children.length
|
||||||
? renderTreeTableColumn(children)
|
? renderTreeTableColumn(children)
|
||||||
: props?.slots?.default
|
: props?.slots?.default
|
||||||
? props.slots.default(args)
|
? props.slots.default(args)
|
||||||
: v?.formatter?.(data.row, data.column, data.row[v.field], data.$index) ||
|
: v?.formatter
|
||||||
data.row[v.field]
|
? v?.formatter?.(data.row, data.column, data.row[v.field], data.$index)
|
||||||
|
: isImageUrl
|
||||||
|
? renderPreview(data.row[v.field])
|
||||||
|
: data.row[v.field]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (props?.slots?.header) {
|
if (props?.slots?.header) {
|
||||||
|
@ -338,6 +388,21 @@ export default defineComponent({
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const renderPreview = (url: string) => {
|
||||||
|
return (
|
||||||
|
<div class="flex items-center">
|
||||||
|
<ElImage
|
||||||
|
src={url}
|
||||||
|
fit="cover"
|
||||||
|
class="w-[100%] h-100px"
|
||||||
|
lazy
|
||||||
|
preview-src-list={[url]}
|
||||||
|
preview-teleported
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
const renderTableColumn = (columnsChildren?: TableColumn[]) => {
|
const renderTableColumn = (columnsChildren?: TableColumn[]) => {
|
||||||
const {
|
const {
|
||||||
columns,
|
columns,
|
||||||
|
@ -347,7 +412,8 @@ export default defineComponent({
|
||||||
align,
|
align,
|
||||||
headerAlign,
|
headerAlign,
|
||||||
showOverflowTooltip,
|
showOverflowTooltip,
|
||||||
reserveSelection
|
reserveSelection,
|
||||||
|
preview
|
||||||
} = unref(getProps)
|
} = unref(getProps)
|
||||||
|
|
||||||
return (columnsChildren || columns).map((v) => {
|
return (columnsChildren || columns).map((v) => {
|
||||||
|
@ -384,12 +450,21 @@ export default defineComponent({
|
||||||
const slots = {
|
const slots = {
|
||||||
default: (...args: any[]) => {
|
default: (...args: any[]) => {
|
||||||
const data = args[0]
|
const data = args[0]
|
||||||
|
|
||||||
|
let isImageUrl = false
|
||||||
|
if (preview.length) {
|
||||||
|
isImageUrl = preview.some((item) => (item as string) === v.field)
|
||||||
|
}
|
||||||
|
|
||||||
return children && children.length
|
return children && children.length
|
||||||
? renderTreeTableColumn(children)
|
? renderTreeTableColumn(children)
|
||||||
: props?.slots?.default
|
: props?.slots?.default
|
||||||
? props.slots.default(args)
|
? props.slots.default(args)
|
||||||
: v?.formatter?.(data.row, data.column, data.row[v.field], data.$index) ||
|
: v?.formatter
|
||||||
data.row[v.field]
|
? v?.formatter?.(data.row, data.column, data.row[v.field], data.$index)
|
||||||
|
: isImageUrl
|
||||||
|
? renderPreview(data.row[v.field])
|
||||||
|
: data.row[v.field]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (props?.slots?.header) {
|
if (props?.slots?.header) {
|
||||||
|
@ -419,6 +494,21 @@ export default defineComponent({
|
||||||
if (getSlot(slots, 'append')) {
|
if (getSlot(slots, 'append')) {
|
||||||
tableSlots['append'] = (...args: any[]) => getSlot(slots, 'append', args)
|
tableSlots['append'] = (...args: any[]) => getSlot(slots, 'append', args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { sortable } = unref(getProps)
|
||||||
|
|
||||||
|
const sortableEl = sortable ? (
|
||||||
|
<ElTableColumn
|
||||||
|
className="table-move cursor-move"
|
||||||
|
type="sortable"
|
||||||
|
prop="sortable"
|
||||||
|
width="60px"
|
||||||
|
align="center"
|
||||||
|
>
|
||||||
|
<Icon icon="ant-design:drag-outlined" />
|
||||||
|
</ElTableColumn>
|
||||||
|
) : null
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div v-loading={unref(getProps).loading}>
|
<div v-loading={unref(getProps).loading}>
|
||||||
{unref(getProps).showAction ? (
|
{unref(getProps).showAction ? (
|
||||||
|
@ -426,7 +516,7 @@ export default defineComponent({
|
||||||
) : null}
|
) : null}
|
||||||
<ElTable ref={elTableRef} data={unref(getProps).data} {...unref(getBindValue)}>
|
<ElTable ref={elTableRef} data={unref(getProps).data} {...unref(getBindValue)}>
|
||||||
{{
|
{{
|
||||||
default: () => renderTableColumn(),
|
default: () => [sortableEl, ...renderTableColumn()],
|
||||||
...tableSlots
|
...tableSlots
|
||||||
}}
|
}}
|
||||||
</ElTable>
|
</ElTable>
|
||||||
|
|
|
@ -91,5 +91,7 @@ export interface TableProps extends Omit<Partial<ElTableProps<any[]>>, 'data'> {
|
||||||
align?: 'left' | 'center' | 'right'
|
align?: 'left' | 'center' | 'right'
|
||||||
// 表头对齐方式
|
// 表头对齐方式
|
||||||
headerAlign?: 'left' | 'center' | 'right'
|
headerAlign?: 'left' | 'center' | 'right'
|
||||||
|
preview?: string[]
|
||||||
|
sortable?: boolean
|
||||||
data?: Recordable
|
data?: Recordable
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,7 +94,9 @@ const toDocument = () => {
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
.fade-bottom-enter-active,
|
.fade-bottom-enter-active,
|
||||||
.fade-bottom-leave-active {
|
.fade-bottom-leave-active {
|
||||||
transition: opacity 0.25s, transform 0.3s;
|
transition:
|
||||||
|
opacity 0.25s,
|
||||||
|
transform 0.3s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fade-bottom-enter-from {
|
.fade-bottom-enter-from {
|
||||||
|
|
|
@ -154,6 +154,11 @@ export const useTable = (config: UseTableConfig) => {
|
||||||
|
|
||||||
refresh: () => {
|
refresh: () => {
|
||||||
methods.getList()
|
methods.getList()
|
||||||
|
},
|
||||||
|
|
||||||
|
sortableChange: (e: any) => {
|
||||||
|
const { oldIndex, newIndex } = e
|
||||||
|
dataList.value.splice(newIndex, 0, dataList.value.splice(oldIndex, 1)[0])
|
||||||
}
|
}
|
||||||
// // 删除数据
|
// // 删除数据
|
||||||
// delList: async (ids: string[] | number[], multiple: boolean, message = true) => {
|
// delList: async (ids: string[] | number[], multiple: boolean, message = true) => {
|
||||||
|
|
|
@ -158,7 +158,9 @@ export default {
|
||||||
role: 'Role management',
|
role: 'Role management',
|
||||||
document: 'Document',
|
document: 'Document',
|
||||||
inputPassword: 'InputPassword',
|
inputPassword: 'InputPassword',
|
||||||
sticky: 'Sticky'
|
sticky: 'Sticky',
|
||||||
|
treeTable: 'Tree table',
|
||||||
|
PicturePreview: 'Table Image Preview'
|
||||||
},
|
},
|
||||||
permission: {
|
permission: {
|
||||||
hasPermission: 'Please set the operation permission value'
|
hasPermission: 'Please set the operation permission value'
|
||||||
|
@ -426,7 +428,9 @@ export default {
|
||||||
showOrHiddenStripe: 'Show or hidden stripe',
|
showOrHiddenStripe: 'Show or hidden stripe',
|
||||||
showOrHiddenBorder: 'Show or hidden border',
|
showOrHiddenBorder: 'Show or hidden border',
|
||||||
fixedHeaderOrAuto: 'Fixed header or auto',
|
fixedHeaderOrAuto: 'Fixed header or auto',
|
||||||
getSelections: 'Get selections'
|
getSelections: 'Get selections',
|
||||||
|
preview: 'Preview',
|
||||||
|
showOrHiddenSortable: 'Show or hidden sortable'
|
||||||
},
|
},
|
||||||
richText: {
|
richText: {
|
||||||
richText: 'Rich text',
|
richText: 'Rich text',
|
||||||
|
|
|
@ -158,7 +158,9 @@ export default {
|
||||||
role: '角色管理',
|
role: '角色管理',
|
||||||
document: '文档',
|
document: '文档',
|
||||||
inputPassword: '密码输入框',
|
inputPassword: '密码输入框',
|
||||||
sticky: '黏性'
|
sticky: '黏性',
|
||||||
|
treeTable: '树形表格',
|
||||||
|
PicturePreview: '表格图片预览'
|
||||||
},
|
},
|
||||||
permission: {
|
permission: {
|
||||||
hasPermission: '请设置操作权限值'
|
hasPermission: '请设置操作权限值'
|
||||||
|
@ -421,7 +423,9 @@ export default {
|
||||||
showOrHiddenStripe: '显示/隐藏斑马纹',
|
showOrHiddenStripe: '显示/隐藏斑马纹',
|
||||||
showOrHiddenBorder: '显示/隐藏边框',
|
showOrHiddenBorder: '显示/隐藏边框',
|
||||||
fixedHeaderOrAuto: '固定头部/自动',
|
fixedHeaderOrAuto: '固定头部/自动',
|
||||||
getSelections: '获取多选数据'
|
getSelections: '获取多选数据',
|
||||||
|
preview: '封面',
|
||||||
|
showOrHiddenSortable: '显示/隐藏排序'
|
||||||
},
|
},
|
||||||
richText: {
|
richText: {
|
||||||
richText: '富文本',
|
richText: '富文本',
|
||||||
|
|
|
@ -190,7 +190,15 @@ export const asyncRouterMap: AppRouteRecordRaw[] = [
|
||||||
component: () => import('@/views/Components/Table/TreeTable.vue'),
|
component: () => import('@/views/Components/Table/TreeTable.vue'),
|
||||||
name: 'TreeTable',
|
name: 'TreeTable',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'TreeTable'
|
title: t('router.treeTable')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'table-image-preview',
|
||||||
|
component: () => import('@/views/Components/Table/TableImagePreview.vue'),
|
||||||
|
name: 'TableImagePreview',
|
||||||
|
meta: {
|
||||||
|
title: t('router.PicturePreview')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -103,3 +103,8 @@ export const isUrl = (path: string): boolean => {
|
||||||
export const isDark = (): boolean => {
|
export const isDark = (): boolean => {
|
||||||
return window.matchMedia('(prefers-color-scheme: dark)').matches
|
return window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 是否是图片链接
|
||||||
|
export const isImgPath = (path: string): boolean => {
|
||||||
|
return /(https?:\/\/|data:image\/).*?\.(png|jpg|jpeg|gif|svg|webp|ico)/gi.test(path)
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
<script setup lang="tsx">
|
||||||
|
import { ContentWrap } from '@/components/ContentWrap'
|
||||||
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
|
import { Table, TableColumn } from '@/components/Table'
|
||||||
|
import { getTableListApi } from '@/api/table'
|
||||||
|
import { TableData } from '@/api/table/types'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { ElTag } from 'element-plus'
|
||||||
|
|
||||||
|
interface Params {
|
||||||
|
pageIndex?: number
|
||||||
|
pageSize?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const columns: TableColumn[] = [
|
||||||
|
{
|
||||||
|
field: 'title',
|
||||||
|
label: t('tableDemo.title')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'image_uri',
|
||||||
|
label: t('tableDemo.preview')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'author',
|
||||||
|
label: t('tableDemo.author')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'display_time',
|
||||||
|
label: t('tableDemo.displayTime')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'importance',
|
||||||
|
label: t('tableDemo.importance'),
|
||||||
|
formatter: (_: Recordable, __: TableColumn, cellValue: number) => {
|
||||||
|
return (
|
||||||
|
<ElTag type={cellValue === 1 ? 'success' : cellValue === 2 ? 'warning' : 'danger'}>
|
||||||
|
{cellValue === 1
|
||||||
|
? t('tableDemo.important')
|
||||||
|
: cellValue === 2
|
||||||
|
? t('tableDemo.good')
|
||||||
|
: t('tableDemo.commonly')}
|
||||||
|
</ElTag>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'pageviews',
|
||||||
|
label: t('tableDemo.pageviews')
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const loading = ref(true)
|
||||||
|
|
||||||
|
let tableDataList = ref<TableData[]>([])
|
||||||
|
|
||||||
|
const getTableList = async (params?: Params) => {
|
||||||
|
const res = await getTableListApi(
|
||||||
|
params || {
|
||||||
|
pageIndex: 1,
|
||||||
|
pageSize: 10
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.catch(() => {})
|
||||||
|
.finally(() => {
|
||||||
|
loading.value = false
|
||||||
|
})
|
||||||
|
if (res) {
|
||||||
|
tableDataList.value = res.data.list
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getTableList()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ContentWrap :title="t('router.PicturePreview')">
|
||||||
|
<Table :columns="columns" :data="tableDataList" :loading="loading" :preview="['image_uri']" />
|
||||||
|
</ContentWrap>
|
||||||
|
</template>
|
|
@ -92,7 +92,7 @@ const actionFn = (data: TableSlotDefault) => {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ContentWrap :title="`TreeTable ${t('tableDemo.example')}`">
|
<ContentWrap :title="`${t('router.treeTable')} ${t('tableDemo.example')}`">
|
||||||
<Table
|
<Table
|
||||||
v-model:pageSize="pageSize"
|
v-model:pageSize="pageSize"
|
||||||
v-model:currentPage="currentPage"
|
v-model:currentPage="currentPage"
|
||||||
|
|
|
@ -21,7 +21,8 @@ const { tableRegister, tableMethods, tableState } = useTable({
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const { loading, dataList, total, currentPage, pageSize } = tableState
|
const { loading, dataList, total, currentPage, pageSize } = tableState
|
||||||
const { setProps, setColumn, getElTableExpose, addColumn, delColumn, refresh } = tableMethods
|
const { setProps, setColumn, getElTableExpose, addColumn, delColumn, refresh, sortableChange } =
|
||||||
|
tableMethods
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
@ -213,6 +214,11 @@ const getSelections = async () => {
|
||||||
const selections = elTableRef?.getSelectionRows()
|
const selections = elTableRef?.getSelectionRows()
|
||||||
console.log(selections)
|
console.log(selections)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const sortable = ref(false)
|
||||||
|
const showOrHiddenSortable = () => {
|
||||||
|
sortable.value = !unref(sortable)
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -244,6 +250,8 @@ const getSelections = async () => {
|
||||||
<ElButton @click="fixedHeaderOrAuto">{{ t('tableDemo.fixedHeaderOrAuto') }}</ElButton>
|
<ElButton @click="fixedHeaderOrAuto">{{ t('tableDemo.fixedHeaderOrAuto') }}</ElButton>
|
||||||
|
|
||||||
<ElButton @click="getSelections">{{ t('tableDemo.getSelections') }}</ElButton>
|
<ElButton @click="getSelections">{{ t('tableDemo.getSelections') }}</ElButton>
|
||||||
|
|
||||||
|
<ElButton @click="showOrHiddenSortable">{{ t('tableDemo.showOrHiddenSortable') }}</ElButton>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
<ContentWrap :title="`UseTable ${t('tableDemo.example')}`">
|
<ContentWrap :title="`UseTable ${t('tableDemo.example')}`">
|
||||||
<Table
|
<Table
|
||||||
|
@ -253,6 +261,7 @@ const getSelections = async () => {
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:data="dataList"
|
:data="dataList"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
|
:sortable="sortable"
|
||||||
:pagination="
|
:pagination="
|
||||||
canShowPagination
|
canShowPagination
|
||||||
? {
|
? {
|
||||||
|
@ -262,6 +271,7 @@ const getSelections = async () => {
|
||||||
"
|
"
|
||||||
@register="tableRegister"
|
@register="tableRegister"
|
||||||
@refresh="refresh"
|
@refresh="refresh"
|
||||||
|
@sortable-change="sortableChange"
|
||||||
/>
|
/>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -10,7 +10,6 @@ import { viteMockServe } from 'vite-plugin-mock'
|
||||||
import PurgeIcons from 'vite-plugin-purge-icons'
|
import PurgeIcons from 'vite-plugin-purge-icons'
|
||||||
import VueI18nPlugin from "@intlify/unplugin-vue-i18n/vite"
|
import VueI18nPlugin from "@intlify/unplugin-vue-i18n/vite"
|
||||||
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
|
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
|
||||||
// @ts-expect-error
|
|
||||||
import DefineOptions from "unplugin-vue-define-options/vite"
|
import DefineOptions from "unplugin-vue-define-options/vite"
|
||||||
import { createStyleImportPlugin, ElementPlusResolve } from 'vite-plugin-style-import'
|
import { createStyleImportPlugin, ElementPlusResolve } from 'vite-plugin-style-import'
|
||||||
import UnoCSS from 'unocss/vite'
|
import UnoCSS from 'unocss/vite'
|
||||||
|
@ -50,10 +49,10 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
}),
|
}),
|
||||||
// EslintPlugin({
|
EslintPlugin({
|
||||||
// cache: false,
|
cache: false,
|
||||||
// include: ['src/**/*.vue', 'src/**/*.ts', 'src/**/*.tsx'] // 检查的文件
|
include: ['src/**/*.vue', 'src/**/*.ts', 'src/**/*.tsx'] // 检查的文件
|
||||||
// }),
|
}),
|
||||||
VueI18nPlugin({
|
VueI18nPlugin({
|
||||||
runtimeOnly: true,
|
runtimeOnly: true,
|
||||||
compositionOnly: true,
|
compositionOnly: true,
|
||||||
|
|
Loading…
Reference in New Issue