perf: 优化数量显示,异步获取 hover 的内容

This commit is contained in:
ibuler
2024-01-22 16:48:16 +08:00
committed by Bryan
parent ff63d2ca39
commit ea575e0515
5 changed files with 69 additions and 29 deletions

View File

@@ -126,13 +126,17 @@ export default {
return _.uniq(value)
},
set(val) {
this.$emit('input', val)
this.emit(val)
}
}
},
methods: {
emit(val) {
const value = _.uniq(val)
this.$emit('input', value)
},
onInputChange(val) {
this.$emit('input', val)
this.emit(val)
},
handleFocus() {
this.$refs.select2.selectRef.blur()
@@ -155,7 +159,7 @@ export default {
return { value: item.id, label: item.label }
})
this.select2.options = options
this.$emit('input', options.map(item => item.value))
this.emit(options.map(item => item.value))
this.showTransfer = false
}
}

View File

@@ -3,17 +3,19 @@
<template>
<el-popover
:disabled="!showItems"
:open-delay="500"
:title="title"
placement="top-start"
trigger="hover"
width="400"
@show="getAsyncItems"
>
<div class="detail-content">
<div v-for="item of items" :key="getKey(item)" class="detail-item">
<span class="detail-item-name">{{ item }}</span>
</div>
</div>
<span slot="reference">{{ items && items.length }}</span>
<span slot="reference">{{ amount }}</span>
</el-popover>
</template>
</DetailFormatter>
@@ -37,41 +39,73 @@ export default {
showItems: true,
getItem(item) {
return item.name
}
},
async: false,
ajax: {},
title: ''
}
}
}
},
data() {
const formatterArgs = Object.assign(this.formatterArgsDefault, this.col.formatterArgs || {})
return {
formatterArgs: Object.assign(this.formatterArgsDefault, this.col.formatterArgs || {})
formatterArgs: formatterArgs,
data: formatterArgs.async ? [] : (this.cellValue || []),
amount: '',
asyncGetDone: false
}
},
computed: {
title() {
return this.formatterArgs.title || ''
return this.formatterArgs.title || this.col.label.replace('amount', '').replace('数量', '')
},
items() {
if (this.formatterArgs.async && !this.asyncGetDone) {
return [this.$t('common.tree.Loading') + '...']
}
const getItem = this.formatterArgs.getItem || (item => item.name)
let data = this.cellValue?.map(item => getItem(item)) || []
let data = this.data.map(item => getItem(item)) || []
data = data.filter(Boolean)
return data
},
showItems() {
return this.formatterArgs.showItems !== false && this.cellValue?.length > 0
return this.amount !== 0 && this.amount !== ''
}
},
async mounted() {
this.amount = this.formatterArgs.async ? this.cellValue : (this.cellValue || []).length
},
methods: {
getKey(item) {
const id = Math.random().toString(36).substring(2)
const id = Math.random().toString(36).substring(16)
return id + item
},
getDefaultUrl() {
const url = new URL(this.url, location.origin)
url.pathname += this.row.id + '/'
return url.pathname
},
async getAsyncItems() {
if (!this.formatterArgs.async) {
return
}
if (this.asyncGetDone) {
return
}
const url = this.formatterArgs.ajax.url || this.getDefaultUrl()
const params = this.formatterArgs.ajax.params || {}
const transform = this.formatterArgs.ajax.transform || (resp => resp[this.col.prop.replace('_amount', '')])
const response = await this.$axios.get(url, { params: params })
this.data = transform(response)
this.asyncGetDone = true
}
}
}
</script>
<style lang="scss" scoped>
.detail-content {
padding: 20px 10px;
padding: 5px 10px;
max-height: 60vh;
overflow-y: auto;
}
@@ -86,6 +120,6 @@ export default {
}
.detail-item:first-child {
border-top: 1px solid #EBEEF5;
//border-top: 1px solid #EBEEF5;
}
</style>

View File

@@ -4,7 +4,7 @@
<script>
import { GenericListPage } from '@/layout/components'
import { DetailFormatter } from '@/components/Table/TableFormatters'
import AmountFormatter from '@/components/Table/TableFormatters/AmountFormatter.vue'
export default {
components: {
@@ -15,34 +15,32 @@ export default {
tableConfig: {
url: '/api/v1/assets/domains/',
columnsExclude: ['gateway'],
columnsExtra: ['gateway_count'],
columns: ['name', 'assets_amount', 'gateway_count', 'comment', 'actions'],
columnsExtra: ['gateways'],
columns: ['name', 'assets_amount', 'gateways', 'comment', 'actions'],
columnsShow: {
min: ['name', 'actions'],
default: ['name', 'assets_amount', 'gateway_count', 'comment', 'actions']
default: ['name', 'assets_amount', 'gateways', 'comment', 'actions']
},
columnsMeta: {
assets_amount: {
label: this.$t('assets.Assets'),
width: '160px',
formatter: DetailFormatter,
formatter: AmountFormatter,
formatterArgs: {
async: true,
permissions: 'assets.view_asset',
routeQuery: {
activeTab: 'AssetList'
}
}
},
gateway_count: {
gateways: {
label: this.$t('assets.Gateway'),
formatter: DetailFormatter,
formatter: AmountFormatter,
formatterArgs: {
permissions: 'assets.view_gateway',
routeQuery: {
activeTab: 'GatewayList'
},
getTitle: function({ row }) {
return row.gateways.length
}
}
}

View File

@@ -21,7 +21,6 @@ import PermBulkUpdateDialog from './components/PermBulkUpdateDialog'
import AmountFormatter from '@/components/Table/TableFormatters/AmountFormatter'
import { mapGetters } from 'vuex'
import { AccountLabelMapper, AssetPermissionListPageSearchConfigOptions } from '../const'
import { DetailFormatter } from '@/components/Table/TableFormatters'
export default {
components: {
@@ -90,8 +89,9 @@ export default {
users_amount: {
label: this.$t('perms.User'),
width: '60px',
formatter: DetailFormatter,
formatter: AmountFormatter,
formatterArgs: {
async: true,
routeQuery: {
activeTab: 'AssetPermissionUser'
}
@@ -100,8 +100,9 @@ export default {
user_groups_amount: {
label: this.$t('perms.UserGroups'),
width: '100px',
formatter: DetailFormatter,
formatter: AmountFormatter,
formatterArgs: {
async: true,
routeQuery: {
activeTab: 'AssetPermissionUser'
}
@@ -110,8 +111,9 @@ export default {
assets_amount: {
label: this.$t('perms.Asset'),
width: '60px',
formatter: DetailFormatter,
formatter: AmountFormatter,
formatterArgs: {
async: true,
routeQuery: {
activeTab: 'AssetPermissionAsset'
}
@@ -120,8 +122,9 @@ export default {
nodes_amount: {
label: this.$t('perms.Node'),
width: '60px',
formatter: DetailFormatter,
formatter: AmountFormatter,
formatterArgs: {
async: true,
routeQuery: {
activeTab: 'AssetPermissionAsset'
}

View File

@@ -4,7 +4,7 @@
<script>
import { GenericListPage } from '@/layout/components'
import { DetailFormatter } from '@/components/Table/TableFormatters'
import AmountFormatter from '@/components/Table/TableFormatters/AmountFormatter.vue'
export default {
components: {
@@ -23,8 +23,9 @@ export default {
users_amount: {
label: this.$t('users.Users'),
width: '120px',
formatter: DetailFormatter,
formatter: AmountFormatter,
formatterArgs: {
async: true,
getRoute({ row }) {
return {
name: 'UserGroupDetail',