1
This commit is contained in:
@@ -0,0 +1,228 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed } from "vue"
|
||||
import { getDefaultColor } from "../../core/util/xCoreColorUtil.uts"
|
||||
import { checkIsCssUnit } from "../../core/util/xCoreUtil.uts"
|
||||
import { xConfig } from "../../config/xConfig.uts"
|
||||
|
||||
/**
|
||||
*
|
||||
* @name 卡片 xCard
|
||||
* @page /pages/index/card
|
||||
* @category 展示组件
|
||||
* @description 圆角,主题可统一全局配置风格。
|
||||
* @constant 平台兼容
|
||||
* | Harmony | H5 | andriod | IOS | 小程序 | UTS | UNIAPP-X SDK | version |
|
||||
| --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
| ☑ | ☑ | ☑️ | ☑️ | ☑️ | ☑️ | 4.76+ | 1.1.18 |
|
||||
*/
|
||||
defineOptions({name:"xCard"})
|
||||
|
||||
const emits = defineEmits([
|
||||
/** 卡片被点击 */
|
||||
'click',
|
||||
/** 右边状态小图标被点击 */
|
||||
'status',
|
||||
/** 底部按钮被点击 */
|
||||
'action'
|
||||
])
|
||||
|
||||
type BtnSizeType = "mini" | "small" | "normal" | "large"
|
||||
|
||||
type xCardPropsType = {
|
||||
/** 内容的内边距。 */
|
||||
padding: string,
|
||||
/** 标题文字大小 */
|
||||
titleSize: string,
|
||||
/** 按钮颜色 */
|
||||
btnColor: string,
|
||||
/** 标题颜色 */
|
||||
color: string,
|
||||
/** 背景颜色 */
|
||||
bgColor: string,
|
||||
/** 暗黑背景颜色,如果为空,取sheetDarkColor */
|
||||
darkBgColor: string,
|
||||
/** 底部按钮数组。如果不满意风格布局请使用插槽footer来布局 */
|
||||
btns: string[],
|
||||
/** 副标题 */
|
||||
subtitle: string,
|
||||
/** 标题 */
|
||||
title: string,
|
||||
/** 右边的小图标,如果你是想显示状态,日期请使用对应插槽 */
|
||||
statusIcon: string,
|
||||
/** 中间内容。如果有大量内容请直接在默认插槽(标签内)内布局 */
|
||||
content: string,
|
||||
/** 头部图片地址。 */
|
||||
image: string,
|
||||
/** 头图片高度 */
|
||||
imageHeight: string,
|
||||
/** 圆角请不要动态更改此会,默认为空,取全局设置的风格值。 */
|
||||
round: string,
|
||||
/** 请不要动态更改些投影值,截止4.75+鸿蒙无法使用投影 */
|
||||
shadow: string,
|
||||
/** 按钮尺寸 */
|
||||
btnSize: BtnSizeType
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<xCardPropsType>(), {
|
||||
padding: "16",
|
||||
titleSize: "18",
|
||||
btnColor: "",
|
||||
color: "#333333",
|
||||
bgColor: "#ffffff",
|
||||
darkBgColor: "",
|
||||
btns: () : string[] => [] as string[],
|
||||
subtitle: "",
|
||||
title: "",
|
||||
statusIcon: "more-fill",
|
||||
content: "",
|
||||
image: "",
|
||||
imageHeight: "150",
|
||||
round: "",
|
||||
shadow: "0 3px 10px rgba(0, 0, 0, 0.05)",
|
||||
btnSize: "small" as BtnSizeType
|
||||
})
|
||||
|
||||
// 计算属性
|
||||
const _image = computed((): string => props.image)
|
||||
const _round = computed((): string => {
|
||||
if (props.round == "") return checkIsCssUnit(xConfig.cardRound, xConfig.unit)
|
||||
return checkIsCssUnit(props.round, xConfig.unit)
|
||||
})
|
||||
const _imageHeight = computed((): string => checkIsCssUnit(props.imageHeight, xConfig.unit))
|
||||
const _padding = computed((): string => checkIsCssUnit(props.padding, xConfig.unit))
|
||||
const _titleSize = computed((): string => props.titleSize)
|
||||
const _color = computed((): string => getDefaultColor(props.color))
|
||||
const _bgColor = computed((): string => {
|
||||
if(xConfig.dark=='dark'){
|
||||
if(props.darkBgColor!='') return getDefaultColor(props.darkBgColor)
|
||||
return getDefaultColor(xConfig.sheetDarkColor)
|
||||
}
|
||||
return getDefaultColor(props.bgColor)
|
||||
})
|
||||
const _btnColor = computed((): string => {
|
||||
if (props.btnColor == "") return getDefaultColor(xConfig.color)
|
||||
return getDefaultColor(props.btnColor)
|
||||
})
|
||||
const _btns = computed((): string[] => props.btns)
|
||||
const _subtitle = computed((): string => props.subtitle)
|
||||
const _title = computed((): string => props.title)
|
||||
const _statusIcon = computed((): string => props.statusIcon)
|
||||
const _content = computed((): string => props.content)
|
||||
|
||||
// 方法
|
||||
function actionClick(index : number) {
|
||||
emits('action', index)
|
||||
}
|
||||
function statusClick() {
|
||||
emits('status')
|
||||
}
|
||||
function onClick() {
|
||||
emits('click')
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<!-- boxShadow: shadow, -->
|
||||
<view @click="onClick" class="xCard"
|
||||
<!-- #ifndef APP-HARMONY -->
|
||||
:style="{borderRadius:_round,boxShadow: shadow,backgroundColor:_bgColor}"
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef APP-HARMONY -->
|
||||
:style="{borderRadius:_round,backgroundColor:_bgColor}"
|
||||
<!-- #endif -->
|
||||
>
|
||||
<!--
|
||||
@slot 图片插槽
|
||||
-->
|
||||
<slot name="image">
|
||||
<image :style="{width:'100%',height:_imageHeight,borderRadius:`${_round} ${_round} 0px 0px`}" :src="_image"
|
||||
v-if="_image!=''"></image>
|
||||
</slot>
|
||||
<view :style="{padding:_padding}">
|
||||
<view class="xCardHeader">
|
||||
<!--
|
||||
@slot 标题插槽
|
||||
-->
|
||||
<slot name="title">
|
||||
<view v-if="_title!=''">
|
||||
<x-text :color="_color" :font-size="_titleSize" class="xCardTitle">{{_title}}</x-text>
|
||||
</view>
|
||||
</slot>
|
||||
<!--
|
||||
@slot 状态右边小图标插槽
|
||||
-->
|
||||
<slot name="statusIcon">
|
||||
<view @click.stop="statusClick" v-if="_statusIcon!=''" style="padding: 0rpx 0rpx 0rpx 16px;">
|
||||
<x-icon :font-size="_titleSize" :name="_statusIcon"></x-icon>
|
||||
</view>
|
||||
</slot>
|
||||
</view>
|
||||
<view class="xCardSubtitle">
|
||||
<!--
|
||||
@slot 副标题插槽
|
||||
-->
|
||||
<slot name="subtitle">
|
||||
<x-text font-size="12" v-if="_subtitle!=''" class="xCardSubtitleText">
|
||||
{{subtitle}}
|
||||
</x-text>
|
||||
</slot>
|
||||
</view>
|
||||
<!--
|
||||
@slot 默认内容插槽
|
||||
-->
|
||||
<slot>
|
||||
<x-text :color="_color" font-size="16" v-if="_content!=''" class="xCardContent">
|
||||
{{_content}}
|
||||
</x-text>
|
||||
</slot>
|
||||
<!--
|
||||
@slot 底部插槽
|
||||
-->
|
||||
<slot name="footer">
|
||||
<view class="xCardFooter" v-if="_btns.length>0">
|
||||
<x-button round="6" @click.stop="actionClick(index)" v-for="(item,index) in _btns" :key="index"
|
||||
:style="{marginRight:(index!=_btns.length-1)?'12px':'0px'}" :color="_btnColor"
|
||||
:size="btnSize">{{item}}</x-button>
|
||||
</view>
|
||||
</slot>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<style scoped>
|
||||
.xCardContent {
|
||||
font-size: 14px;
|
||||
line-height: 1.4;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.xCardFooter {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-start;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.xCardSubtitle {}
|
||||
|
||||
.xCardSubtitleText {
|
||||
font-size: 13px;
|
||||
opacity: 0.7;
|
||||
padding: 12rpx 0rpx 24rpx 0rpx;
|
||||
}
|
||||
|
||||
.xCardHeader {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.xCardTitle {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.xCard {
|
||||
/* box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1); */
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user