6 changed files with 242 additions and 19 deletions
@ -0,0 +1,117 @@ |
|||
<template> |
|||
<div class="h-full w-panel"> |
|||
<template v-if="!expansion"> |
|||
<q-card flat :bordered="bordered" class="h-full"> |
|||
<q-item dense style="padding: 0px"> |
|||
<q-item-section> |
|||
<q-item-label header :style="headerStyleComputed"> |
|||
<q-icon v-if="props.icon" :name="props.icon" size="sm" v-bind="props.iconAttrs" /> |
|||
<span style="margin-left: 5px">{{ label }}</span> |
|||
</q-item-label> |
|||
</q-item-section> |
|||
</q-item> |
|||
<q-separator v-if="!titleMode" /> |
|||
<q-card-section v-if="!titleMode" :style="contentPadding"> |
|||
<slot></slot> |
|||
</q-card-section> |
|||
</q-card> |
|||
</template> |
|||
<template v-else> |
|||
<q-list :bordered="bordered" class="rounded-borders"> |
|||
<q-expansion-item default-opened expand-separator :icon="icon" :label="label" :header-style="headerStyleComputed"> |
|||
<template #header> |
|||
<div class="q-item__section column q-item__section--side justify-center q-item__section--avatar"> |
|||
<q-icon v-if="props.icon" :name="props.icon" size="sm" v-bind="props.iconAttrs" /> |
|||
</div> |
|||
<div class="q-item__section column q-item__section--main justify-center"> |
|||
<span style="margin-left: 5px">{{ label }}</span> |
|||
</div> |
|||
</template> |
|||
<q-separator v-if="!titleMode" /> |
|||
<div v-if="!titleMode" class="h-full" :style="contentPadding"> |
|||
<slot></slot> |
|||
</div> |
|||
</q-expansion-item> |
|||
</q-list> |
|||
</template> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import { computed } from 'vue'; |
|||
import { Tools } from '@/platform'; |
|||
|
|||
// 颜色透明度 |
|||
const colorOpacity = 0.048; |
|||
const colors = { |
|||
// 红色 |
|||
red: 'rgba(255, 0, 0, ' + colorOpacity + ')', |
|||
// 橙色 |
|||
orange: 'rgba(255, 149, 0, ' + colorOpacity + ')', |
|||
// 黄色 |
|||
yellow: 'rgba(255, 255, 0, ' + colorOpacity + ')', |
|||
// 绿色 |
|||
green: 'rgba(4, 255, 0, ' + colorOpacity + ')', |
|||
// 青色 |
|||
teal: 'rgba(0, 255, 255, ' + colorOpacity + ')', |
|||
// 蓝色 |
|||
blue: 'rgba(0, 38, 255, ' + colorOpacity + ')', |
|||
// 紫色 |
|||
purple: 'rgba(255, 0, 247, ' + colorOpacity + ')', |
|||
// 灰色 |
|||
grey: 'rgba(0, 0, 0, ' + colorOpacity + ')', |
|||
}; |
|||
|
|||
const props = defineProps({ |
|||
// 标签名 |
|||
label: { type: String, default: '' }, |
|||
// 背景色 |
|||
color: { type: String, default: undefined }, |
|||
// 图标 |
|||
icon: { type: String, default: undefined }, |
|||
// 图标其余属性 |
|||
iconAttrs: { type: Object, default: undefined }, |
|||
// title模式,开启后无内容块 |
|||
titleMode: { type: Boolean, default: false }, |
|||
// 是否显示边框线 |
|||
bordered: { type: Boolean, default: true }, |
|||
// 是否可折叠 |
|||
expansion: { type: Boolean, default: false }, |
|||
// 内容块边距 |
|||
contentPadding: { type: String, default: 'padding: 8px' }, |
|||
}); |
|||
|
|||
const headerStyleComputed = computed(() => { |
|||
const style = { |
|||
// 垂直居中 |
|||
display: 'flex', |
|||
alignItems: 'center', |
|||
// 文字颜色 |
|||
color: '#000', |
|||
}; |
|||
if (!props.expansion) { |
|||
style['padding'] = '5px'; |
|||
} |
|||
if (props.color) { |
|||
// 背景颜色 |
|||
if (Tools.hasOwnProperty(colors, props.color)) { |
|||
style['background-color'] = colors[props.color]; |
|||
} else { |
|||
style['background-color'] = props.color; |
|||
} |
|||
} |
|||
return style; |
|||
}); |
|||
</script> |
|||
|
|||
<style lang="css"> |
|||
.w-panel .q-expansion-item__container .q-item:first-of-type { |
|||
min-height: 34px; |
|||
height: 34px; |
|||
padding: 5px; |
|||
} |
|||
.w-panel .q-expansion-item .q-item__section--side { |
|||
min-width: auto; |
|||
padding-right: 5px; |
|||
} |
|||
</style> |
@ -0,0 +1,94 @@ |
|||
<template> |
|||
<q-splitter |
|||
v-model="splitterModel" |
|||
v-bind="attrs" |
|||
:horizontal="horizontal" |
|||
:disable="disable" |
|||
class="h-full w-full w-splitter" |
|||
:separator-class="{ lineColor: !disable }" |
|||
> |
|||
<template #before> |
|||
<slot name="before"></slot> |
|||
</template> |
|||
<template v-if="showIcon && !disable" #separator> |
|||
<q-icon :name="horizontal ? 'more_horiz' : 'more_vert'" :color="iconColor" :size="iconSize"> </q-icon> |
|||
</template> |
|||
<template #after> |
|||
<slot name="after"></slot> |
|||
</template> |
|||
</q-splitter> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import { getCssVar } from 'quasar'; |
|||
import { ref, useAttrs } from 'vue'; |
|||
|
|||
const attrs = useAttrs(); |
|||
const props = defineProps({ |
|||
/** |
|||
* 切分大小 |
|||
*/ |
|||
size: { |
|||
type: Number, |
|||
default: 50, |
|||
}, |
|||
/** |
|||
* 上下切分,默认为左右切分 |
|||
*/ |
|||
horizontal: { |
|||
type: Boolean, |
|||
default: false, |
|||
}, |
|||
/** |
|||
* 禁用拖拽面板大小 |
|||
*/ |
|||
disable: { |
|||
type: Boolean, |
|||
default: false, |
|||
}, |
|||
/** |
|||
* 分割线上显示icon |
|||
*/ |
|||
showIcon: { |
|||
type: Boolean, |
|||
default: true, |
|||
}, |
|||
/** |
|||
* icon大小 |
|||
*/ |
|||
iconSize: { |
|||
type: String, |
|||
default: 'sm', |
|||
}, |
|||
/** |
|||
* icon颜色 |
|||
*/ |
|||
iconColor: { |
|||
type: String, |
|||
default: 'primary', |
|||
}, |
|||
/** |
|||
* 分割线颜色 |
|||
*/ |
|||
separatorColor: { |
|||
type: String, |
|||
default: undefined, |
|||
}, |
|||
}); |
|||
const splitterModel = ref(props.size); |
|||
const lineColor = props.separatorColor || getCssVar('primary'); |
|||
</script> |
|||
|
|||
<style lang="css"> |
|||
.w-splitter .lineColor { |
|||
/* 添加平滑过渡 */ |
|||
transition: background-color 0.3s; |
|||
} |
|||
.w-splitter .lineColor:hover { |
|||
/* 悬停时的背景色 */ |
|||
background-color: v-bind(lineColor); |
|||
} |
|||
.w-splitter.q-splitter--active .lineColor { |
|||
background-color: v-bind(lineColor); |
|||
} |
|||
</style> |
Loading…
Reference in new issue