|
|
<!-- @format -->
<template> <view class="index-card"> <view class="card-header"> <view class="flag-container"> <image :src="getMarketFlag(market)" class="flag-icon" mode="aspectFit"></image> </view> <text class="index-name">{{ stockName }}</text> </view>
<view class="price-info"> <text class="current-price" :style="{ color: priceColor }">{{ currentPrice }}</text> <view class="change-info"> <text class="change-amount" :style="{ color: priceColor }">{{ changeAmount }}</text> <text class="change-percent" :style="{ color: priceColor }">{{ changePercent }}</text> </view> </view>
<view class="chart-container"> <view class="mini-chart" :style="{ backgroundColor: chartBgColor }"> <!-- 这里可以放置实际的图表组件,目前用简单的波浪线表示 --> <view class="chart-line" :style="{ borderColor: priceColor }"></view> </view> </view> </view></template>
<script setup>import { computed } from "vue";
// 定义组件属性
const props = defineProps({ // 国旗图标路径
market: { type: String, required: true, }, // 指数名称
stockName: { type: String, required: true, }, // 当前价格
currentPrice: { type: [String, Number], required: true, }, // 涨跌金额
changeAmount: { type: [String, Number], required: true, }, // 涨跌幅
changePercent: { type: [String, Number], required: true, }, // 是否上涨
isRising: { type: Boolean, default: true, },});
const judgeSymbol = (num) => { // 兼容 undefined/null/数字/字符串
if (num === null || num === undefined) return ''; const n = Number(num); if (!isNaN(n)) { // 数值:正数加'+',负数原样
return (n < 0 ? '' : '+') + n; } // 字符串:去空格后判断前缀
const s = String(num).trim(); if (s.startsWith('-')) return s; if (s.startsWith('+')) return s; return '+' + s;};
const getMarketFlag = (market) => { let imagePath;
if (market === "cn") { imagePath = "/static/marketSituation-image/country-flag/cn.png"; } else if (market === "hk") { imagePath = "/static/marketSituation-image/country-flag/hk.png"; } else if (market === "can") { imagePath = "/static/marketSituation-image/country-flag/can.png"; } else if (market === "my") { imagePath = "/static/marketSituation-image/country-flag/my.png"; } else if (market === "sg") { imagePath = "/static/marketSituation-image/country-flag/sg.png"; } else if (market === "th") { imagePath = "/static/marketSituation-image/country-flag/th.png"; } else if (market === "vi") { imagePath = "/static/marketSituation-image/country-flag/vi.png"; } else if (market === "us" || market === "usa") { imagePath = "/static/marketSituation-image/country-flag/us.png"; } else { imagePath = "/static/marketSituation-image/country-flag/global.png"; } return imagePath;};
// 计算价格颜色
const priceColor = computed(() => { return props.isRising ? "#00C853" : "#FF1744";});
// 计算图表背景色
const chartBgColor = computed(() => { return props.isRising ? "#E8F5E8" : "#FFEBEE";});</script>
<style scoped>.index-card { background-color: #ffffff; border-radius: 12rpx; padding: 20rpx; margin: 16rpx; box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1); border: 1rpx solid #f0f0f0;}
.card-header { display: flex; align-items: center; margin-bottom: 16rpx;}
.flag-container { width: 48rpx; height: 32rpx; margin-right: 12rpx; border-radius: 4rpx; overflow: hidden;}
.flag-icon { width: 100%; height: 100%;}
.index-name { font-size: 28rpx; font-weight: 500; color: #333333; flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;}
.price-info { margin-bottom: 20rpx;}
.current-price { font-size: 36rpx; font-weight: bold; display: block; margin-bottom: 8rpx;}
.change-info { display: flex; align-items: center; gap: 16rpx;}
.change-amount { font-size: 24rpx; font-weight: 500;}
.change-percent { font-size: 24rpx; font-weight: 500;}
.chart-container { height: 80rpx; border-radius: 8rpx; overflow: hidden;}
.mini-chart { width: 100%; height: 100%; position: relative; border-radius: 8rpx;}
.chart-line { position: absolute; bottom: 20rpx; left: 10rpx; right: 10rpx; height: 2rpx; border-top: 2rpx solid; border-style: solid;}
/* 添加一些波浪效果 */.chart-line::before { content: ""; position: absolute; top: -10rpx; left: 20%; width: 20rpx; height: 20rpx; border: 2rpx solid; border-color: inherit; border-radius: 50%; background: transparent;}
.chart-line::after { content: ""; position: absolute; top: -6rpx; right: 30%; width: 12rpx; height: 12rpx; border: 2rpx solid; border-color: inherit; border-radius: 50%; background: transparent;}</style>
|