组件代码
<template>
<view>
<view class="signals">
<view v-for="(item, index) in signals" :key="index" class="signal" :style="item"></view>
</view>
</view>
</template>
<script setup>
/**
* 信号格组件
* @description 信号格组件
* @property {Number} signal 当前信号值
* @property {Number|String} columnWidth 柱宽度
* @property {Number} maxSignal 最大信号值
* @property {Number} bisection 信号等分
* @property {String} lowColor 信号低颜色
* @property {String} midColor 信号中颜色
* @property {String} highColor 信号高颜色
* @property {String} nothingColor 信号空颜色
* @example <signal :signal="31"></signal>
*/
import {
ref,
watch,
defineProps
} from 'vue'
const props = defineProps({
signal: {
type: Number,
default: 31,
},
columnWidth: {
type: [Number, String],
default: 2,
},
maxSignal: {
type: Number,
default: 31,
},
bisection: {
type: Number,
default: 4,
},
lowColor: {
type: String,
default: '#13AD11',
},
midColor: {
type: String,
default: '#13AD11',
},
highColor: {
type: String,
default: '#13AD11',
},
nothingColor: {
type: String,
default: '#c8c9cc',
}
})
const initHeight = ref(1)
const signals = ref([])
const doChanges = () => {
const x = props.maxSignal / props.bisection
let min = 0
let max = x
const list = []
for (let i = 0; i < props.bisection; i++) {
let color
if (i === 0) {
color = props.lowColor
} else if (i > 0 && i < props.bisection - 1) {
color = props.midColor
} else if (i === props.bisection - 1) {
color = props.highColor
}
list.push({
min: Math.floor(min),
max: Math.floor(max),
color: color
})
min = max
max += x
}
let color
if (props.signal >= props.maxSignal) {
color = props.highColor
} else if (props.signal === 0) {
color = props.nothingColor
} else {
list.forEach((items) => {
if (props.signal >= items.min && props.signal < items.max) {
color = items.color
}
})
}
list.forEach((items) => {
if (props.signal >= items.min) {
items.color = color
} else {
items.color = props.nothingColor
}
})
signals.value = list.map((items) => ({
width: `${
props.columnWidth}px`,
height: `${
initHeight.value += 1}px`,
backgroundColor: items.color
}))
}
watch(() => [props.signal, props.columnWidth, props.maxSignal, props.bisection, props.lowColor, props.midColor, props
.highColor, props.nothingColor
], doChanges, {
deep: true,
immediate: true
})
doChanges()
</script>
<style lang="scss">
.signals {
display: flex;
align-items: baseline;
.signal {
border-radius: 50rpx;
margin: 0 1px;
}
}
</style>
使用代码
引入:
import Signal from '@/components/signal/signal.vue'
使用:
<Signal :signal="info.signal" style="margin-right: 10rpx;"></Signal>