This commit is contained in:
2026-01-05 12:47:14 +08:00
commit 1fc846fae3
1614 changed files with 162035 additions and 0 deletions

View File

@@ -0,0 +1,66 @@
.nut-price {
display: inline;
font-size: 0;
color: $primary-color;
&--strike {
[class*='nut-price'] {
text-decoration: line-through;
}
}
&--symbol {
display: inline-block;
font-size: $font-size-3;
}
&--large {
display: inline-block;
font-size: $price-big-size;
}
&--point {
display: inline-block;
font-size: $price-big-size;
}
&--decimal-large {
display: inline-block;
font-size: $price-decimal-big-size;
}
&--symbol-large {
display: inline-block;
font-size: $price-symbol-big-size;
}
&--normal {
display: inline-block;
font-size: $price-medium-size;
}
&--decimal-normal {
display: inline-block;
font-size: $price-decimal-medium-size;
}
&--symbol-normal {
display: inline-block;
font-size: $price-symbol-medium-size;
}
&--small {
display: inline-block;
font-size: $price-small-size;
}
&--decimal-small {
display: inline-block;
font-size: $price-decimal-small-size;
}
&--symbol-small {
display: inline-block;
font-size: $price-symbol-small-size;
}
}

View File

@@ -0,0 +1 @@
export * from './price'

View File

@@ -0,0 +1,40 @@
import type { ExtractPropTypes } from 'vue'
import { commonProps, makeNumberProp, makeNumericProp, makeStringProp, truthProp } from '../_utils'
export const priceProps = {
...commonProps,
/**
* @description 价格数量
*/
price: makeNumericProp(0),
/**
* @description 是否需要加上 symbol 符号
*/
needSymbol: truthProp,
/**
* @description 符号类型
*/
symbol: makeStringProp('¥'),
/**
* @description 小数位位数
*/
decimalDigits: makeNumberProp(2),
/**
* @description 是否按照千分号形式显示
*/
thousands: Boolean,
/**
* @description 符号显示在价格前或者后,`before`、`after`
*/
position: makeStringProp<'before' | 'after'>('before'),
/**
* @description 价格尺寸,`small`、`normal`、`large`
*/
size: makeStringProp<'small' | 'normal' | 'large'>('normal'),
/**
* @description 是否展示划线价
*/
strikeThrough: Boolean,
}
export type PriceProps = ExtractPropTypes<typeof priceProps>

View File

@@ -0,0 +1,106 @@
<script setup lang="ts">
import { computed, defineComponent } from 'vue'
import { PREFIX } from '../_constants'
import { getMainClass } from '../_utils'
import { priceProps } from './price'
const props = defineProps(priceProps)
const classes = computed(() => {
return getMainClass(props, componentName, {
[`${componentName}--strike`]: props.strikeThrough,
})
})
function replaceSpecialChar(url: string) {
url = url.replace(/&quot;/g, '"')
url = url.replace(/&amp;/g, '&')
url = url.replace(/&lt;/g, '<')
url = url.replace(/&gt;/g, '>')
url = url.replace(/&nbsp;/g, ' ')
url = url.replace(/&yen;/g, '¥')
return url
}
const showSymbol = computed(() => {
const symbol = props.needSymbol ? replaceSpecialChar(props.symbol) : ''
return symbol
})
function checkPoint(price: string | number) {
return String(price).indexOf('.') > 0
}
function formatThousands(num: any) {
if (Number(num) === 0)
num = 0
if (checkPoint(num)) {
num = Number(num).toFixed(props.decimalDigits)
num = typeof num.split('.') === 'string' ? num.split('.') : num.split('.')[0]
}
else {
num = num.toString()
}
if (props.thousands)
return (num || 0).toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,')
else
return num
}
function formatDecimal(decimalNum: any) {
if (Number(decimalNum) === 0)
decimalNum = 0
if (checkPoint(decimalNum)) {
decimalNum = Number(decimalNum).toFixed(props.decimalDigits)
decimalNum
= typeof decimalNum.split('.') === 'string' ? 0 : decimalNum.split('.')[1] ? decimalNum.split('.')[1] : 0
}
else {
decimalNum = 0
}
const result = `0.${decimalNum}`
const resultFixed = Number(result).toFixed(props.decimalDigits)
return String(resultFixed).substring(2, resultFixed.length)
}
</script>
<script lang="ts">
const componentName = `${PREFIX}-price`
export default defineComponent({
name: componentName,
options: {
virtualHost: true,
addGlobalClass: true,
styleIsolation: 'shared',
},
})
</script>
<template>
<view :class="classes" :style="customStyle">
<rich-text
v-if="needSymbol && position === 'before'"
class="nut-price--symbol"
:class="`nut-price--symbol-${size}`"
:nodes="showSymbol"
/>
<view :class="`nut-price--${size}`">
{{ formatThousands(price) }}
</view>
<view v-if="decimalDigits !== 0" :class="`nut-price--decimal-${size}`">
.
</view>
<view :class="`nut-price--decimal-${size}`">
{{ formatDecimal(price) }}
</view>
<rich-text
v-if="needSymbol && position === 'after'"
class="nut-price--symbol"
:class="`nut-price--symbol-${size}`"
:nodes="showSymbol"
/>
</view>
</template>
<style lang="scss">
@import './index';
</style>