1
This commit is contained in:
@@ -0,0 +1,242 @@
|
||||
<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>
|
||||
Reference in New Issue
Block a user