文件
Henglianshutong/uniapp/pages/goods/components/format-price.vue

194 行
5.3 KiB
Vue

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

<script setup>
import { computed, ref, watch } from 'vue'
const props = defineProps({
type: { type: String, default: 'from' },
price: { type: [String, Number, Array], default: 0 },
color: { type: String, default: '#333' },
fontSize: { type: [Number, String], default: 36 },
currencySymbol: { type: String, default: '¥' },
fontClass: { type: String, default: 'font-ALMM' },
fillDecimalZero: { type: Boolean, default: false },
decimalScale: { type: Number, default: 0.8 },
fromScale: { type: Number, default: 0.7 },
})
const priceType = ref(props.type)
const minPrice = ref(0)
const maxPrice = ref(0)
const minPriceSplit = computed(() => splitPrice(minPrice.value))
const maxPriceSplit = computed(() => splitPrice(maxPrice.value))
const decimalFontSize = computed(() => {
return (Number(props.fontSize) * props.decimalScale).toFixed(0)
})
const fromFontSize = computed(() => {
return (Number(props.fontSize) * props.fromScale).toFixed(0)
})
function toSafeNumber(v) {
const n = Number(v)
return Number.isFinite(n) ? n : 0
}
function formatPrice() {
const p = props.price
if (Array.isArray(p)) {
if (p.length === 0) {
minPrice.value = 0
maxPrice.value = 0
}
else if (p.length === 1) {
minPrice.value = toSafeNumber(p[0])
maxPrice.value = minPrice.value
}
else {
const nums = p.map(toSafeNumber)
minPrice.value = Math.min(...nums)
maxPrice.value = Math.max(...nums)
}
}
else {
minPrice.value = maxPrice.value = toSafeNumber(p)
}
if (minPrice.value === maxPrice.value) {
priceType.value = 'single'
}
else {
priceType.value = props.type
}
}
function splitPrice(price) {
const str = toSafeNumber(price).toFixed(2)
const [intPart, decPart = '00'] = str.split('.')
return {
int: intPart,
dec: decPart,
hasDec: decPart !== '00',
}
}
// 关键:props 变化时重算(含 price 从 undefined -> 有值)
watch(() => [props.price, props.type], formatPrice, { immediate: true, deep: true })
</script>
<template>
<view class="ss-flex">
<view class="ss-flex ss-col-baseline" :style="{ color: props.color }">
<!-- 货币单位 -->
<!-- <sar-icon name="demo-icons:bbd" color="#FFB013" :size="`${decimalFontSize}rpx`" /> -->
<view
v-if="props.currencySymbol"
class="ss-col-bottom"
:class="{ [props.fontClass]: true }"
:style="{
fontSize: `${decimalFontSize}rpx`,
}"
>
{{ props.currencySymbol }}
</view>
<!-- 单独价格 -->
<view v-if="priceType === 'single'" class="ss-flex ss-col-baseline">
<view
class="ss-col-bottom"
:class="{ [props.fontClass]: true }"
:style="{
fontSize: `${props.fontSize}rpx`,
}"
>
{{ minPriceSplit.int }}
</view>
<view
v-if="minPriceSplit.hasDec || props.fillDecimalZero"
class="ss-col-bottom"
:class="{ [props.fontClass]: true }"
:style="{
fontSize: `${decimalFontSize}rpx`,
}"
>
.{{ minPriceSplit.dec }}
</view>
</view>
<!-- 起价 -->
<view v-else-if="priceType === 'from'" class="ss-flex ss-col-baseline">
<view
class="ss-col-bottom"
:class="{ [props.fontClass]: true }"
:style="{
fontSize: `${props.fontSize}rpx`,
}"
>
{{ minPriceSplit.int }}
</view>
<view
v-if="minPriceSplit.hasDec || props.fillDecimalZero"
class="ss-col-bottom"
:class="{ [props.fontClass]: true }"
:style="{
fontSize: `${decimalFontSize}rpx`,
}"
>
.{{ minPriceSplit.dec }}
</view>
<view
class="ss-m-l-2 ss-col-bottom"
:style="{
fontSize: `${fromFontSize}rpx`,
}"
>
起
</view>
</view>
<!-- 价格范围 -->
<view v-else-if="priceType === 'range'" class="ss-flex ss-col-baseline" :class="{ [props.fontClass]: true }">
<view
class="ss-col-bottom"
:style="{
fontSize: `${props.fontSize}rpx`,
}"
>
{{ minPriceSplit.int }}
</view>
<!-- 小数部分:单独样式 -->
<view
v-if="minPriceSplit.hasDec || props.fillDecimalZero"
class="ss-col-bottom"
:style="{
fontSize: `${decimalFontSize}rpx`,
}"
>
.{{ minPriceSplit.dec }}
</view>
<view>~</view>
<view
class="ss-col-bottom"
:style="{
fontSize: `${props.fontSize}rpx`,
}"
>
{{ maxPriceSplit.int }}
</view>
<!-- 小数部分:单独样式 -->
<view
v-if="maxPriceSplit.hasDec || props.fillDecimalZero"
class="ss-col-bottom"
:class="{ [props.fontClass]: true }"
:style="{
fontSize: `${decimalFontSize}rpx`,
}"
>
.{{ maxPriceSplit.dec }}
</view>
</view>
</view>
</view>
</template>