Files
hospital-rescue-app-v2/uni_modules/tmx-ui/components/x-image-group/x-image-group.uvue
T
2026-09-24 16:25:22 +08:00

242 lines
6.3 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script lang="ts" setup>
import { ref, computed } from "vue"
import { getUid } from "../../core/util/xCoreUtil.uts"
import { getDefaultColor } from "../../core/util/xCoreColorUtil.uts"
import { checkIsCssUnit, getUnit } from "../../core/util/xCoreUtil.uts"
import { xConfig } from "../../config/xConfig.uts"
/**
* @name 图集 xImageGroup
* @description 主要是为了一些需要快速图片排版集的展示,比如评论图集,详情列表图集等,快速开发时使用。方便快捷。
* @page /pages/index/image-group
* @category 展示组件
* @constant 平台兼容
* | Harmony | H5 | andriod | IOS | 小程序 | UTS | UNIAPP-X SDK | version |
| --- | --- | --- | --- | --- | --- | --- | --- |
| ☑ | ☑ | ☑️ | ☑️ | ☑️ | ☑️ | 4.76+ | 1.1.18 |
*/
defineOptions({name:"xImageGroup"})
const emits = defineEmits<{
/**
* 图片项目被点击
* @param item - 项目
*/
click: [item: UTSJSONObject]
}>()
type xImageGroupPropsType = {
/**
* 图片列表
* 只要包含有url字段即可。
* label需要在图片显示的文本字段,如果没有不要出现此字段
* 如果提供了temp缩略图,会优先展示temp字段,预览时采用url原图
* {url:string,label?:string,temp?:string}
*/
list: UTSJSONObject[],
/**
* 显示的模式见:https://doc.dcloud.net.cn/uni-app-x/component/image.html
*/
model: string,
/**
* 图片高,不要使用auto%
*/
height: string,
/**
* 图片宽,不要使用auto,可以%值
*/
width: string,
/**
* 间隙
*/
gutter: string,
/**
* inset表示文本在图片上
* ouuter表示文本在正文展示
* 不要动态修改
*/
labelModel: 'inset' | 'outter',
/**
* 如果有文字显示文字的大小
*/
labelFontSize: string,
/**
* 如果有文字,显示文字的颜色
*/
labelFontColor: string,
/**
* 如果有文字,显示文字的颜色,暗黑时为空时取白
*/
darkLabelFontColor: string,
/**
* 是否预览图片
*/
preview: boolean,
/**
* 圆角
*/
round: string
}
const props = withDefaults(defineProps<xImageGroupPropsType>(), {
list: ():UTSJSONObject[] => [] as UTSJSONObject[],
model: "scaleToFill",
height: "100",
width: "33.33%",
gutter: "2",
labelModel: "inset",
labelFontSize: "14",
labelFontColor: "white",
darkLabelFontColor: "",
preview: true,
round: "0"
})
// 计算属性
const _list = computed((): UTSJSONObject[] => {
return props.list
})
const _labelFontColor = computed((): string => {
if (xConfig.dark == 'dark') {
if (props.darkLabelFontColor != '') return getDefaultColor(props.darkLabelFontColor)
return "#ffffff"
}
return getDefaultColor(props.labelFontColor)
})
const _gutter = computed((): string => {
return checkIsCssUnit(props.gutter, xConfig.unit)
})
const _labelFontSize = computed((): string => {
let fontSize = checkIsCssUnit(props.labelFontSize, xConfig.unit);
if (xConfig.fontScale == 1) return fontSize;
let sizeNumber = parseInt(fontSize)
if (isNaN(sizeNumber)) {
sizeNumber = 14
}
return (sizeNumber * xConfig.fontScale).toString() + getUnit(fontSize)
})
const _width = computed((): string => {
return checkIsCssUnit(props.width, xConfig.unit)
})
const _height = computed((): string => {
return checkIsCssUnit(props.height, xConfig.unit)
})
const _round = computed((): string => {
return checkIsCssUnit(props.round, xConfig.unit)
})
// 方法
function showUrlList(item: UTSJSONObject): string {
let url = item.getString('url');
url = url == null ? '' : url
let temp = item.getString('temp');
if (temp != null) return temp;
return url;
}
function showLabel(item: UTSJSONObject): string {
let label = item.getString('label');
label = label == null ? '' : label
return label;
}
function onClick(item: UTSJSONObject, index: number): void {
let url = item.getString('url');
url = url == null ? '' : url
let listurl = _list.value.map((el: UTSJSONObject): string => {
let temurl = el.getString('url');
temurl = temurl == null ? '' : temurl
return temurl;
})
if (props.preview) {
uni.previewImage({
current: url,
urls: listurl as string[]
})
}
emits('click', item)
}
</script>
<template>
<view class="xImageGroup">
<view @click="onClick(item,index)" v-for="(item,index) in _list" :key="index" class="xImageGroupWrap"
:style="{padding:_gutter,width:_width,height:_height,borderRadius:_round}">
<view class="xImageGroupWrapBox">
<x-image :round="_round" :ratio="1" width="100%" height="100%" style="height: 100%;width:100%" :model="props.model" :preview="false" :src="showUrlList(item)"></x-image>
</view>
<!-- margin:labelModel=='inset'?_gutter:'0px' -->
<view v-if="showLabel(item)!=''" class="xImageGroupLabelBox" :style="{
position:props.labelModel=='inset'?'absolute':'static',
}">
<view class="xImageGroupLabelBoxPadding" :style="{
margin:props.labelModel=='inset'?_gutter:'0px',
padding: props.labelModel=='inset'?'20rpx':'20rpx 0px',
borderRadius:_round,
'background-image': props.labelModel=='inset'?'linear-gradient(to bottom,rgba(0,0,0,0),rgba(0,0,0,0.9))':''
}">
<text :style="{fontSize:_labelFontSize,color:_labelFontColor}"
class="xImageGroupLabelLabel">{{showLabel(item)}}</text>
</view>
</view>
</view>
</view>
</template>
<style scoped>
.xImageGroupLabelBox {
z-index: 2;
left: 0px;
bottom: 0px;
pointer-events: none;
width: 100%;
/* #ifdef MP || WEB */
box-sizing: border-box;
/* #endif */
}
.xImageGroupLabelBoxPadding {
/* background-image: linear-gradient(to bottom,rgba(0,0,0,0),rgba(0,0,0,0.9)); */
}
.xImageGroupLabelLabel {
/* color:white; */
lines: 1;
/* #ifdef WEB */
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
text-overflow: ellipsis;
overflow: hidden;
word-break: break-all;
/* #endif */
}
.xImageGroupWrap {
display: flex;
flex-direction: column;
align-items: stretch;
position: relative;
/* #ifdef MP || WEB */
box-sizing: border-box;
/* #endif */
}
.xImageGroupWrapBox {
flex: 1;
pointer-events: none;
}
.xImageGroup {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: flex-start;
flex-wrap: wrap;
}
</style>