tableTags
This commit is contained in:
parent
59cdbef5f2
commit
8536bceeb8
|
|
@ -0,0 +1,97 @@
|
||||||
|
<template>
|
||||||
|
<template v-if="isFilter">
|
||||||
|
<n-tag
|
||||||
|
v-for="(item,index) in getData.data"
|
||||||
|
:key="`tag_${index}`"
|
||||||
|
v-bind="getProps"
|
||||||
|
:color="getFilter(item[getData.rowKey]).color || getProps.color"
|
||||||
|
>
|
||||||
|
{{ getFilter(item[getData.rowKey]).label }}
|
||||||
|
</n-tag>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<n-tag v-for="(item,index) in getData.data" :key="`tag_${index}`" v-bind="getProps">
|
||||||
|
{{ item[getData.rowKey] }}
|
||||||
|
</n-tag>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { defineComponent, computed, unref } from 'vue'
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'TableTags',
|
||||||
|
props: {
|
||||||
|
/* 展示的数据 */
|
||||||
|
data: {
|
||||||
|
type: Object,
|
||||||
|
defalut: [],
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
/* 展示数据取的字段 */
|
||||||
|
rowKey: {
|
||||||
|
type: String,
|
||||||
|
default: 'name'
|
||||||
|
},
|
||||||
|
/* 过滤的数据 */
|
||||||
|
// filters: [
|
||||||
|
// {
|
||||||
|
// key: '',
|
||||||
|
// label: '',
|
||||||
|
// color: {}
|
||||||
|
// }
|
||||||
|
// ],
|
||||||
|
filters: {
|
||||||
|
type: Array,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
/* tag标签的属性 */
|
||||||
|
tags: {
|
||||||
|
type: Object,
|
||||||
|
default: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setup(props, { emit }) {
|
||||||
|
const isFilter = computed(() => {
|
||||||
|
return !!(props.filters)
|
||||||
|
})
|
||||||
|
const { filters } = unref(props)
|
||||||
|
function getFilter(value) {
|
||||||
|
const data = filters.find(item => {
|
||||||
|
return item.key === value
|
||||||
|
})
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 获取传递的数据 */
|
||||||
|
const getData = computed(() => {
|
||||||
|
return {
|
||||||
|
rowKey: unref(props.rowKey),
|
||||||
|
data: { ...unref(props.data) },
|
||||||
|
filters: { ...unref(props.filters) }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
/* 获取tags的属性 */
|
||||||
|
const getProps = computed(() => {
|
||||||
|
return {
|
||||||
|
...unref(props.tags),
|
||||||
|
closable: false,
|
||||||
|
bordered: props.tags?.bordered || false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return {
|
||||||
|
isFilter,
|
||||||
|
getFilter,
|
||||||
|
getData,
|
||||||
|
getProps
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang='scss'>
|
||||||
|
.n-tag{
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -1,134 +0,0 @@
|
||||||
<template>
|
|
||||||
<!-- <n-data-table>
|
|
||||||
n-data-table
|
|
||||||
</n-data-table> -->
|
|
||||||
<div class="table-toolbar">
|
|
||||||
<!--顶部左侧区域-->
|
|
||||||
<div class="flex items-center table-toolbar-left">
|
|
||||||
<slot name="tableTitle" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex items-center table-toolbar-right">
|
|
||||||
<!--顶部右侧区域-->
|
|
||||||
<slot name="toolbar" />
|
|
||||||
<!--刷新-->
|
|
||||||
<!-- <n-tooltip trigger="hover">
|
|
||||||
<template #trigger>
|
|
||||||
<div class="table-toolbar-right-icon" @click="reload">
|
|
||||||
<n-icon size="18">
|
|
||||||
<ReloadOutlined />
|
|
||||||
</n-icon>
|
|
||||||
</div>
|
|
||||||
</template> -->
|
|
||||||
<span @click="reload">刷新</span>
|
|
||||||
<!-- </n-tooltip> -->
|
|
||||||
<!--表格设置单独抽离成组件-->
|
|
||||||
<!-- <ColumnSetting /> -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="s-table">
|
|
||||||
<n-data-table
|
|
||||||
ref="tableElRef"
|
|
||||||
v-bind="getBindValues"
|
|
||||||
:pagination="pagination"
|
|
||||||
>
|
|
||||||
<template v-for="item in Object.keys($slots)" #[item]="data" :key="item">
|
|
||||||
<slot :name="item" v-bind="data" />
|
|
||||||
</template>
|
|
||||||
</n-data-table>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { tableProps } from './tools/props.js'
|
|
||||||
import { useDataSource } from './tools/useDataSource.js'
|
|
||||||
import { usePagination } from './tools/usePagination.js'
|
|
||||||
|
|
||||||
import { unref, ref, computed, toRaw } from 'vue'
|
|
||||||
export default {
|
|
||||||
name: 'DataTable',
|
|
||||||
props: {
|
|
||||||
...tableProps
|
|
||||||
},
|
|
||||||
emits: [
|
|
||||||
'fetch-success',
|
|
||||||
'fetch-error',
|
|
||||||
'update:checked-row-keys',
|
|
||||||
'edit-end',
|
|
||||||
'edit-cancel',
|
|
||||||
'edit-row-end',
|
|
||||||
'edit-change'
|
|
||||||
],
|
|
||||||
setup(props, { emit }) {
|
|
||||||
const loadingRef = ref(unref(props).loading)
|
|
||||||
const getLoading = computed(() => unref(loadingRef))
|
|
||||||
function setLoading(loading) {
|
|
||||||
loadingRef.value = loading
|
|
||||||
}
|
|
||||||
|
|
||||||
/* pagination-start */
|
|
||||||
const pagination = computed(() => toRaw(unref(getPaginationInfo)))
|
|
||||||
const { getPaginationInfo, setPagination } = usePagination(props)
|
|
||||||
/* pagination-end */
|
|
||||||
|
|
||||||
/* tableData-start */
|
|
||||||
const tableData = ref([])
|
|
||||||
const { getDataSourceRef, reload } = useDataSource(props, { getPaginationInfo, setPagination, tableData, setLoading }, emit)
|
|
||||||
|
|
||||||
// 组装表格信息
|
|
||||||
const getBindValues = computed(() => {
|
|
||||||
const tableData = unref(getDataSourceRef)
|
|
||||||
return {
|
|
||||||
...unref(props),
|
|
||||||
loading: unref(getLoading),
|
|
||||||
// columns: toRaw(unref(getPageColumns)),
|
|
||||||
// rowKey: unref(getRowKey),
|
|
||||||
data: tableData,
|
|
||||||
// size: unref(getTableSize),
|
|
||||||
remote: true,
|
|
||||||
'max-height': 'auto'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
/* tableData-end */
|
|
||||||
|
|
||||||
return {
|
|
||||||
pagination,
|
|
||||||
fetch,
|
|
||||||
reload,
|
|
||||||
getBindValues
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
<style scoped lang='scss'>
|
|
||||||
.table-toolbar {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 0 0 16px 0;
|
|
||||||
.table-toolbar-left {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: flex-start;
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
.table-toolbar-right {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
flex: 1;
|
|
||||||
.table-toolbar-icon {
|
|
||||||
margin-left: 12px;
|
|
||||||
font-size: 16px;
|
|
||||||
cursor: pointer;
|
|
||||||
color: var(--text-color);
|
|
||||||
&:hover {
|
|
||||||
color: #1890ff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.table-toolbar-inner-popover-title {
|
|
||||||
padding: 2px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
import { NDataTable } from 'naive-ui'
|
|
||||||
|
|
||||||
export const tableProps = {
|
|
||||||
...NDataTable.props,
|
|
||||||
/* 初始化接口请求 */
|
|
||||||
request: {
|
|
||||||
type: Function,
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
/* 分页信息 */
|
|
||||||
pagination: {
|
|
||||||
type: [Object, Boolean],
|
|
||||||
default: () => {}
|
|
||||||
},
|
|
||||||
/* 分页设置信息 */
|
|
||||||
paginationSetting: {
|
|
||||||
type: Object,
|
|
||||||
default: () => {
|
|
||||||
return {
|
|
||||||
// 当前页的字段名
|
|
||||||
pageField: 'page',
|
|
||||||
// 每页数量字段名
|
|
||||||
sizeField: 'pageSize',
|
|
||||||
// 接口返回的数据字段名
|
|
||||||
listField: 'list',
|
|
||||||
// 接口返回总页数字段名
|
|
||||||
totalField: 'pageCount',
|
|
||||||
// 默认分页数量
|
|
||||||
defaultPageSize: 10,
|
|
||||||
// 可切换每页数量集合
|
|
||||||
pageSizes: [10, 20, 30, 40, 50]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,99 +0,0 @@
|
||||||
import { ref, unref, computed, onMounted } from 'vue'
|
|
||||||
import { isBoolean } from '@/utils/is'
|
|
||||||
|
|
||||||
export function useDataSource(propsRef, { getPaginationInfo, setPagination, setLoading, tableData }, emit) {
|
|
||||||
const dataSourceRef = ref([])
|
|
||||||
|
|
||||||
async function fetch(opt) {
|
|
||||||
try {
|
|
||||||
// setLoading(true)
|
|
||||||
const { request, pagination } = unref(propsRef)
|
|
||||||
/* 无接口请求中断 */
|
|
||||||
if (!request) return
|
|
||||||
/* 获取分页信息 */
|
|
||||||
const paginationSetting = propsRef.paginationSetting
|
|
||||||
const pageField = paginationSetting.pageField
|
|
||||||
const sizeField = paginationSetting.sizeField
|
|
||||||
const totalField = paginationSetting.totalField
|
|
||||||
const listField = paginationSetting.listField
|
|
||||||
|
|
||||||
let pageParams = {}
|
|
||||||
const { page = 1, pageSize = 10 } = unref(getPaginationInfo)
|
|
||||||
if ((isBoolean(pagination) && !pagination) || isBoolean(getPaginationInfo)) {
|
|
||||||
pageParams = {}
|
|
||||||
} else {
|
|
||||||
pageParams[pageField] = (opt && opt[pageField]) || page
|
|
||||||
pageParams[sizeField] = pageSize
|
|
||||||
}
|
|
||||||
|
|
||||||
const params = {
|
|
||||||
...pageParams
|
|
||||||
}
|
|
||||||
const res = await request(params)
|
|
||||||
console.log('res', res)
|
|
||||||
const resultTotal = res[totalField] || 0
|
|
||||||
const currentPage = res[pageField]
|
|
||||||
|
|
||||||
// // 如果数据异常,需获取正确的页码再次执行
|
|
||||||
// if (resultTotal) {
|
|
||||||
// if (page > resultTotal) {
|
|
||||||
// setPagination({
|
|
||||||
// [pageField]: resultTotal
|
|
||||||
// })
|
|
||||||
// fetch(opt)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
const resultInfo = res[listField] ? res[listField] : []
|
|
||||||
dataSourceRef.value = resultInfo
|
|
||||||
setPagination({
|
|
||||||
[pageField]: currentPage,
|
|
||||||
[totalField]: resultTotal
|
|
||||||
})
|
|
||||||
// if (opt && opt[pageField]) {
|
|
||||||
// setPagination({
|
|
||||||
// [pageField]: opt[pageField] || 1
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
emit('fetch-success', {
|
|
||||||
items: unref(resultInfo),
|
|
||||||
resultTotal
|
|
||||||
})
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error)
|
|
||||||
// emit('fetch-error', error)
|
|
||||||
// dataSourceRef.value = []
|
|
||||||
} finally {
|
|
||||||
setLoading(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const getDataSourceRef = computed(() => {
|
|
||||||
const dataSource = unref(dataSourceRef)
|
|
||||||
if (!dataSource || dataSource.length === 0) {
|
|
||||||
return unref(dataSourceRef)
|
|
||||||
}
|
|
||||||
return unref(dataSourceRef)
|
|
||||||
})
|
|
||||||
|
|
||||||
function getDataSource() {
|
|
||||||
console.log(getDataSourceRef.value)
|
|
||||||
return getDataSourceRef.value
|
|
||||||
}
|
|
||||||
|
|
||||||
function setTableData(values) {
|
|
||||||
dataSourceRef.value = values
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
setTimeout(() => {
|
|
||||||
fetch()
|
|
||||||
}, 15)
|
|
||||||
})
|
|
||||||
|
|
||||||
return {
|
|
||||||
fetch,
|
|
||||||
getDataSourceRef,
|
|
||||||
getDataSource,
|
|
||||||
setTableData
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
import { computed, unref, ref } from 'vue'
|
|
||||||
import { isBoolean } from '@/utils/is'
|
|
||||||
|
|
||||||
export function usePagination(refProps) {
|
|
||||||
const configRef = ref({})
|
|
||||||
const show = ref(true)
|
|
||||||
console.log('configRef', configRef)
|
|
||||||
console.log('refProps', refProps)
|
|
||||||
const getPaginationInfo = computed(() => {
|
|
||||||
const { pagination, paginationSetting } = unref(refProps)
|
|
||||||
if (!unref(show) || (isBoolean(pagination) && !pagination)) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
pageSize: paginationSetting.defaultPageSize,
|
|
||||||
pageSizes: paginationSetting.pageSizes,
|
|
||||||
showSizePicker: true,
|
|
||||||
showQuickJumper: true,
|
|
||||||
...(isBoolean(pagination) ? {} : pagination),
|
|
||||||
...unref(configRef),
|
|
||||||
pageCount: unref(configRef)[paginationSetting.totalField]
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
function setPagination(info) {
|
|
||||||
const paginationInfo = unref(getPaginationInfo)
|
|
||||||
configRef.value = {
|
|
||||||
...(!isBoolean(paginationInfo) ? paginationInfo : {}),
|
|
||||||
...info
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return { getPaginationInfo, setPagination }
|
|
||||||
}
|
|
||||||
|
|
@ -29,8 +29,6 @@ const getMenuOptions = computed(() => {
|
||||||
return generateOptions(permissionStore.routes, '')
|
return generateOptions(permissionStore.routes, '')
|
||||||
})
|
})
|
||||||
|
|
||||||
console.log('getMenuOptions', getMenuOptions)
|
|
||||||
|
|
||||||
function resolvePath(basePath, path) {
|
function resolvePath(basePath, path) {
|
||||||
if (isExternal(path)) return path
|
if (isExternal(path)) return path
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,6 @@ export const usePermissionStore = defineStore('permission', {
|
||||||
const res = await getMenu()
|
const res = await getMenu()
|
||||||
if (res.code === 0) {
|
if (res.code === 0) {
|
||||||
const result = dataArrayToRoutes(res.data)
|
const result = dataArrayToRoutes(res.data)
|
||||||
console.log(result)
|
|
||||||
this.accessRoutes = result
|
this.accessRoutes = result
|
||||||
return Promise.resolve(result)
|
return Promise.resolve(result)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,6 @@
|
||||||
<n-card>
|
<n-card>
|
||||||
<data-table
|
<data-table
|
||||||
:columns="data.columns"
|
:columns="data.columns"
|
||||||
:data="data.data"
|
|
||||||
:pagination="data.pagination"
|
|
||||||
:row-key="(row) => row.id"
|
:row-key="(row) => row.id"
|
||||||
:request="loadDataTable"
|
:request="loadDataTable"
|
||||||
size="large"
|
size="large"
|
||||||
|
|
@ -23,8 +21,9 @@
|
||||||
import dataTable from '@/components/DataTable/index.vue'
|
import dataTable from '@/components/DataTable/index.vue'
|
||||||
import TableAction from '@/components/DataTable/tools/Action.vue'
|
import TableAction from '@/components/DataTable/tools/Action.vue'
|
||||||
import TableImage from '@/components/DataTable/tools/Image.vue'
|
import TableImage from '@/components/DataTable/tools/Image.vue'
|
||||||
|
import TableTags from '@/components/DataTable/tools/Tags.vue'
|
||||||
import { getUserList } from '@/api/system/user/index.js'
|
import { getUserList } from '@/api/system/user/index.js'
|
||||||
import { h, onMounted, unref } from 'vue'
|
import { h, unref } from 'vue'
|
||||||
import { reactive } from 'vue'
|
import { reactive } from 'vue'
|
||||||
export default {
|
export default {
|
||||||
name: 'MenuPage',
|
name: 'MenuPage',
|
||||||
|
|
@ -70,7 +69,12 @@ export default {
|
||||||
{
|
{
|
||||||
title: '角色',
|
title: '角色',
|
||||||
key: 'roles',
|
key: 'roles',
|
||||||
align: 'center'
|
align: 'center',
|
||||||
|
render(row) {
|
||||||
|
return h(TableTags, {
|
||||||
|
data: row.roles
|
||||||
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '状态',
|
title: '状态',
|
||||||
|
|
@ -126,32 +130,15 @@ export default {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
data: [],
|
|
||||||
pagination: {
|
|
||||||
pageSize: 10
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
function play(row) {
|
function play(row) {
|
||||||
console.log(row)
|
console.log(row)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @description: 获取用户数据
|
|
||||||
* @return {*}
|
|
||||||
*/
|
|
||||||
async function fetchList() {
|
|
||||||
const params = {
|
|
||||||
page: 1,
|
|
||||||
limit: 10
|
|
||||||
}
|
|
||||||
const res = await getUserList(params)
|
|
||||||
data.data = res.data.list
|
|
||||||
}
|
|
||||||
|
|
||||||
const params = reactive({
|
const params = reactive({
|
||||||
name: 'xiaoMa'
|
name: ''
|
||||||
})
|
})
|
||||||
|
|
||||||
const loadDataTable = async(res) => {
|
const loadDataTable = async(res) => {
|
||||||
|
|
@ -161,9 +148,6 @@ export default {
|
||||||
}
|
}
|
||||||
return await getUserList(_params)
|
return await getUserList(_params)
|
||||||
}
|
}
|
||||||
onMounted(() => {
|
|
||||||
fetchList()
|
|
||||||
})
|
|
||||||
|
|
||||||
return { data, loadDataTable }
|
return { data, loadDataTable }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue