<script setup>
|
import { ref, computed } from "vue";
|
const props = defineProps({
|
label: {
|
type: String,
|
required: true
|
},
|
unit: {
|
type: String,
|
default: '',
|
},
|
value: {
|
type: [String, Number],
|
required: true
|
},
|
color: {
|
type: String,
|
default: '#0ff'
|
},
|
})
|
|
function hexToRgba(hex, alpha = 1) {
|
// 去除 # 符号
|
hex = hex.replace('#', '');
|
|
// 处理 3 位和 6 位十六进制颜色码
|
if (hex.length === 3) {
|
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
|
}
|
|
// 解析红、绿、蓝通道的值
|
const r = parseInt(hex.slice(0, 2), 16);
|
const g = parseInt(hex.slice(2, 4), 16);
|
const b = parseInt(hex.slice(4, 6), 16);
|
|
// 生成 rgba 字符串
|
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
|
}
|
|
const bgColor = computed(() => {
|
return hexToRgba(props.color, 0.2);
|
});
|
|
const bdColor = computed(() => {
|
return hexToRgba(props.color, 0.4);
|
});
|
|
|
|
</script>
|
|
<template>
|
<div class="panel" :style="{ '--color': props.color, '--bg': bgColor, '--border-color': bdColor, '--bg2': '#052C3B'}">
|
<div class="top">
|
<div class="label">{{ label }}</div>
|
<div class="unit" v-if="unit">{{ unit }}</div>
|
</div>
|
<div class="value">{{ value }}</div>
|
</div>
|
</template>
|
|
<style scoped lang="less">
|
.panel {
|
display: flex;
|
flex-direction: column;
|
justify-content: center;
|
// align-items: center;
|
padding: 6px 20px;
|
height: 70px;
|
width: 130px;
|
color: var(--color);
|
font-size: 14px;
|
border: 2px solid var(--border-color);
|
|
background-color: var(--bg) ;
|
position: relative;
|
.top {
|
display: flex;
|
justify-content: space-between;
|
align-items: flex-end;
|
padding: 0 6px;
|
}
|
.unit {
|
color: #fff;
|
font-size: 12px;
|
}
|
.label {
|
|
}
|
.value {
|
border: 2px solid var(--border-color);
|
background: var(--bg2);
|
font-weight: bold;
|
width: 100%;
|
font-size: 18px;
|
padding: 6px;
|
margin-top: 6px;
|
// margin-left: 1em;
|
}
|
&::before {
|
content: '';
|
position: absolute;
|
top: 0;
|
left: 0;
|
width: 100%;
|
height: 100%;
|
background-color: var(--color);
|
mask: url("data:image/svg+xml,%3csvg width='30' height='30' xmlns='http://www.w3.org/2000/svg' viewBox='-2 -2 30 30'%3e%3cpath d='M0 30L0 13L13 0L30 0' stroke='red' fill='none' stroke-width='4'%3e%3c/path%3e%3c/svg%3e") 4px 4px / auto 16% no-repeat,
|
url("data:image/svg+xml,%3csvg width='30' height='30' xmlns='http://www.w3.org/2000/svg' viewBox='-2 -2 30 30' transform='rotate(90)' %3e%3cpath d='M0 30L0 13L13 0L30 0' stroke='red' fill='none' stroke-width='4'%3e%3c/path%3e%3c/svg%3e") calc(100% - 4px) 4px e('/') auto 16% no-repeat,
|
url("data:image/svg+xml,%3csvg width='30' height='30' xmlns='http://www.w3.org/2000/svg' viewBox='-2 -2 30 30' transform='rotate(180)' %3e%3cpath d='M0 30L0 13L13 0L30 0' stroke='red' fill='none' stroke-width='4'%3e%3c/path%3e%3c/svg%3e") calc(100% - 4px) calc(100% - 4px) e('/') auto 16% no-repeat,
|
url("data:image/svg+xml,%3csvg width='30' height='30' xmlns='http://www.w3.org/2000/svg' viewBox='-2 -2 30 30' transform='rotate(270)' %3e%3cpath d='M0 30L0 13L13 0L30 0' stroke='red' fill='none' stroke-width='4'%3e%3c/path%3e%3c/svg%3e") 4px calc(100% - 4px) e('/') auto 16% no-repeat;
|
mask-composite: add;
|
}
|
|
}
|
</style>
|