110 lines
2.6 KiB
Vue
110 lines
2.6 KiB
Vue
<template>
|
||
<!--
|
||
微信小程序真机:
|
||
- CSS mask-image + 本地 SVG 常失效
|
||
- <image> 对 SVG / svg+xml data-URI 也常失效
|
||
故精致图标用本地 PNG;尺寸必须写死 px/rpx(勿用 em,自定义组件内 em 易为 0)
|
||
-->
|
||
<image
|
||
v-if="src"
|
||
class="v-icon v-icon--img"
|
||
:src="src"
|
||
:style="imgStyle"
|
||
mode="aspectFit"
|
||
/>
|
||
<text v-else class="v-icon" :style="iconStyle">{{ glyph }}</text>
|
||
</template>
|
||
|
||
<script>
|
||
/** H5 兼容:替代 @vant/weapp van-icon(weapp 组件无法在 Vite H5 下 ESM 导入) */
|
||
const GLYPHS = {
|
||
'todo-list-o': '☰',
|
||
'orders-o': '▤',
|
||
'balance-list-o': '¥',
|
||
logistics: '🚚',
|
||
certificate: '✓',
|
||
'cluster-o': '◈',
|
||
'send-gift-o': '↗',
|
||
'apps-o': '▦',
|
||
passed: '✓',
|
||
'warning-o': '!',
|
||
plus: '+',
|
||
'add-o': '+',
|
||
edit: '✎',
|
||
arrow: '›',
|
||
'eye-o': '◎',
|
||
down: '↓',
|
||
checked: '✓',
|
||
search: '⌕',
|
||
clear: '×',
|
||
'manager-o': '☺',
|
||
'clock-o': '◷',
|
||
description: '📄',
|
||
'photo-o': '▣',
|
||
'video-o': '▶',
|
||
'music-o': '♪',
|
||
'bag-o': '▣',
|
||
records: '☰'
|
||
}
|
||
|
||
/** 本地位图(小程序 <image> 真机可靠);颜色已烘焙在 PNG 内 */
|
||
const PNG_ICONS = {
|
||
approve: '/static/menu-icons/start-approval.png',
|
||
'oa-drafts': '/static/menu-icons/oa-drafts.png',
|
||
'oa-pending': '/static/menu-icons/oa-pending.png',
|
||
'oa-done': '/static/menu-icons/oa-done.png',
|
||
'oa-mine': '/static/menu-icons/oa-mine.png',
|
||
'oa-cc': '/static/menu-icons/oa-cc.png'
|
||
}
|
||
|
||
export default {
|
||
name: 'VanIconShim',
|
||
props: {
|
||
name: { type: String, default: '' },
|
||
size: { type: [String, Number], default: '' },
|
||
color: { type: String, default: '' }
|
||
},
|
||
computed: {
|
||
src() {
|
||
return PNG_ICONS[this.name] || ''
|
||
},
|
||
glyph() {
|
||
return GLYPHS[this.name] || '●'
|
||
},
|
||
dim() {
|
||
if (!this.size) return ''
|
||
const s = String(this.size)
|
||
return /px|rpx|em|rem|%$/.test(s) ? s : `${s}px`
|
||
},
|
||
iconStyle() {
|
||
const style = {}
|
||
if (this.dim) style.fontSize = this.dim
|
||
if (this.color) style.color = this.color
|
||
return style
|
||
},
|
||
imgStyle() {
|
||
// 默认 52rpx:对齐首页宫格;勿回退到 em
|
||
const d = this.dim || '52rpx'
|
||
return { width: d, height: d }
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.v-icon {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
line-height: 1;
|
||
font-style: normal;
|
||
}
|
||
|
||
.v-icon--img {
|
||
width: 52rpx;
|
||
height: 52rpx;
|
||
flex-shrink: 0;
|
||
display: block;
|
||
}
|
||
</style>
|