-
190components/IndexCard.vue
-
371package-lock.json
-
5package.json
-
709pages/home/marketSituation.vue
-
6static/language/en.js
-
6static/language/ms.js
-
6static/language/th.js
-
6static/language/vi.js
-
4static/language/zh_CN.js
-
4static/language/zh_HK.js
-
BINstatic/marketSituation-image/bg.png
-
BINstatic/marketSituation-image/history.png
-
BINstatic/marketSituation-image/map.png
-
BINstatic/marketSituation-image/menu.png
-
BINstatic/marketSituation-image/more.png
-
BINstatic/marketSituation-image/mySeclected.png
-
BINstatic/marketSituation-image/search.png
-
BINstatic/marketSituation-image/warn.png
@ -0,0 +1,190 @@ |
|||
<template> |
|||
<view class="index-card"> |
|||
<view class="card-header"> |
|||
<view class="flag-container"> |
|||
<image :src="flagIcon" class="flag-icon" mode="aspectFit"></image> |
|||
</view> |
|||
<text class="index-name">{{ indexName }}</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({ |
|||
// 国旗图标路径 |
|||
flagIcon: { |
|||
type: String, |
|||
required: true |
|||
}, |
|||
// 指数名称 |
|||
indexName: { |
|||
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 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> |
|||
@ -0,0 +1,371 @@ |
|||
{ |
|||
"name": "DeepChartApp", |
|||
"lockfileVersion": 3, |
|||
"requires": true, |
|||
"packages": { |
|||
"": { |
|||
"dependencies": { |
|||
"vue-i18n": "^9.14.5" |
|||
} |
|||
}, |
|||
"node_modules/@babel/helper-string-parser": { |
|||
"version": "7.27.1", |
|||
"resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", |
|||
"integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", |
|||
"license": "MIT", |
|||
"peer": true, |
|||
"engines": { |
|||
"node": ">=6.9.0" |
|||
} |
|||
}, |
|||
"node_modules/@babel/helper-validator-identifier": { |
|||
"version": "7.27.1", |
|||
"resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", |
|||
"integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", |
|||
"license": "MIT", |
|||
"peer": true, |
|||
"engines": { |
|||
"node": ">=6.9.0" |
|||
} |
|||
}, |
|||
"node_modules/@babel/parser": { |
|||
"version": "7.28.4", |
|||
"resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.28.4.tgz", |
|||
"integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==", |
|||
"license": "MIT", |
|||
"peer": true, |
|||
"dependencies": { |
|||
"@babel/types": "^7.28.4" |
|||
}, |
|||
"bin": { |
|||
"parser": "bin/babel-parser.js" |
|||
}, |
|||
"engines": { |
|||
"node": ">=6.0.0" |
|||
} |
|||
}, |
|||
"node_modules/@babel/types": { |
|||
"version": "7.28.4", |
|||
"resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.28.4.tgz", |
|||
"integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", |
|||
"license": "MIT", |
|||
"peer": true, |
|||
"dependencies": { |
|||
"@babel/helper-string-parser": "^7.27.1", |
|||
"@babel/helper-validator-identifier": "^7.27.1" |
|||
}, |
|||
"engines": { |
|||
"node": ">=6.9.0" |
|||
} |
|||
}, |
|||
"node_modules/@intlify/core-base": { |
|||
"version": "9.14.5", |
|||
"resolved": "https://registry.npmmirror.com/@intlify/core-base/-/core-base-9.14.5.tgz", |
|||
"integrity": "sha512-5ah5FqZG4pOoHjkvs8mjtv+gPKYU0zCISaYNjBNNqYiaITxW8ZtVih3GS/oTOqN8d9/mDLyrjD46GBApNxmlsA==", |
|||
"license": "MIT", |
|||
"dependencies": { |
|||
"@intlify/message-compiler": "9.14.5", |
|||
"@intlify/shared": "9.14.5" |
|||
}, |
|||
"engines": { |
|||
"node": ">= 16" |
|||
}, |
|||
"funding": { |
|||
"url": "https://github.com/sponsors/kazupon" |
|||
} |
|||
}, |
|||
"node_modules/@intlify/message-compiler": { |
|||
"version": "9.14.5", |
|||
"resolved": "https://registry.npmmirror.com/@intlify/message-compiler/-/message-compiler-9.14.5.tgz", |
|||
"integrity": "sha512-IHzgEu61/YIpQV5Pc3aRWScDcnFKWvQA9kigcINcCBXN8mbW+vk9SK+lDxA6STzKQsVJxUPg9ACC52pKKo3SVQ==", |
|||
"license": "MIT", |
|||
"dependencies": { |
|||
"@intlify/shared": "9.14.5", |
|||
"source-map-js": "^1.0.2" |
|||
}, |
|||
"engines": { |
|||
"node": ">= 16" |
|||
}, |
|||
"funding": { |
|||
"url": "https://github.com/sponsors/kazupon" |
|||
} |
|||
}, |
|||
"node_modules/@intlify/shared": { |
|||
"version": "9.14.5", |
|||
"resolved": "https://registry.npmmirror.com/@intlify/shared/-/shared-9.14.5.tgz", |
|||
"integrity": "sha512-9gB+E53BYuAEMhbCAxVgG38EZrk59sxBtv3jSizNL2hEWlgjBjAw1AwpLHtNaeda12pe6W20OGEa0TwuMSRbyQ==", |
|||
"license": "MIT", |
|||
"engines": { |
|||
"node": ">= 16" |
|||
}, |
|||
"funding": { |
|||
"url": "https://github.com/sponsors/kazupon" |
|||
} |
|||
}, |
|||
"node_modules/@jridgewell/sourcemap-codec": { |
|||
"version": "1.5.5", |
|||
"resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", |
|||
"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", |
|||
"license": "MIT", |
|||
"peer": true |
|||
}, |
|||
"node_modules/@vue/compiler-core": { |
|||
"version": "3.5.22", |
|||
"resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.5.22.tgz", |
|||
"integrity": "sha512-jQ0pFPmZwTEiRNSb+i9Ow/I/cHv2tXYqsnHKKyCQ08irI2kdF5qmYedmF8si8mA7zepUFmJ2hqzS8CQmNOWOkQ==", |
|||
"license": "MIT", |
|||
"peer": true, |
|||
"dependencies": { |
|||
"@babel/parser": "^7.28.4", |
|||
"@vue/shared": "3.5.22", |
|||
"entities": "^4.5.0", |
|||
"estree-walker": "^2.0.2", |
|||
"source-map-js": "^1.2.1" |
|||
} |
|||
}, |
|||
"node_modules/@vue/compiler-dom": { |
|||
"version": "3.5.22", |
|||
"resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.5.22.tgz", |
|||
"integrity": "sha512-W8RknzUM1BLkypvdz10OVsGxnMAuSIZs9Wdx1vzA3mL5fNMN15rhrSCLiTm6blWeACwUwizzPVqGJgOGBEN/hA==", |
|||
"license": "MIT", |
|||
"peer": true, |
|||
"dependencies": { |
|||
"@vue/compiler-core": "3.5.22", |
|||
"@vue/shared": "3.5.22" |
|||
} |
|||
}, |
|||
"node_modules/@vue/compiler-sfc": { |
|||
"version": "3.5.22", |
|||
"resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.5.22.tgz", |
|||
"integrity": "sha512-tbTR1zKGce4Lj+JLzFXDq36K4vcSZbJ1RBu8FxcDv1IGRz//Dh2EBqksyGVypz3kXpshIfWKGOCcqpSbyGWRJQ==", |
|||
"license": "MIT", |
|||
"peer": true, |
|||
"dependencies": { |
|||
"@babel/parser": "^7.28.4", |
|||
"@vue/compiler-core": "3.5.22", |
|||
"@vue/compiler-dom": "3.5.22", |
|||
"@vue/compiler-ssr": "3.5.22", |
|||
"@vue/shared": "3.5.22", |
|||
"estree-walker": "^2.0.2", |
|||
"magic-string": "^0.30.19", |
|||
"postcss": "^8.5.6", |
|||
"source-map-js": "^1.2.1" |
|||
} |
|||
}, |
|||
"node_modules/@vue/compiler-ssr": { |
|||
"version": "3.5.22", |
|||
"resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.5.22.tgz", |
|||
"integrity": "sha512-GdgyLvg4R+7T8Nk2Mlighx7XGxq/fJf9jaVofc3IL0EPesTE86cP/8DD1lT3h1JeZr2ySBvyqKQJgbS54IX1Ww==", |
|||
"license": "MIT", |
|||
"peer": true, |
|||
"dependencies": { |
|||
"@vue/compiler-dom": "3.5.22", |
|||
"@vue/shared": "3.5.22" |
|||
} |
|||
}, |
|||
"node_modules/@vue/devtools-api": { |
|||
"version": "6.6.4", |
|||
"resolved": "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.6.4.tgz", |
|||
"integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==", |
|||
"license": "MIT" |
|||
}, |
|||
"node_modules/@vue/reactivity": { |
|||
"version": "3.5.22", |
|||
"resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.5.22.tgz", |
|||
"integrity": "sha512-f2Wux4v/Z2pqc9+4SmgZC1p73Z53fyD90NFWXiX9AKVnVBEvLFOWCEgJD3GdGnlxPZt01PSlfmLqbLYzY/Fw4A==", |
|||
"license": "MIT", |
|||
"peer": true, |
|||
"dependencies": { |
|||
"@vue/shared": "3.5.22" |
|||
} |
|||
}, |
|||
"node_modules/@vue/runtime-core": { |
|||
"version": "3.5.22", |
|||
"resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.5.22.tgz", |
|||
"integrity": "sha512-EHo4W/eiYeAzRTN5PCextDUZ0dMs9I8mQ2Fy+OkzvRPUYQEyK9yAjbasrMCXbLNhF7P0OUyivLjIy0yc6VrLJQ==", |
|||
"license": "MIT", |
|||
"peer": true, |
|||
"dependencies": { |
|||
"@vue/reactivity": "3.5.22", |
|||
"@vue/shared": "3.5.22" |
|||
} |
|||
}, |
|||
"node_modules/@vue/runtime-dom": { |
|||
"version": "3.5.22", |
|||
"resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.5.22.tgz", |
|||
"integrity": "sha512-Av60jsryAkI023PlN7LsqrfPvwfxOd2yAwtReCjeuugTJTkgrksYJJstg1e12qle0NarkfhfFu1ox2D+cQotww==", |
|||
"license": "MIT", |
|||
"peer": true, |
|||
"dependencies": { |
|||
"@vue/reactivity": "3.5.22", |
|||
"@vue/runtime-core": "3.5.22", |
|||
"@vue/shared": "3.5.22", |
|||
"csstype": "^3.1.3" |
|||
} |
|||
}, |
|||
"node_modules/@vue/server-renderer": { |
|||
"version": "3.5.22", |
|||
"resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.5.22.tgz", |
|||
"integrity": "sha512-gXjo+ao0oHYTSswF+a3KRHZ1WszxIqO7u6XwNHqcqb9JfyIL/pbWrrh/xLv7jeDqla9u+LK7yfZKHih1e1RKAQ==", |
|||
"license": "MIT", |
|||
"peer": true, |
|||
"dependencies": { |
|||
"@vue/compiler-ssr": "3.5.22", |
|||
"@vue/shared": "3.5.22" |
|||
}, |
|||
"peerDependencies": { |
|||
"vue": "3.5.22" |
|||
} |
|||
}, |
|||
"node_modules/@vue/shared": { |
|||
"version": "3.5.22", |
|||
"resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.22.tgz", |
|||
"integrity": "sha512-F4yc6palwq3TT0u+FYf0Ns4Tfl9GRFURDN2gWG7L1ecIaS/4fCIuFOjMTnCyjsu/OK6vaDKLCrGAa+KvvH+h4w==", |
|||
"license": "MIT", |
|||
"peer": true |
|||
}, |
|||
"node_modules/csstype": { |
|||
"version": "3.1.3", |
|||
"resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz", |
|||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", |
|||
"license": "MIT", |
|||
"peer": true |
|||
}, |
|||
"node_modules/entities": { |
|||
"version": "4.5.0", |
|||
"resolved": "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz", |
|||
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", |
|||
"license": "BSD-2-Clause", |
|||
"peer": true, |
|||
"engines": { |
|||
"node": ">=0.12" |
|||
}, |
|||
"funding": { |
|||
"url": "https://github.com/fb55/entities?sponsor=1" |
|||
} |
|||
}, |
|||
"node_modules/estree-walker": { |
|||
"version": "2.0.2", |
|||
"resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz", |
|||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", |
|||
"license": "MIT", |
|||
"peer": true |
|||
}, |
|||
"node_modules/magic-string": { |
|||
"version": "0.30.19", |
|||
"resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.19.tgz", |
|||
"integrity": "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==", |
|||
"license": "MIT", |
|||
"peer": true, |
|||
"dependencies": { |
|||
"@jridgewell/sourcemap-codec": "^1.5.5" |
|||
} |
|||
}, |
|||
"node_modules/nanoid": { |
|||
"version": "3.3.11", |
|||
"resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.11.tgz", |
|||
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", |
|||
"funding": [ |
|||
{ |
|||
"type": "github", |
|||
"url": "https://github.com/sponsors/ai" |
|||
} |
|||
], |
|||
"license": "MIT", |
|||
"peer": true, |
|||
"bin": { |
|||
"nanoid": "bin/nanoid.cjs" |
|||
}, |
|||
"engines": { |
|||
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" |
|||
} |
|||
}, |
|||
"node_modules/picocolors": { |
|||
"version": "1.1.1", |
|||
"resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz", |
|||
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", |
|||
"license": "ISC", |
|||
"peer": true |
|||
}, |
|||
"node_modules/postcss": { |
|||
"version": "8.5.6", |
|||
"resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.5.6.tgz", |
|||
"integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", |
|||
"funding": [ |
|||
{ |
|||
"type": "opencollective", |
|||
"url": "https://opencollective.com/postcss/" |
|||
}, |
|||
{ |
|||
"type": "tidelift", |
|||
"url": "https://tidelift.com/funding/github/npm/postcss" |
|||
}, |
|||
{ |
|||
"type": "github", |
|||
"url": "https://github.com/sponsors/ai" |
|||
} |
|||
], |
|||
"license": "MIT", |
|||
"peer": true, |
|||
"dependencies": { |
|||
"nanoid": "^3.3.11", |
|||
"picocolors": "^1.1.1", |
|||
"source-map-js": "^1.2.1" |
|||
}, |
|||
"engines": { |
|||
"node": "^10 || ^12 || >=14" |
|||
} |
|||
}, |
|||
"node_modules/source-map-js": { |
|||
"version": "1.2.1", |
|||
"resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz", |
|||
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", |
|||
"license": "BSD-3-Clause", |
|||
"engines": { |
|||
"node": ">=0.10.0" |
|||
} |
|||
}, |
|||
"node_modules/vue": { |
|||
"version": "3.5.22", |
|||
"resolved": "https://registry.npmmirror.com/vue/-/vue-3.5.22.tgz", |
|||
"integrity": "sha512-toaZjQ3a/G/mYaLSbV+QsQhIdMo9x5rrqIpYRObsJ6T/J+RyCSFwN2LHNVH9v8uIcljDNa3QzPVdv3Y6b9hAJQ==", |
|||
"license": "MIT", |
|||
"peer": true, |
|||
"dependencies": { |
|||
"@vue/compiler-dom": "3.5.22", |
|||
"@vue/compiler-sfc": "3.5.22", |
|||
"@vue/runtime-dom": "3.5.22", |
|||
"@vue/server-renderer": "3.5.22", |
|||
"@vue/shared": "3.5.22" |
|||
}, |
|||
"peerDependencies": { |
|||
"typescript": "*" |
|||
}, |
|||
"peerDependenciesMeta": { |
|||
"typescript": { |
|||
"optional": true |
|||
} |
|||
} |
|||
}, |
|||
"node_modules/vue-i18n": { |
|||
"version": "9.14.5", |
|||
"resolved": "https://registry.npmmirror.com/vue-i18n/-/vue-i18n-9.14.5.tgz", |
|||
"integrity": "sha512-0jQ9Em3ymWngyiIkj0+c/k7WgaPO+TNzjKSNq9BvBQaKJECqn9cd9fL4tkDhB5G1QBskGl9YxxbDAhgbFtpe2g==", |
|||
"license": "MIT", |
|||
"dependencies": { |
|||
"@intlify/core-base": "9.14.5", |
|||
"@intlify/shared": "9.14.5", |
|||
"@vue/devtools-api": "^6.5.0" |
|||
}, |
|||
"engines": { |
|||
"node": ">= 16" |
|||
}, |
|||
"funding": { |
|||
"url": "https://github.com/sponsors/kazupon" |
|||
}, |
|||
"peerDependencies": { |
|||
"vue": "^3.0.0" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,5 @@ |
|||
{ |
|||
"dependencies": { |
|||
"vue-i18n": "^9.14.5" |
|||
} |
|||
} |
|||
@ -1,28 +1,731 @@ |
|||
<template> |
|||
<view class="main"> |
|||
<!-- 顶部状态栏占位 --> |
|||
<view class="top" :style="{height:iSMT+'px'}"></view> |
|||
<view>行情</view> |
|||
<view class="top" :style="{ height: iSMT + 'px' }"></view> |
|||
|
|||
<!-- 固定头部 --> |
|||
<view class="header_fixed" :style="{ top: iSMT + 'px' }"> |
|||
<view class="header_content"> |
|||
<view class="header_input_wrapper"> |
|||
<image class="search_icon" src="/static/marketSituation-image/search.png" mode="" @click="onSearchClick"></image> |
|||
<input class="header_input" type="text" placeholder="搜索" |
|||
placeholder-style="color: #A6A6A6; font-size: 22rpx;" v-model="searchValue" |
|||
@input="onSearchInput" @confirm="onSearchConfirm" /> |
|||
</view> |
|||
<view class="header_icons"> |
|||
<view class="header_icon" @click="selected"> |
|||
<image src="/static/marketSituation-image/mySeclected.png" mode=""></image> |
|||
</view> |
|||
<view class="header_icon" @click="history"> |
|||
<image src="/static/marketSituation-image/history.png" mode=""></image> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="channel_li" v-if="channelData.length > 0"> |
|||
<scroll-view class="channel_wrap" scroll-x="true" :scroll-into-view="scrollToView" |
|||
:scroll-with-animation="true" show-scrollbar="false"> |
|||
<view class="channel_innerWrap"> |
|||
<view v-for="(item, index) in channelData" :key="item.id" :id="'nav' + item.id" |
|||
:class="['channel_item', index === pageIndex ? 'active' : '']" @click="navClick(index)"> |
|||
<text class="channel_text">{{ item.title }}</text> |
|||
<view v-if="index === pageIndex" class="active_indicator"></view> |
|||
</view> |
|||
</view> |
|||
</scroll-view> |
|||
<view class="scroll_indicator" @click="channel_more"> |
|||
<image src="/static/marketSituation-image/menu.png" mode="aspectFit"></image> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 可滚动内容区域 --> |
|||
<scroll-view class="content_scroll" scroll-y="true" :style="{ top: (iSMT + 136) + 'px' }"> |
|||
<view class="content"> |
|||
<view class="map"> |
|||
<image src="/static/marketSituation-image/map.png" mode="aspectFill"></image> |
|||
</view> |
|||
<view class="global_index"> |
|||
<view class="global_index_title"> |
|||
{{ $t('marketSituation.globalIndex') }} |
|||
</view> |
|||
<view class="global_index_more"> |
|||
<text>{{ $t('marketSituation.globalIndexMore') }}</text> |
|||
<image src="/static/marketSituation-image/more.png" mode="aspectFit"></image> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 卡片网格 --> |
|||
<view class="cards_grid"> |
|||
<view v-for="(card, index) in cardData" :key="index" class="card_item"> |
|||
<IndexCard |
|||
:flagIcon="card.flagIcon" |
|||
:indexName="card.indexName" |
|||
:currentPrice="card.currentPrice" |
|||
:changeAmount="card.changeAmount" |
|||
:changePercent="card.changePercent" |
|||
:isRising="card.isRising" |
|||
/> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 底部安全区域,防止被导航栏遮挡 --> |
|||
<view class="bottom_safe_area"></view> |
|||
</view> |
|||
</scroll-view> |
|||
</view> |
|||
|
|||
<footerBar class="static-footer" :type="type"></footerBar> |
|||
|
|||
<!-- 更多tab弹窗 --> |
|||
<view v-if="showCountryModal" class="modal_overlay" @click="closeModal"> |
|||
<view class="modal_content" @click.stop> |
|||
<view class="modal_header"> |
|||
<text class="modal_title">全部栏目</text> |
|||
<view class="modal_close" @click="closeModal"> |
|||
<text>×</text> |
|||
</view> |
|||
</view> |
|||
<view class="modal_body"> |
|||
<view class="country_grid"> |
|||
<view v-for="(country, index) in countryList" :key="index" |
|||
:class="['country_item', selectedCountry === country ? 'selected' : '']" |
|||
@click="selectCountry(country)"> |
|||
<text class="country_text">{{ country }}</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import { ref,onMounted } from 'vue' |
|||
import { ref, onMounted } from 'vue' |
|||
import footerBar from '../../components/footerBar.vue' |
|||
import IndexCard from '../../components/IndexCard.vue' |
|||
|
|||
const type = ref('marketSituation') |
|||
const iSMT = ref(0) |
|||
const searchValue = ref('') |
|||
const contentHeight = ref(0) |
|||
|
|||
// Tab 栏相关数据 |
|||
const channelData = ref([ |
|||
{ id: 1, title: '概况' }, |
|||
{ id: 2, title: '新加坡' }, |
|||
{ id: 3, title: '马来西亚' }, |
|||
{ id: 4, title: '印度尼西亚' }, |
|||
{ id: 5, title: '美国' }, |
|||
{ id: 6, title: '中国香港' }, |
|||
{ id: 7, title: '泰国' }, |
|||
{ id: 8, title: '中国' }, |
|||
{ id: 9, title: '加拿大' }, |
|||
{ id: 10, title: '越南' }, |
|||
{ id: 11, title: '外汇' }, |
|||
{ id: 12, title: '贵金属' }, |
|||
]) |
|||
const pageIndex = ref(0) |
|||
const scrollToView = ref('') |
|||
|
|||
// 弹窗相关数据 |
|||
const showCountryModal = ref(false) |
|||
const selectedCountry = ref('概况') |
|||
const countryList = ref([ |
|||
'概况', '新加坡', '马来西亚', '印度尼西亚', '美国', '中国香港', |
|||
'泰国', '中国', '加拿大', '越南', '外汇', '贵金属' |
|||
]) |
|||
|
|||
// 卡片数据 |
|||
const cardData = ref([ |
|||
{ |
|||
flagIcon: '🇺🇸', |
|||
indexName: '道琼斯', |
|||
currentPrice: '45757.90', |
|||
changeAmount: '-125.22', |
|||
changePercent: '-0.27%', |
|||
isRising: false |
|||
}, |
|||
{ |
|||
flagIcon: '🇺🇸', |
|||
indexName: '纳斯达克', |
|||
currentPrice: '22333.96', |
|||
changeAmount: '+125.22', |
|||
changePercent: '+0.47%', |
|||
isRising: true |
|||
}, |
|||
{ |
|||
flagIcon: '🇺🇸', |
|||
indexName: '标普500', |
|||
currentPrice: '6606.08', |
|||
changeAmount: '+125.22', |
|||
changePercent: '+0.27%', |
|||
isRising: true |
|||
}, |
|||
{ |
|||
flagIcon: '🇨🇳', |
|||
indexName: '上证指数', |
|||
currentPrice: '3333.96', |
|||
changeAmount: '+125.22', |
|||
changePercent: '+0.27%', |
|||
isRising: true |
|||
}, |
|||
{ |
|||
flagIcon: '🇨🇳', |
|||
indexName: '科创50', |
|||
currentPrice: '757.90', |
|||
changeAmount: '-25.22', |
|||
changePercent: '-0.27%', |
|||
isRising: false |
|||
}, |
|||
{ |
|||
flagIcon: '🇭🇰', |
|||
indexName: '恒生指数', |
|||
currentPrice: '19757.90', |
|||
changeAmount: '-125.22', |
|||
changePercent: '-0.63%', |
|||
isRising: false |
|||
}, |
|||
{ |
|||
flagIcon: '🇸🇬', |
|||
indexName: '道琼斯', |
|||
currentPrice: '3757.90', |
|||
changeAmount: '+85.22', |
|||
changePercent: '+2.31%', |
|||
isRising: true |
|||
}, |
|||
{ |
|||
flagIcon: '🇲🇾', |
|||
indexName: '纳斯达克', |
|||
currentPrice: '1657.90', |
|||
changeAmount: '-15.22', |
|||
changePercent: '-0.91%', |
|||
isRising: false |
|||
}, |
|||
{ |
|||
flagIcon: '🇹🇭', |
|||
indexName: '标普500', |
|||
currentPrice: '1457.90', |
|||
changeAmount: '+35.22', |
|||
changePercent: '+2.48%', |
|||
isRising: true |
|||
} |
|||
]) |
|||
|
|||
// 搜索输入事件 |
|||
const onSearchInput = (e) => { |
|||
searchValue.value = e.detail.value |
|||
} |
|||
|
|||
// 搜索确认事件 |
|||
const onSearchConfirm = (e) => { |
|||
console.log('搜索内容:', e.detail.value) |
|||
// 这里可以添加搜索逻辑 |
|||
performSearch(e.detail.value) |
|||
} |
|||
|
|||
// 搜索图标点击事件 |
|||
const onSearchClick = () => { |
|||
if (searchValue.value.trim()) { |
|||
performSearch(searchValue.value) |
|||
} |
|||
} |
|||
|
|||
// 执行搜索 |
|||
const performSearch = (keyword) => { |
|||
if (!keyword.trim()) { |
|||
uni.showToast({ |
|||
title: '请输入搜索内容', |
|||
icon: 'none' |
|||
}) |
|||
return |
|||
} |
|||
|
|||
uni.showToast({ |
|||
title: `搜索: ${keyword}`, |
|||
icon: 'none' |
|||
}) |
|||
// 这里添加实际的搜索逻辑 |
|||
} |
|||
|
|||
// 我的收藏点击事件 |
|||
const selected = () => { |
|||
uni.showToast({ |
|||
title: '我的收藏', |
|||
icon: 'none' |
|||
}) |
|||
// 这里可以跳转到收藏页面 |
|||
} |
|||
|
|||
// 历史记录点击事件 |
|||
const history = () => { |
|||
uni.showToast({ |
|||
title: '历史记录', |
|||
icon: 'none' |
|||
}) |
|||
// 这里可以跳转到历史页面 |
|||
} |
|||
|
|||
// Tab 栏点击事件 |
|||
const navClick = (index) => { |
|||
pageIndex.value = index |
|||
const currentItem = channelData.value[index] |
|||
scrollToView.value = 'nav' + currentItem.id |
|||
|
|||
// 同步更新弹窗中的选中状态 |
|||
selectedCountry.value = currentItem.title |
|||
|
|||
uni.showToast({ |
|||
title: `切换到: ${currentItem.title}`, |
|||
icon: 'none' |
|||
}) |
|||
|
|||
// 这里可以添加切换 tab 后的数据加载逻辑 |
|||
console.log('当前选中的 tab:', currentItem) |
|||
} |
|||
|
|||
// 更多选项点击事件 |
|||
const channel_more = () => { |
|||
showCountryModal.value = true |
|||
} |
|||
|
|||
// 选择国家 |
|||
const selectCountry = (country) => { |
|||
selectedCountry.value = country |
|||
|
|||
// 查找对应的tab索引 |
|||
const targetIndex = channelData.value.findIndex(item => item.title === country) |
|||
|
|||
if (targetIndex !== -1) { |
|||
// 同步更新页面tab |
|||
pageIndex.value = targetIndex |
|||
const currentItem = channelData.value[targetIndex] |
|||
scrollToView.value = 'nav' + currentItem.id |
|||
|
|||
console.log('选中了:' + country + ',同步到tab索引:' + targetIndex) |
|||
uni.showToast({ |
|||
title: '已切换到:' + country, |
|||
icon: 'none', |
|||
duration: 2000 |
|||
}) |
|||
} else { |
|||
// 如果是"概况"或其他特殊选项,默认切换到第一个tab |
|||
if (country === '概况' || country === '全部') { |
|||
pageIndex.value = 0 |
|||
scrollToView.value = 'nav' + channelData.value[0].id |
|||
} |
|||
|
|||
console.log('选中了:' + country) |
|||
uni.showToast({ |
|||
title: '已选择:' + country, |
|||
icon: 'none', |
|||
duration: 2000 |
|||
}) |
|||
} |
|||
|
|||
// 这里可以添加切换到对应国家/地区数据的逻辑 |
|||
// 例如:loadMarketData(country) |
|||
closeModal() |
|||
} |
|||
|
|||
// 关闭弹窗 |
|||
const closeModal = () => { |
|||
showCountryModal.value = false |
|||
} |
|||
|
|||
onMounted(() => { |
|||
// 状态栏高度 |
|||
iSMT.value = uni.getSystemInfoSync().statusBarHeight; |
|||
|
|||
// 计算内容区域高度 |
|||
const systemInfo = uni.getSystemInfoSync() |
|||
const windowHeight = systemInfo.windowHeight |
|||
const statusBarHeight = systemInfo.statusBarHeight || 0 |
|||
const headerHeight = 160 // header大约高度,包括搜索栏和tab栏 |
|||
const footerHeight = 100 // 底部导航栏高度 |
|||
|
|||
contentHeight.value = windowHeight - statusBarHeight - headerHeight - footerHeight |
|||
|
|||
// 初始化 tab 栏 |
|||
if (channelData.value.length > 0) { |
|||
pageIndex.value = 0 |
|||
scrollToView.value = 'nav' + channelData.value[0].id |
|||
} |
|||
}) |
|||
</script> |
|||
|
|||
<style scoped> |
|||
/* 状态栏占位 */ |
|||
.top { |
|||
position: fixed; |
|||
top: 0; |
|||
left: 0; |
|||
right: 0; |
|||
z-index: 1001; |
|||
background-color: #ffffff; |
|||
} |
|||
|
|||
/* 固定头部样式 */ |
|||
.header_fixed { |
|||
position: fixed; |
|||
left: 0; |
|||
right: 0; |
|||
z-index: 1000; |
|||
background-color: #ffffff; |
|||
padding: 20rpx 0 0 0; |
|||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1); |
|||
} |
|||
|
|||
/* 可滚动内容区域 */ |
|||
.content_scroll { |
|||
position: fixed; |
|||
left: 0; |
|||
right: 0; |
|||
bottom: 100rpx; /* 底部导航栏高度 */ |
|||
overflow-y: auto; |
|||
} |
|||
|
|||
.header_content { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
height: 80rpx; |
|||
padding: 0 20rpx; |
|||
margin-bottom: 10rpx; |
|||
} |
|||
|
|||
.header_input_wrapper { |
|||
display: flex; |
|||
align-items: center; |
|||
width: 100%; |
|||
margin: 0 20rpx 0 0; |
|||
height: 70rpx; |
|||
border-radius: 35rpx; |
|||
background-color: #ffffff; |
|||
border: 1rpx solid #e9ecef; |
|||
padding: 0 80rpx 0 30rpx; |
|||
font-size: 28rpx; |
|||
color: #5c5c5c; |
|||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1); |
|||
} |
|||
|
|||
.search_icon { |
|||
width: 40rpx; |
|||
height: 40rpx; |
|||
opacity: 0.6; |
|||
} |
|||
|
|||
.header_input { |
|||
margin-left: 10rpx; |
|||
} |
|||
|
|||
.header_icons { |
|||
display: flex; |
|||
align-items: center; |
|||
gap: 15rpx; |
|||
} |
|||
|
|||
.header_icon { |
|||
width: 40rpx; |
|||
height: 40rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
} |
|||
|
|||
.header_icon image { |
|||
width: 40rpx; |
|||
height: 40rpx; |
|||
} |
|||
|
|||
/* Tab 栏样式 */ |
|||
.channel_li { |
|||
display: flex; |
|||
align-items: center; |
|||
height: 80rpx; |
|||
background-color: #ffffff; |
|||
border-bottom: 1rpx solid #f0f0f0; |
|||
} |
|||
|
|||
.channel_wrap { |
|||
width: calc(100% - 60rpx); |
|||
height: 100%; |
|||
overflow: hidden; |
|||
flex-shrink: 0; |
|||
} |
|||
|
|||
.channel_innerWrap { |
|||
display: flex; |
|||
align-items: center; |
|||
height: 100%; |
|||
padding: 0 20rpx; |
|||
white-space: nowrap; |
|||
} |
|||
|
|||
.channel_item { |
|||
position: relative; |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
justify-content: center; |
|||
height: 60rpx; |
|||
padding: 0 20rpx; |
|||
border-radius: 30rpx; |
|||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); |
|||
cursor: pointer; |
|||
white-space: nowrap; |
|||
flex-shrink: 0; |
|||
} |
|||
|
|||
.channel_item:active { |
|||
transform: scale(0.98); |
|||
} |
|||
|
|||
.channel_item.active { |
|||
color: #333; |
|||
font-weight: bold; |
|||
} |
|||
|
|||
.channel_text { |
|||
font-size: 28rpx; |
|||
font-weight: 500; |
|||
color: #666666; |
|||
transition: color 0.3s ease; |
|||
white-space: nowrap; |
|||
} |
|||
|
|||
.channel_item.active .channel_text { |
|||
color: #333333; |
|||
font-weight: 400; |
|||
z-index: 2; |
|||
} |
|||
|
|||
.active_indicator { |
|||
position: absolute; |
|||
left: 50%; |
|||
top: 60%; |
|||
transform: translateX(-45%); |
|||
width: calc(100% - 20rpx); |
|||
min-width: 40rpx; |
|||
max-width: 120rpx; |
|||
height: 8rpx; |
|||
background-image: url('/static/marketSituation-image/bg.png'); |
|||
background-size: cover; |
|||
background-position: center; |
|||
background-repeat: no-repeat; |
|||
animation: slideIn 0.1s ease; |
|||
border-radius: 8rpx; |
|||
z-index: 1; |
|||
} |
|||
|
|||
@keyframes slideIn { |
|||
from { |
|||
width: 0; |
|||
opacity: 0; |
|||
} |
|||
|
|||
to { |
|||
width: 40rpx; |
|||
opacity: 1; |
|||
} |
|||
} |
|||
|
|||
.scroll_indicator { |
|||
border-left: 1rpx solid #b6b6b6; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
width: 60rpx; |
|||
height: 30rpx; |
|||
background-color: #ffffff; |
|||
flex-shrink: 0; |
|||
} |
|||
|
|||
.scroll_indicator image { |
|||
width: 20rpx; |
|||
height: 20rpx; |
|||
opacity: 0.5; |
|||
} |
|||
|
|||
.content { |
|||
margin-top: 20rpx; |
|||
background-color: white; |
|||
} |
|||
|
|||
.map { |
|||
flex: 1; |
|||
width: calc(100% - 60rpx); |
|||
min-height: 450rpx; |
|||
margin: 0 30rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
background-color: #F3F3F3; |
|||
border-radius: 30rpx; |
|||
border: 1rpx solid #E0E0E0; |
|||
} |
|||
|
|||
.map image { |
|||
width: 90%; |
|||
height: 400rpx; |
|||
object-fit: contain; |
|||
} |
|||
|
|||
.static-footer { |
|||
position: fixed; |
|||
bottom: 0; |
|||
} |
|||
|
|||
/* 弹窗样式 */ |
|||
.modal_overlay { |
|||
position: fixed; |
|||
top: 0; |
|||
left: 0; |
|||
right: 0; |
|||
bottom: 0; |
|||
background-color: rgba(0, 0, 0, 0.5); |
|||
display: flex; |
|||
align-items: flex-end; |
|||
z-index: 1000; |
|||
} |
|||
|
|||
.modal_content { |
|||
width: 100%; |
|||
background-color: #fff; |
|||
border-radius: 20rpx 20rpx 0 0; |
|||
max-height: 80vh; |
|||
overflow: hidden; |
|||
} |
|||
|
|||
.modal_header { |
|||
position: relative; |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
padding: 30rpx 40rpx; |
|||
border-bottom: 1rpx solid #f0f0f0; |
|||
} |
|||
|
|||
.modal_title { |
|||
font-size: 32rpx; |
|||
font-weight: bold; |
|||
color: #333333; |
|||
text-align: center; |
|||
} |
|||
|
|||
.modal_close { |
|||
position: absolute; |
|||
right: 40rpx; |
|||
top: 50%; |
|||
transform: translateY(-50%); |
|||
width: 60rpx; |
|||
height: 60rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
font-size: 40rpx; |
|||
color: #999; |
|||
} |
|||
|
|||
.modal_body { |
|||
padding: 40rpx; |
|||
} |
|||
|
|||
.country_grid { |
|||
display: grid; |
|||
grid-template-columns: 1fr 1fr; |
|||
gap: 20rpx; |
|||
} |
|||
|
|||
.country_item { |
|||
padding: 24rpx 30rpx; |
|||
border-radius: 12rpx; |
|||
background-color: #f8f8f8; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
transition: all 0.3s ease; |
|||
} |
|||
|
|||
.country_item.selected { |
|||
background-color: #ff4444; |
|||
color: #fff; |
|||
} |
|||
|
|||
.country_text { |
|||
font-size: 28rpx; |
|||
color: #333; |
|||
} |
|||
|
|||
.country_item.selected .country_text { |
|||
color: #fff; |
|||
} |
|||
|
|||
.global_index{ |
|||
margin: 30rpx 20rpx 0 20rpx; |
|||
display: flex; |
|||
justify-content: space-between; |
|||
} |
|||
.global_index_title{ |
|||
margin-left: 20rpx; |
|||
font-size: 40rpx; |
|||
font-weight: 100; |
|||
color: #333333; |
|||
align-items: center; |
|||
} |
|||
.global_index_more{ |
|||
display: flex; |
|||
gap: 10rpx; |
|||
font-size: 28rpx; |
|||
color: #333333; |
|||
align-items: center; |
|||
} |
|||
.global_index_more image{ |
|||
width: 40rpx; |
|||
height: 40rpx; |
|||
align-items: center; |
|||
} |
|||
|
|||
/* 卡片网格样式 */ |
|||
.cards_grid { |
|||
display: grid; |
|||
grid-template-columns: repeat(3, 1fr); |
|||
margin: 0; |
|||
box-sizing: border-box; |
|||
width: 100%; |
|||
} |
|||
|
|||
.card_item { |
|||
width: 100%; |
|||
box-sizing: border-box; |
|||
min-width: 0; /* 防止内容溢出 */ |
|||
} |
|||
|
|||
/* 响应式布局 - 小屏幕时改为两列 */ |
|||
@media (max-width: 600rpx) { |
|||
.cards_grid { |
|||
grid-template-columns: repeat(2, 1fr); |
|||
padding: 30rpx 20rpx; |
|||
} |
|||
} |
|||
|
|||
/* 超小屏幕时改为单列 */ |
|||
@media (max-width: 400rpx) { |
|||
.cards_grid { |
|||
grid-template-columns: 1fr; |
|||
padding: 30rpx 20rpx; |
|||
} |
|||
} |
|||
|
|||
/* 底部安全区域 */ |
|||
.bottom_safe_area { |
|||
height: 40rpx; |
|||
background-color: transparent; |
|||
} |
|||
|
|||
/* 主容器样式调整 */ |
|||
.main { |
|||
position: relative; |
|||
height: 100vh; |
|||
overflow: hidden; |
|||
background-color: white; |
|||
} |
|||
</style> |
|||
|
After Width: 82 | Height: 24 | Size: 3.0 KiB |
|
After Width: 36 | Height: 33 | Size: 2.0 KiB |
|
After Width: 623 | Height: 400 | Size: 113 KiB |
|
After Width: 60 | Height: 60 | Size: 238 B |
|
After Width: 18 | Height: 32 | Size: 437 B |
|
After Width: 32 | Height: 32 | Size: 1.8 KiB |
|
After Width: 60 | Height: 60 | Size: 867 B |
|
After Width: 30 | Height: 30 | Size: 1.5 KiB |