| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- <template>
- <view class="menu-grid">
- <view
- v-for="m in menus"
- :key="m.id"
- class="menu-card"
- :class="{ 'menu-card--text-only': !m.icon }"
- @click="$emit('select', m)"
- >
- <view
- v-if="m.icon"
- class="menu-icon"
- :class="[toneClass(m), plainClass(m)]"
- :style="iconBoxStyle(m)"
- >
- <VanIcon :name="m.icon" :color="iconFg(m)" :size="iconSize(m)" />
- <text v-if="badgeText(m)" class="menu-badge">{{ badgeText(m) }}</text>
- </view>
- <text
- v-if="showGroupTitle && m.groupTitle"
- class="menu-group-title"
- >{{ m.groupTitle }}</text>
- <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'
- import { formatOaBadgeCount } from '../utils/oa-badge.js'
- export default {
- name: 'MenuGrid',
- components: { VanIcon },
- props: {
- menus: { type: Array, default: () => [] },
- /** 分区标题栏展示区域名时,卡片内不再重复 groupTitle 胶囊 */
- showGroupTitle: { type: Boolean, default: true }
- },
- emits: ['select'],
- methods: {
- badgeText(m) {
- if (!m) return ''
- if (m.badge != null && String(m.badge).trim() !== '' && String(m.badge).trim() !== '0') {
- if (typeof m.badge === 'number') return formatOaBadgeCount(m.badge)
- return String(m.badge).trim()
- }
- return formatOaBadgeCount(m.badgeCount)
- },
- 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>
|