mirror of
https://github.com/fugary/simple-element-plus-template.git
synced 2025-11-12 14:27:49 +00:00
1. 新增描述列表包装控件
2. 优化tooltip显示 3. 动态属性slots支持
This commit is contained in:
@@ -78,7 +78,7 @@ const allMenus = [
|
|||||||
{
|
{
|
||||||
id: 25,
|
id: 25,
|
||||||
parentId: 2,
|
parentId: 2,
|
||||||
iconCls: 'PieChartSharp',
|
iconCls: 'PieChart',
|
||||||
nameCn: '图表示例',
|
nameCn: '图表示例',
|
||||||
nameEn: 'Charts',
|
nameEn: 'Charts',
|
||||||
menuUrl: '/charts'
|
menuUrl: '/charts'
|
||||||
|
|||||||
83
src/components/common-descriptions/index.vue
Normal file
83
src/components/common-descriptions/index.vue
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
<script setup>
|
||||||
|
import { calcSlotsResult, toLabelByKey } from '@/components/utils'
|
||||||
|
import { isFunction } from 'lodash-es'
|
||||||
|
import { isVNode, computed } from 'vue'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
items: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
width: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
minWidth: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const calcItems = computed(() => {
|
||||||
|
return props.items.filter(item => item.enabled !== false).map(item => {
|
||||||
|
const label = item.labelKey ? toLabelByKey(item.labelKey) : item.label
|
||||||
|
const value = isFunction(item.formatter) ? item.formatter(item) : item.value
|
||||||
|
const valueResult = { value, vnode: isVNode(value) }
|
||||||
|
const slotsResult = calcSlotsResult(item)
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
label,
|
||||||
|
width: item.width || props.width,
|
||||||
|
minWidth: item.minWidth || props.minWidth,
|
||||||
|
valueResult,
|
||||||
|
slotsResult
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<el-descriptions
|
||||||
|
v-bind="$attrs"
|
||||||
|
>
|
||||||
|
<el-descriptions-item
|
||||||
|
v-for="(calcItem, index) in calcItems"
|
||||||
|
:key="index"
|
||||||
|
:label="calcItem.label"
|
||||||
|
:min-width="calcItem.minWidth"
|
||||||
|
:width="calcItem.width"
|
||||||
|
:span="calcItem.span"
|
||||||
|
:align="calcItem.align"
|
||||||
|
v-bind="calcItem.attrs"
|
||||||
|
>
|
||||||
|
<template
|
||||||
|
v-for="(slot, slotKey) in (calcItem.slots||{})"
|
||||||
|
:key="slotKey"
|
||||||
|
#[slotKey]
|
||||||
|
>
|
||||||
|
<component
|
||||||
|
:is="calcItem.slotsResult[slotKey].result"
|
||||||
|
v-if="calcItem.slotsResult[slotKey]?.vnode"
|
||||||
|
/>
|
||||||
|
<template v-else>
|
||||||
|
{{ calcItem.slotsResult[slotKey].result }}
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
<template v-if="calcItem.valueResult.value">
|
||||||
|
<span
|
||||||
|
v-if="calcItem.valueResult.value&&!calcItem.valueResult.vnode"
|
||||||
|
v-html="calcItem.valueResult.value"
|
||||||
|
/>
|
||||||
|
<component
|
||||||
|
:is="calcItem.valueResult.value"
|
||||||
|
v-if="calcItem.valueResult.vnode"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
30
src/components/common-descriptions/public.d.ts
vendored
Normal file
30
src/components/common-descriptions/public.d.ts
vendored
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import { VNode } from 'vue'
|
||||||
|
import { descriptionItemProps } from 'element-plus/es/components/descriptions/src/description-item'
|
||||||
|
|
||||||
|
export interface CommonDescriptionItem {
|
||||||
|
label?: string;
|
||||||
|
labelKey?: string;
|
||||||
|
value?: string;
|
||||||
|
span?: number;
|
||||||
|
width?: string;
|
||||||
|
minWidth?: string;
|
||||||
|
className?: string;
|
||||||
|
labelClassName?: string;
|
||||||
|
align?: 'left' | 'right' | 'center';
|
||||||
|
labelAlign?: string;
|
||||||
|
slots?: any;
|
||||||
|
formatter?: (item: CommonDescriptionItem) => string | VNode;
|
||||||
|
attrs?: descriptionItemProps;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CommonDescriptionProps {
|
||||||
|
border?: boolean;
|
||||||
|
column?: number;
|
||||||
|
direction?: 'horizontal' | 'vertical';
|
||||||
|
size?: 'default' | 'small' | 'large';
|
||||||
|
title?: string;
|
||||||
|
extra?: string;
|
||||||
|
items?: Array<CommonDescriptionItem>;
|
||||||
|
width?: string;
|
||||||
|
minWidth?: string;
|
||||||
|
}
|
||||||
@@ -48,11 +48,12 @@ const tooltipFunc = ($event) => {
|
|||||||
{{ label }}
|
{{ label }}
|
||||||
<el-tooltip
|
<el-tooltip
|
||||||
v-if="option.tooltip||option.tooltipFunc"
|
v-if="option.tooltip||option.tooltipFunc"
|
||||||
class="box-item"
|
class="box-item common-el-tooltip"
|
||||||
effect="dark"
|
effect="dark"
|
||||||
:disabled="!option.tooltip"
|
:disabled="!option.tooltip"
|
||||||
:content="option.tooltip"
|
:content="option.tooltip"
|
||||||
placement="top-start"
|
placement="top-start"
|
||||||
|
raw-content
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
<el-link
|
<el-link
|
||||||
|
|||||||
@@ -222,6 +222,24 @@ const formatResult = computed(() => {
|
|||||||
return null
|
return null
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const slotsResult = computed(() => {
|
||||||
|
const results = {}
|
||||||
|
if (calcOption.value?.slots) {
|
||||||
|
const slots = calcOption.value.slots
|
||||||
|
for (const slotKey in slots) {
|
||||||
|
const slot = slots[slotKey]
|
||||||
|
if (isFunction(slot)) {
|
||||||
|
const slotResult = slot(modelValue.value, calcOption.value)
|
||||||
|
results[slotKey] = {
|
||||||
|
result: slotResult,
|
||||||
|
vnode: isVNode(slotResult)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results
|
||||||
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -252,11 +270,12 @@ const formatResult = computed(() => {
|
|||||||
<slot name="afterLabel" />
|
<slot name="afterLabel" />
|
||||||
<el-tooltip
|
<el-tooltip
|
||||||
v-if="calcOption.tooltip||calcOption.tooltipFunc"
|
v-if="calcOption.tooltip||calcOption.tooltipFunc"
|
||||||
class="box-item"
|
class="box-item common-el-tooltip"
|
||||||
effect="dark"
|
effect="dark"
|
||||||
:disabled="!calcOption.tooltip"
|
:disabled="!calcOption.tooltip"
|
||||||
:content="calcOption.tooltip"
|
:content="calcOption.tooltip"
|
||||||
placement="top-start"
|
placement="top-start"
|
||||||
|
raw-content
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
<el-link
|
<el-link
|
||||||
@@ -280,6 +299,19 @@ const formatResult = computed(() => {
|
|||||||
:readonly="calcOption.readonly"
|
:readonly="calcOption.readonly"
|
||||||
@change="controlChange"
|
@change="controlChange"
|
||||||
>
|
>
|
||||||
|
<template
|
||||||
|
v-for="(slot, slotKey) in (calcOption.slots||{})"
|
||||||
|
:key="slotKey"
|
||||||
|
#[slotKey]
|
||||||
|
>
|
||||||
|
<component
|
||||||
|
:is="slotsResult[slotKey].result"
|
||||||
|
v-if="slotsResult[slotKey]?.vnode"
|
||||||
|
/>
|
||||||
|
<template v-else>
|
||||||
|
{{ slotsResult[slotKey].result }}
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
<template
|
<template
|
||||||
v-if="hasModelText&&formatResult"
|
v-if="hasModelText&&formatResult"
|
||||||
#default
|
#default
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import CommonBreadcrumb from '@/components/common-breadcrumb/index.vue'
|
|||||||
import CommonWindow from '@/components/common-window/index.vue'
|
import CommonWindow from '@/components/common-window/index.vue'
|
||||||
import CommonAutocomplete from '@/components/common-autocomplete/index.vue'
|
import CommonAutocomplete from '@/components/common-autocomplete/index.vue'
|
||||||
import CommonSort from '@/components/common-sort/index.vue'
|
import CommonSort from '@/components/common-sort/index.vue'
|
||||||
|
import CommonDescriptions from '@/components/common-descriptions/index.vue'
|
||||||
import CommonDirectives from '@/components/directives'
|
import CommonDirectives from '@/components/directives'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -42,6 +43,7 @@ export default {
|
|||||||
Vue.component('CommonWindow', CommonWindow)
|
Vue.component('CommonWindow', CommonWindow)
|
||||||
Vue.component('CommonAutocomplete', CommonAutocomplete)
|
Vue.component('CommonAutocomplete', CommonAutocomplete)
|
||||||
Vue.component('CommonSort', CommonSort)
|
Vue.component('CommonSort', CommonSort)
|
||||||
|
Vue.component('CommonDescriptions', CommonDescriptions)
|
||||||
Vue.use(CommonDirectives)
|
Vue.use(CommonDirectives)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { ref, unref } from 'vue'
|
import { isVNode, ref, unref } from 'vue'
|
||||||
import { $i18nBundle, $i18nKey } from '@/messages'
|
import { $i18nBundle, $i18nKey } from '@/messages'
|
||||||
import { isArray, isFunction, isObject } from 'lodash-es'
|
import { isArray, isFunction, isObject } from 'lodash-es'
|
||||||
|
|
||||||
@@ -64,8 +64,8 @@ export const useMenuName = item => {
|
|||||||
return toLabelByKey(menuInfo.labelKey)
|
return toLabelByKey(menuInfo.labelKey)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (item.meta && item.meta.labelKey) {
|
if (item.meta && (item.meta.label || item.meta.labelKey)) {
|
||||||
return toLabelByKey(item.meta.labelKey)
|
return item.meta.label || toLabelByKey(item.meta.labelKey)
|
||||||
}
|
}
|
||||||
return item.name || 'No Name'
|
return item.name || 'No Name'
|
||||||
}
|
}
|
||||||
@@ -154,6 +154,24 @@ export const proxyMethod = (targets = [], methodName) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const calcSlotsResult = (config, data) => {
|
||||||
|
const results = {}
|
||||||
|
if (config?.slots) {
|
||||||
|
const slots = config.slots
|
||||||
|
for (const slotKey in slots) {
|
||||||
|
const slot = slots[slotKey]
|
||||||
|
if (isFunction(slot)) {
|
||||||
|
const slotResult = slot(data, config)
|
||||||
|
results[slotKey] = {
|
||||||
|
result: slotResult,
|
||||||
|
vnode: isVNode(slotResult)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 定义表单选项,带有jsdoc注解,方便代码提示
|
* 定义表单选项,带有jsdoc注解,方便代码提示
|
||||||
* @param {CommonFormOption|CommonFormOption[]} formOptions 表单选项
|
* @param {CommonFormOption|CommonFormOption[]} formOptions 表单选项
|
||||||
|
|||||||
Reference in New Issue
Block a user