|
|
- <template>
- <text class="l-icon" :class="[classes]" :style="[styles, lStyle]" v-if="!isImage && !isIconify && !isSVG" @click="$emit('click')">{{iconCode}}</text>
- <image class="l-icon" :class="[classes]" :style="[styles, lStyle]" v-else-if="(!isSVG && !isIconify) && isImage" :src="iconUrl" @click="$emit('click')"></image>
- <l-svg class="l-icon" :class="[classes]" :style="[styles, lStyle]" v-else :web="web" :color="color" :src="iconUrl" @error="imageError" @load="imageLoad" @click="$emit('click')"></l-svg>
- </template>
- <script lang="ts">
- // @ts-nocheck
- /**
- * LimeIcon 图标
- * @description ICON集
- * @tutorial https://ext.dcloud.net.cn/plugin?id=14057
- * @property {String} name 图标名称
- * @property {String} color 颜色
- * @property {String} size 尺寸
- * @property {String} prefix 字体图标前缀
- * @property {Boolean} inherit 是否继承颜色
- * @property {Boolean} web 原生 app(nvue,uvue) 是否使用web渲染
- * @event {Function} click 点击事件
- */
- // @ts-nocheck
- import { computed, defineComponent, ref, inject } from '@/uni_modules/lime-shared/vue';
- import icons from '../../static/icons.json';
- import { addUnit } from '@/uni_modules/lime-shared/addUnit';
-
- import { isObject } from '@/uni_modules/lime-shared/isObject';
- import IconProps from './props';
-
- // #ifdef VUE2 && MP
- import { getClassStr } from '@/uni_modules/lime-shared/getClassStr';
- // #endif
-
- // #ifdef APP-NVUE
- import iconSrc from '@/uni_modules/lime-icon/hybrid/html/t3.ttf';
- var domModule = weex.requireModule('dom');
- domModule.addRule('fontFace', {
- 'fontFamily': "uniicons",
- 'src': "url('" + iconSrc + "')"
- });
- // #endif
-
- const name = 'l-icon';
- export default defineComponent({
- name,
- externalClasses: ['l-class'],
- options: {
- addGlobalClass: true,
- virtualHost: true,
- },
- props: IconProps,
- emits: ['click'],
- setup(props, { emit }) {
- const $iconCollection = inject('$iconCollection', null)
- const { $limeIconsHost: $iconsHost } = uni as any
- const IconifyURL = 'https://api.iconify.design/'
- // const isAPP = uni.getSystemInfoSync().uniPlatform == 'app'
- const hasHost = computed(() => `${props.name}`.indexOf('/') !== -1);
- const isIconify = computed(() => !hasHost.value && `${props.name}`.includes(':'))
- const collectionIcon = computed(() => isObject($iconCollection) && $iconCollection.icons[props.name])
- const isImage = computed<boolean>(() : boolean => {
- return /\.(jpe?g|png|gif|bmp|webp|tiff?)$/i.test(props.name) || /^data:image\/(jpeg|png|gif|bmp|webp|tiff);base64,/.test(props.name)
- })
- const isSVG = computed<boolean>(() : boolean => {
- return /\.svg$/i.test(props.name) || props.name.startsWith('data:image/svg+xml') || props.name.startsWith('<svg')
- })
- const classes = computed(() => {
- const { prefix } = props
- const iconPrefix = prefix || name
- const iconName = `${iconPrefix}-${props.name}`
- const isFont = !isImage.value && !isIconify.value && !isSVG.value
- const isImages = isImage.value || isIconify.value || isSVG.value
- const cls = {
- [iconPrefix]: !isImages && prefix,
- [iconName]: !isImages,
- [`${name}--image`]: isImages,
- [`${name}--font`]: isFont,
- // [`is-inherit`]: isIconify.value && (props.color || props.inherit)
- }
-
- // #ifdef VUE2 && MP
- return getClassStr(cls)
- // #endif
-
- return cls
- })
- const iconCode = computed(() => {
- const isImages = isImage.value || isIconify.value || isSVG.value
- return (!isImages && icons[props.name]) || ''
- })
- const isError = ref(false)
- const cacheMap = new Map<string, string>()
- const iconUrl = computed(() => {
- const hasIconsHost = $iconsHost != null && $iconsHost != ''
- // const hasIconCollection = $iconCollectiont != null
- if (isImage.value) {
- return hasHost.value ? props.name : ($iconsHost ?? '') + props.name
- } else if (isIconify.value) {
- // 防止重绘
- if(cacheMap.has(props.name) && !isError.value) {
- return cacheMap.get(props.name)!
- }
- // 如果存在collectionIcon则使用
- // 如果设置的路径加载失败 就使用网络地址 就使用iconify api
- // !isError.value &&
- const _host = `${hasIconsHost ? $iconsHost : IconifyURL}`
- const _icon = collectionIcon.value || _host + `${props.name}.svg`.replace(/:/g, '/')
- cacheMap.set(props.name, _icon)
- return _icon
- } else if (isSVG.value) {
- return (/\.svg$/i.test(props.name) && hasIconsHost && !hasHost.value ? $iconsHost : '') + props.name.replace(/'/g, '"')
- } else {
- return null
- }
- })
- const styles = computed(() => {
- const style : Record<string, any> = {
- 'color': props.color,
- }
- if (typeof props.size == 'number' || props.size) {
- style['font-size'] = addUnit(props.size)
- }
- //#ifdef VUE2
- // VUE2小程序最后一个值莫名的出现undefined
- style['undefined'] = ''
- // #endif
- return style
- })
- const imageLoad = () => {
- isError.value = false
- }
- const imageError = () => {
- isError.value = true
- }
-
- return {
- iconCode,
- classes,
- styles,
- isImage,
- isSVG,
- isIconify,
- iconUrl,
- imageLoad,
- imageError
- }
- }
- })
- </script>
- <style lang="scss">
- @import './index.scss';
- </style>
|