Files
zkxw/mobile-h5/components/MenuGrid.vue
T
2026-08-12 15:48:15 +08:00

66 lines
1.7 KiB
Vue

<template>
<view class="menu-grid">
<view
v-for="m in menus"
:key="m.id"
class="menu-card"
@click="$emit('select', m)"
>
<view
class="menu-icon"
:class="[toneClass(m), plainClass(m)]"
:style="iconBoxStyle(m)"
>
<VanIcon :name="m.icon" :color="iconFg(m)" :size="iconSize(m)" />
</view>
<text class="menu-title">{{ m.title }}</text>
</view>
</view>
</template>
<script>
import VanIcon from './van-icon/van-icon.vue'
import { resolveMenuIconColors } from '../utils/menu-icon-colors.js'
export default {
name: 'MenuGrid',
components: { VanIcon },
props: {
menus: { type: Array, default: () => [] }
},
emits: ['select'],
methods: {
colors(m) {
return resolveMenuIconColors(m)
},
iconFg(m) {
return this.colors(m).iconFg || ''
},
isPlainIcon(m) {
const bg = String(this.colors(m).iconBg || '').trim().toLowerCase()
return bg === 'transparent' || bg === 'none'
},
plainClass(m) {
return this.isPlainIcon(m) ? 'menu-icon--plain' : ''
},
iconSize(m) {
return this.isPlainIcon(m) ? '56rpx' : '52rpx'
},
iconBoxStyle(m) {
const { iconBg, iconFg } = this.colors(m)
const style = {}
if (iconBg) style.background = iconBg
if (this.isPlainIcon(m)) style.boxShadow = 'none'
if (iconFg) style.color = iconFg
return style
},
/** 有自定义色时不再套 tone-*,避免绿底覆盖 */
toneClass(m) {
const { iconBg, iconFg } = this.colors(m)
if (iconBg || iconFg) return ''
return m.tone || ''
}
}
}
</script>