66 lines
1.7 KiB
Vue
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>
|