优化一些显示问题

This commit is contained in:
gary.fu
2024-01-25 17:08:34 +08:00
parent 3887d39449
commit 5fa3fdbc78
17 changed files with 147 additions and 36 deletions

View File

@@ -90,6 +90,10 @@ html, body, #app, .index-container {
display: block;
}
.flex-column {
flex-direction: column;
}
.container-center {
display: flex;
justify-content: center;

View File

@@ -21,6 +21,10 @@ const props = defineProps({
type: String,
default: ''
},
autoPageShowTitle: {
type: Boolean,
default: false
},
placeholder: {
type: String,
default: ''
@@ -29,11 +33,11 @@ const props = defineProps({
type: String,
default: ''
},
idKey: {
idProp: {
type: String,
default: 'value'
},
labelKey: {
labelProp: {
type: String,
default: 'label'
},
@@ -47,7 +51,7 @@ const props = defineProps({
},
inputWidth: {
type: String,
default: '220px'
default: '200px'
},
autocompleteConfig: {
type: Object,
@@ -61,6 +65,14 @@ const props = defineProps({
type: Number,
default: 4
},
rowSize: {
type: Number,
default: 6
},
tabStretch: {
type: Boolean,
default: true
},
clearable: {
type: Boolean,
default: true
@@ -122,8 +134,8 @@ const autoPage = ref({
})
const loadingData = ref(false)
const idProp = computed(() => props.autocompleteConfig?.idKey || props.idKey)
const labelProp = computed(() => props.autocompleteConfig?.labelKey || props.labelKey)
const idProp = computed(() => props.autocompleteConfig?.idProp || props.idProp)
const labelProp = computed(() => props.autocompleteConfig?.labelProp || props.labelProp)
const showSelectPage = computed(() => {
return props.selectPageConfig && (!keywords.value || lastAutocompleteLabel.value === keywords.value)
@@ -303,8 +315,8 @@ const parsedSelectPageData = computed(() => {
})
const getSelectPage = (totalCount) => {
const pageSize = 5
const pageCount = Math.ceil((totalCount + pageSize - 1) / pageSize)
const pageSize = props.rowSize
const pageCount = Math.floor((totalCount + pageSize - 1) / pageSize)
return {
pageNumber: 1,
pageSize,
@@ -321,10 +333,22 @@ const selectPagePagination = (tab) => {
const selectPagePaginationChange = (tab, pageNumber) => {
const pager = selectPagePageConfig.value?.[tab.id]
pager.pageNumber = pageNumber
console.info('==================selectPagePaginationChange', tab, pageNumber, pager)
selectPageData.value = { ...selectPageData.value }
}
const autoTitle = computed(() => {
if (!showSelectPage.value && !props.autoPageShowTitle) {
return undefined
}
return props.title || props.placeholder
})
watch(() => props.selectPageConfig, () => {
selectPagePageConfig.value = {}
selectPageData.value = {}
selectPageTab.value = null
})
</script>
<template>
@@ -334,7 +358,7 @@ const selectPagePaginationChange = (tab, pageNumber) => {
popper-class="common-autocomplete"
placement="bottom-start"
:width="autocompleteWidth"
:title="title||placeholder"
:title="autoTitle"
>
<template #reference>
<el-input
@@ -355,6 +379,7 @@ const selectPagePaginationChange = (tab, pageNumber) => {
v-model="selectPageTab"
class="common-select-page"
type="border-card"
:stretch="tabStretch"
@tab-click="onInputKeywords(false)"
>
<el-tab-pane
@@ -363,7 +388,7 @@ const selectPagePaginationChange = (tab, pageNumber) => {
:name="tab.id"
>
<template #label>
<span>{{ tab.label }}</span>
<span>{{ tab.label || (tab.labelKey && $t(tab.labelKey)) || tab.id }}</span>
</template>
<template #default>
<div

View File

@@ -50,14 +50,16 @@ export interface CommonAutocompleteProps {
disabled?: boolean;
// 没有输入时是否可以搜索
emptySearchEnabled?: boolean;
// 是否在自动完成时显示标题
autoPageShowTitle?: boolean;
// 自动完成标题
title?: string;
// 占位符
placeholder?: string;
// id字段名
idKey?: string;
idProp?: string;
// label字段名
labelKey?: string;
labelProp?: string;
// 防抖延时
debounceTime?: number;
// 自动完成宽度
@@ -68,6 +70,8 @@ export interface CommonAutocompleteProps {
selectPageConfig?: CommonSelectPageOption;
// 可选项列默认显示几列
colSize?: number;
// 可选项列默认显示几行
rowSize?: number;
// 加载提示loading
loadingText?: string;
// 最低高度

View File

@@ -10,7 +10,8 @@ const route = useRoute()
const breadcrumbs = computed(() => {
const exists = []
return route.matched.map(item => {
return route.matched.map((item, index) => {
item = index === route.matched.length - 1 ? route : item
const menuInfo = useMenuInfo(item)
let icon = ''
if (menuInfo && menuInfo.icon) {
@@ -28,7 +29,7 @@ const breadcrumbs = computed(() => {
if (notExist) {
exists.push(item.menuName)
}
return notExist
return notExist && !item.menuName.endsWith('Base')
})
})
</script>

View File

@@ -20,16 +20,24 @@ const props = defineProps({
model: {
type: Object,
required: true
},
labelWidth: {
type: String,
default: null
}
})
const inputType = computed(() => useInputType(props.option))
const modelAttrs = computed(() => {
const attrs = { ...props.option.attrs }
if (attrs.clearable === undefined && ['el-input', 'el-select', 'common-autocomplete', 'el-autocomplete', 'el-cascader', 'el-tree-select'].includes(inputType.value)) {
const option = props.option
const attrs = { ...option.attrs }
if (attrs.clearable === undefined && ['el-input', 'el-select', 'el-select-v2', 'common-autocomplete', 'el-autocomplete', 'el-cascader', 'el-tree-select'].includes(inputType.value)) {
attrs.clearable = true
}
if (inputType.value === 'common-autocomplete' && option.getAutocompleteLabel) {
attrs.defaultLabel = option.getAutocompleteLabel(props.model, option)
}
return attrs
})
@@ -41,6 +49,10 @@ const label = computed(() => {
return option.label
})
const showLabel = computed(() => {
return props.option.showLabel !== false && props.labelWidth !== '0'
})
const formModel = computed(() => props.option.model || props.model)
const modelValue = computed({
@@ -105,7 +117,7 @@ const initFormModel = () => {
const option = props.option
if (option.prop) {
const defaultVal = get(formModel.value, option.prop)
set(formModel.value, option.prop, defaultVal || option.value || undefined)
set(formModel.value, option.prop, defaultVal ?? option.value ?? undefined)
}
}
}
@@ -114,15 +126,36 @@ initFormModel()
watch(() => props.option, initFormModel, { deep: true })
const hasModelText = computed(() => {
return !!(modelAttrs.value.modelText || modelAttrs.value.modelTextFunc)
})
const emit = defineEmits(['change'])
const controlChange = (...args) => {
const option = props.option
if (option.change) {
option.change(...args)
}
emit('change', ...args)
}
const formItemEnabled = computed(() => props.option.enabled !== false)
</script>
<template>
<el-form-item
v-if="formItemEnabled"
ref="formItemRef"
:rules="rules"
:prop="option.prop"
:label-width="labelWidth"
>
<template
v-if="showLabel"
#label
>
<template #label>
<span>{{ label }}</span>
<el-tooltip
v-if="option.tooltip||option.tooltipFunc"
@@ -151,8 +184,14 @@ watch(() => props.option, initFormModel, { deep: true })
:placeholder="option.placeholder"
:disabled="option.disabled"
:readonly="option.readonly"
@change="option.change"
@change="controlChange"
>
<template
v-if="hasModelText"
#default
>
{{ modelAttrs.modelText || modelAttrs.modelTextFunc(modelValue) }}
</template>
<template v-if="children&&children.length">
<control-child
v-for="(childItem, index) in children"

View File

@@ -11,11 +11,13 @@ const props = defineProps({
*/
options: {
type: Array,
required: true
default () {
return []
}
},
labelWidth: {
type: String,
default: '100px'
default: '110px'
},
model: {
type: Object,
@@ -94,6 +96,7 @@ defineExpose({
:model="formModel"
/>
<common-form-control
v-if="option.enabled!==false"
:model="formModel"
:option="option"
/>

View File

@@ -35,7 +35,7 @@ const menuCls = computed(() => {
})
const dropdownClick = (menuItem, $event) => {
if (menuItem.click) {
menuItem.click(router, $event)
menuItem.click($event)
} else {
const route = menuItem.route || menuItem.index
if (route) {
@@ -85,7 +85,7 @@ const dropdownClick = (menuItem, $event) => {
v-else-if="isDropdown"
:key="menuItem.index||index"
:class="menuCls"
@click="menuItem.click&&menuItem.click(router, $event)"
@click="menuItem.click&&menuItem.click($event)"
>
<el-dropdown class="common-dropdown">
<span class="el-dropdown-link">
@@ -120,7 +120,7 @@ const dropdownClick = (menuItem, $event) => {
:route="menuItem.route"
v-bind="menuItem.attrs"
:index="menuItem.index"
@click="menuItem.click&&menuItem.click(router, $event)"
@click="menuItem.click&&menuItem.click(menuItem, $event)"
>
<common-icon
:size="menuItem.iconSize"

View File

@@ -1,4 +1,8 @@
<script setup>
import { formatDate } from '@/components/utils'
import { computed } from 'vue'
import { get } from 'lodash'
/**
* 配置信息
* @type {CommonTableColumnProps}
@@ -20,6 +24,21 @@ const props = defineProps({
}
})
const formatter = computed(() => {
const column = props.column
if (!column.formatter && column.dateFormat) { // 没有formatter但是有dateFormat
return row => {
const data = getPropertyData(row)
return formatDate(data, column.dateFormat)
}
}
return column.formatter
})
const getPropertyData = (row) => {
return get(row, props.column.property)
}
</script>
<template>
@@ -29,7 +48,7 @@ const props = defineProps({
:prop="column.prop||column.property"
:width="column.width"
v-bind="column.attrs"
:formatter="column.formatter"
:formatter="formatter"
>
<template
v-if="column.slot||column.click"
@@ -41,7 +60,7 @@ const props = defineProps({
v-bind="column.linkAttrs"
@click="column.click(scope.row, scope)"
>
{{ column.formatter?column.formatter(scope.row, scope):scope.row[column.property] }}
{{ formatter?formatter(scope.row, scope):getPropertyData(scope.row) }}
</el-link>
<slot
v-bind="scope"

View File

@@ -102,7 +102,7 @@ const calcColumns = computed(() => {
}
_columns = [..._columns, buttonColumn]
}
return _columns
return _columns.filter(column => column.enabled !== false)
})
const emit = defineEmits(['pageSizeChange', 'currentPageChange', 'update:page'])
@@ -127,7 +127,7 @@ defineExpose({
<template>
<el-container
v-loading="loading"
class="no_flex"
class="flex-column"
:element-loading-text="loadingText"
>
<el-table
@@ -160,7 +160,7 @@ defineExpose({
</common-table-column>
</el-table>
<el-pagination
v-if="page&&page.pageCount&&page.pageCount>1"
v-if="page&&page.pageCount"
class="common-pagination"
v-bind="pageAttrs"
:total="page.totalCount"

View File

@@ -2,10 +2,12 @@ import CommonIcon from '@/components/common-icon/index.vue'
import CommonIconSelect from '@/components/common-icon-select/index.vue'
import CommonForm from '@/components/common-form/index.vue'
import CommonFormControl from '@/components/common-form-control/index.vue'
import CommonFormLabel from '@/components/common-form-control/common-form-label.vue'
import CommonMenu from '@/components/common-menu/index.vue'
import CommonMenuItem from '@/components/common-menu-item/index.vue'
import CommonTabsView from '@/components/common-tabs-view/index.vue'
import CommonTable from '@/components/common-table/index.vue'
import CommonTableForm from '@/components/common-table-form/index.vue'
import CommonBreadcrumb from '@/components/common-breadcrumb/index.vue'
import CommonWindow from '@/components/common-window/index.vue'
import CommonAutocomplete from '@/components/common-autocomplete/index.vue'
@@ -22,10 +24,12 @@ export default {
Vue.component('CommonIconSelect', CommonIconSelect)
Vue.component('CommonForm', CommonForm)
Vue.component('CommonFormControl', CommonFormControl)
Vue.component('CommonFormLabel', CommonFormLabel)
Vue.component('CommonMenu', CommonMenu)
Vue.component('CommonMenuItem', CommonMenuItem)
Vue.component('CommonTabsView', CommonTabsView)
Vue.component('CommonTable', CommonTable)
Vue.component('CommonTableForm', CommonTableForm)
Vue.component('CommonBreadcrumb', CommonBreadcrumb)
Vue.component('CommonWindow', CommonWindow)
Vue.component('CommonAutocomplete', CommonAutocomplete)

View File

@@ -1,5 +1,6 @@
import { ref } from 'vue'
import { $i18nBundle } from '@/messages'
import dayjs from 'dayjs'
const calcWithIf = menuItem => {
['icon', 'labelKey', 'label', 'html'].forEach(key => {
@@ -73,3 +74,15 @@ export const useParentRoute = function (route) {
}
return route
}
export const formatDate = (date, format) => {
if (date) {
return dayjs(date).format(format || 'YYYY-MM-DD HH:mm:ss')
}
}
export const formatDay = (date, format) => {
if (date) {
return dayjs(date).format(format || 'YYYY-MM-DD')
}
}

View File

@@ -7,7 +7,7 @@ const globalConfigStore = useGlobalConfigStore()
const menuConfigStore = useMenuConfigStore()
const allMenus = computed(() => {
const topMenus = menuConfigStore.loadBaseTopMenus()
const topMenus = menuConfigStore.loadBaseTopMenus().value
const businessMenus = menuConfigStore.calcBusinessMenus()
if (globalConfigStore.layoutMode === GlobalLayoutMode.TOP) {
return [...businessMenus, ...topMenus.slice(1)]

View File

@@ -27,8 +27,8 @@ export const loadAutoCities = (data, config) => {
*/
export const useCityAutocompleteConfig = () => {
return {
idKey: 'code',
labelKey: $i18nMsg('nameCn', 'nameEn'),
idProp: 'code',
labelProp: $i18nMsg('nameCn', 'nameEn'),
columns: [{
label: $i18nMsg('代码', 'Code'),
property: 'code'

View File

@@ -10,7 +10,7 @@ export const useMenuConfigStore = defineStore('menuConfig', () => {
return {
businessMenus,
loadBaseTopMenus () {
return useBaseTopMenus()
return ref(useBaseTopMenus())
},
async loadBusinessMenus () {
businessMenus.value = await loadAndParseMenus()

View File

@@ -13,7 +13,6 @@ const tabsViewStore = useTabsViewStore()
const showLeftMenu = computed(() => {
return globalConfigStore.layoutMode === GlobalLayoutMode.LEFT
})
menuConfigStore.loadBaseTopMenus()
menuConfigStore.loadBusinessMenus()
</script>

View File

@@ -82,7 +82,7 @@ const doSearch = form => {
<template>
<el-container
class="no_flex"
class="flex-column"
>
<common-form
inline

View File

@@ -130,7 +130,7 @@ const submitForm = () => {
<template>
<el-container
class="no_flex"
class="flex-column"
>
<common-form
inline