Files
2026-09-24 16:25:22 +08:00

125 lines
3.8 KiB
Plaintext
Raw Permalink 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.
<template>
<!--
列表项:内部统一由组件库 xCell 渲染
对外保持本项目既有的 <hr-lrow icon theme title sub value …/> 用法,
这样 30+ 处列表无需逐个改造,且全站列表外观/交互由 xCell 统一保证。
-->
<x-cell :card="false" :margin="emptyMargin" :padding="cellPadding" :min-height="minHeight"
:show-bottom-border="!isLast" :bottom-border-insert="true" bottom-border-color="#F3F4F6" :title="title"
title-color="#1F2937" title-size="28rpx" :icon="resolvedIcon" :link="false" @click="onClick">
<!-- 左侧图标:彩色圆角块 + RemixIcon -->
<template v-slot:avatar>
<view class="hr-lrow-ic" :style="{ backgroundColor: tc.bg }">
<x-icon :name="resolvedIcon" :color="tc.color" font-size="32rpx"></x-icon>
</view>
</template>
<!--
标题走默认插槽自己渲染。
原因:库内 .title 写死 lines:2(且是 scoped 样式),全站列表希望标题只有一行、
超出省略号;用插槽把标题换成自己的元素,样式完全可控,不依赖 !important 覆盖。
-->
<template v-slot:default>
<text class="hr-lrow-t">{{ title }}</text>
</template>
<!-- 副标题 -->
<template v-slot:desc>
<text v-if="sub != ''" class="hr-lmain-s">{{ sub }}</text>
</template>
<!-- 右侧:自定义插槽 + 数值文本 -->
<template v-slot:right>
<slot name="right"></slot>
<text v-if="value != ''" class="hr-lval" :style="valueStyle">{{ value }}</text>
</template>
</x-cell>
</template>
<script lang="uts" setup>
import { computed } from 'vue'
import { toRemixIcon, themeColor, HrThemeColor } from '@/utils/icon.uts'
/**
* 列表行
* themedefault / pri / red / amb / grn —— 控制左侧图标底色
* valueThemet3(默认) / pri / red / amb / grn / t1
* icon 支持字符图标(设计稿沿用)或 RemixIcon 名,内部自动识别
*/
const props = defineProps({
icon : { type: String, default: '' },
theme : { type: String, default: 'default' },
title : { type: String, default: '' },
sub : { type: String, default: '' },
value : { type: String, default: '' },
valueTheme : { type: String, default: 't3' },
/** 右侧文字字号(rpx */
valueSize : { type: String, default: '26rpx' },
/** 值是否加粗 */
valueBold : { type: Boolean, default: false },
/** 是否是最后一行(去除分隔线) */
isLast : { type: Boolean, default: false },
/** 是否是第一行 */
isFirst : { type: Boolean, default: false }
})
const emits = defineEmits<{
(e : 'click') : void
}>()
const resolvedIcon = computed(() : string => {
return toRemixIcon(props.icon)
})
const tc = computed(() : HrThemeColor => {
return themeColor(props.theme)
})
const emptyMargin = computed(() : string[] => {
return ['0', '0']
})
const cellPadding = computed(() : string[] => {
return props.isFirst ? ['20rpx', '0'] : ['24rpx', '0']
})
const minHeight = computed(() : string => {
return '112rpx'
})
const valueStyle = computed(() : string => {
let color = '#9CA3AF'
if (props.valueTheme == 'pri') { color = '#2563EB' }
if (props.valueTheme == 'red') { color = '#DC2626' }
if (props.valueTheme == 'amb') { color = '#D97706' }
if (props.valueTheme == 'grn') { color = '#059669' }
if (props.valueTheme == 't1') { color = '#1F2937' }
const weight = props.valueBold ? 'bold' : 'normal'
return `color:${color};font-size:${props.valueSize};font-weight:${weight};`
})
function onClick() : void {
emits('click')
}
</script>
<style>
.hr-lrow-ic {
width: 64rpx;
height: 64rpx;
border-radius: 18rpx;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
/* 列表行标题:单行显示,超出省略号 */
.hr-lrow-t {
font-size: 28rpx;
color: #1F2937;
lines: 1;
text-overflow: ellipsis;
}
</style>