Files
crmeb-mp/pages/index/components/images.vue

251 lines
6.0 KiB
Vue

<template>
<!-- 图片组件 -->
<view v-show="!dataConfig.isHide" class="images-component" :style="containerStyle">
<!-- 无链接时使用普通view -->
<view v-if="!linkUrl" class="images-navigator" :style="imgContainerStyle">
<image
v-if="imgUrl"
:src="imgUrl"
:mode="imgMode"
class="images-img"
:style="imgStyle"
:show-menu-by-longpress="isQrCode"
@load="onImgLoad"
@error="onImgError"
></image>
<!-- 占位图 -->
<view v-else class="images-placeholder">
<text class="placeholder-text">暂无图片</text>
</view>
</view>
<!-- 有链接时使用navigator -->
<navigator v-else :url="linkUrl" hover-class="none" class="images-navigator" :style="imgContainerStyle">
<image
v-if="imgUrl"
:src="imgUrl"
:mode="imgMode"
class="images-img"
:style="imgStyle"
:show-menu-by-longpress="isQrCode"
@load="onImgLoad"
@error="onImgError"
></image>
<!-- 占位图 -->
<view v-else class="images-placeholder">
<text class="placeholder-text">暂无图片</text>
</view>
</navigator>
</view>
</template>
<script>
export default {
name: 'home_image',
props: {
dataConfig: {
type: Object,
default: () => {}
}
},
data() {
return {
imgError: false
}
},
mounted() {
const debug = uni.getStorageSync('DEBUG_DIY_RENDER') === true
if (!debug) return
console.log('[DIY][component]', 'home_image', 'mounted', {
id: this.dataConfig?.id,
timestamp: this.dataConfig?.timestamp,
url: this.imgConfig?.url || this.dataConfig?.imgConfig?.url
})
},
computed: {
// 图片配置
imgConfig() {
return this.dataConfig.imgConfig || {}
},
// 链接配置
linkConfig() {
return this.dataConfig.linkConfig || {}
},
// 二维码模式
isQrCode() {
return this.dataConfig.isQrCode?.val === true
},
// 上边距
topConfig() {
return this.dataConfig.topConfig || {}
},
// 下边距
bottomConfig() {
return this.dataConfig.bottomConfig || {}
},
// 左右边距
prConfig() {
return this.dataConfig.prConfig || {}
},
// 页面间距
mbConfig() {
return this.dataConfig.mbConfig || {}
},
// 圆角配置
fillet() {
return this.dataConfig.fillet || {}
},
// 背景颜色
bgColor() {
return this.dataConfig.bgColor || {}
},
// 图片地址
imgUrl() {
const url = this.imgConfig.url || ''
if (!url) return ''
// 处理安全域名
if (url.indexOf('https://') > -1) return url
return url.replace('http://', 'https://')
},
// 链接地址(从 imgConfig.link 获取)
linkUrl() {
// 直接从 imgConfig.link 获取字符串链接
const link = this.imgConfig.link || this.linkConfig?.link || ''
if (!link) return ''
// 支持字符串链接
if (typeof link === 'string') {
return link
}
// 支持对象结构 { url: '', title: '' }
if (typeof link === 'object') {
return link.url || ''
}
// 兼容旧的数组结构
if (Array.isArray(link) && link.length > 0) {
return link[0]?.link || link[0]?.url || ''
}
return ''
},
// 图片显示模式
imgMode() {
return 'widthFix'
},
// 容器样式
containerStyle() {
const style = {}
// 上边距
if (this.topConfig.val) {
style.marginTop = this.topConfig.val + 'rpx'
}
// 页面间距
if (this.mbConfig.val) {
style.marginBottom = this.mbConfig.val + 'rpx'
}
// 下边距
if (this.bottomConfig.val) {
style.paddingBottom = this.bottomConfig.val + 'rpx'
}
// 背景颜色
if (this.bgColor.color && this.bgColor.color[0]?.item) {
style.backgroundColor = this.bgColor.color[0].item
}
return style
},
// 图片容器样式
imgContainerStyle() {
const style = {}
const fillet = this.fillet
// 左右边距
if (this.prConfig.val) {
style.paddingLeft = this.prConfig.val + 'rpx'
style.paddingRight = this.prConfig.val + 'rpx'
}
// 圆角 - 全部圆角模式
if (fillet.type === 0 && fillet.val) {
style.borderRadius = fillet.val + 'rpx'
}
return style
},
// 图片样式
imgStyle() {
const style = {}
const fillet = this.fillet
// 圆角 - 单独设置模式
if (fillet.type === 1 && fillet.valList) {
const [tl, tr, br, bl] = fillet.valList
const radius = `${tl?.val || 0}rpx ${tr?.val || 0}rpx ${br?.val || 0}rpx ${bl?.val || 0}rpx`
style.borderRadius = radius
}
return style
}
},
methods: {
onImgLoad(e) {
const debug = uni.getStorageSync('DEBUG_DIY_RENDER') === true
if (!debug) return
console.log('[DIY][component]', 'home_image', 'img_load', {
id: this.dataConfig?.id,
timestamp: this.dataConfig?.timestamp,
src: this.imgUrl,
width: e?.detail?.width,
height: e?.detail?.height
})
},
// 图片加载失败处理
onImgError(e) {
const debug = uni.getStorageSync('DEBUG_DIY_RENDER') === true
if (debug) {
console.log('[DIY][component]', 'home_image', 'img_error', {
id: this.dataConfig?.id,
timestamp: this.dataConfig?.timestamp,
src: this.imgUrl,
detail: e?.detail
})
}
this.imgError = true
}
}
}
</script>
<style lang="scss" scoped>
.images-component {
width: 100%;
box-sizing: border-box;
overflow: hidden;
.images-navigator {
display: block;
width: 100%;
}
.images-img {
width: 100%;
display: block;
}
.images-placeholder {
width: 100%;
height: 300rpx;
background-color: #f5f5f5;
display: flex;
align-items: center;
justify-content: center;
.placeholder-text {
color: #999;
font-size: 28rpx;
}
}
}
</style>