2025/2/8第一次更新

This commit is contained in:
爱吃咸鱼小猫咪
2025-02-08 18:50:38 +08:00
commit d7af560866
26519 changed files with 5046029 additions and 0 deletions
@@ -0,0 +1,92 @@
import { computed, toRef } from 'vue'
import { formatDomSizeValue, isEmpty } from '../../../../utils'
import { useNamespace } from '../../../../hooks/use-namespace'
import { useComponentColor } from '../../../../hooks/use-component-color'
import { useComponentSize } from '../../../../hooks/use-component-size'
import type { CSSProperties } from 'vue'
import type { IconProps } from '../icon'
export const useIcon = (props: IconProps) => {
const ns = useNamespace('icon')
// 解析图标颜色
const [colorClass, colorStyle] = useComponentColor(
toRef(props, 'color'),
'text'
)
// 解析透明图标背景
const [transparentBgClass] = useComponentColor(
toRef(props, 'transparentBg'),
'bg'
)
// 解析图标尺寸
const { sizeType } = useComponentSize(props.size)
// 判断是图片还是图鸟内置的图标
const isImg = computed<boolean>(
() => !!props?.name && props.name.includes('/')
)
// 图标对应的类名
const iconClass = computed<string>(() => {
const cls: string[] = []
cls.push(ns.b())
// 判断图标是否是图片
if (isImg.value) {
cls.push(ns.m('image'))
} else {
// 设置图标颜色类型
if (props.type) cls.push(`tn-type-${props.type}_text`)
// 判断是否设置透明图标背景
if (props.transparent) {
cls.push('tn-text-transparent', transparentBgClass.value)
} else {
// 设置图标颜色
if (colorClass.value) cls.push(colorClass.value)
}
// 设置图标加粗
if (props.bold) cls.push('tn-text-bold')
}
// 设置图标尺寸
if (sizeType.value === 'inner') cls.push(ns.m(props.size as string))
if (props.customClass) cls.push(props.customClass)
return cls.join(' ')
})
// 图标对应的样式
const iconStyle = computed<CSSProperties>(() => {
const style: CSSProperties = {}
// 判断图标是否是图片
if (isImg.value) {
// 如果设置了size,则设置图片的宽高
if (sizeType.value === 'custom' && props.size) {
style.width = style.height = formatDomSizeValue(props.size)
}
} else {
// 设置图标颜色
if (colorStyle.value) style.color = colorStyle.value
// 设置图标大小
if (sizeType.value === 'custom' && props.size)
style.fontSize = formatDomSizeValue(props.size)
}
// 设置垂直方向上的偏移量
if (props.offsetTop)
style.transform = `translateY(${formatDomSizeValue(props.offsetTop)})`
if (!isEmpty(props.customStyle)) Object.assign(style, props.customStyle)
return style
})
return {
isImg,
iconClass,
iconStyle,
}
}
@@ -0,0 +1 @@
export * from './icon-custom'
+76
View File
@@ -0,0 +1,76 @@
import { buildProps, iconPropType } from '../../../utils'
import { componentImgModes, componentTypes } from '../../../constants'
import { useComponentCustomStyleProp } from '../../base/composables/use-component-common-props'
import type { ExtractPropTypes } from 'vue'
export const iconProps = buildProps({
/**
* @description 图标名称,支持图鸟内置图标和图片地址(只支持绝对路径)
*/
name: {
type: iconPropType,
required: true,
},
/**
* @description 图标颜色类型
*/
type: {
type: String,
values: componentTypes,
default: '',
},
/**
* @description 图标颜色, 以tn开头则使用图鸟内置的颜色
*/
color: String,
/**
* @description 图标大小
*/
size: {
type: [String, Number],
},
/**
* @description 图标加粗
*/
bold: Boolean,
/**
* @description 图标是否为透明
*/
transparent: Boolean,
/**
* @description 透明图标背景
*/
transparentBg: String,
/**
* @description 图片模式,当name为图片地址时生效
*/
imgMode: {
type: String,
values: componentImgModes,
default: 'aspectFill',
},
/**
* @description 垂直方向上的偏移量
*/
offsetTop: {
type: [String, Number],
},
/**
* @description 自定义样式
*/
customStyle: useComponentCustomStyleProp,
/**
* @description 自定义类
*/
customClass: String,
})
export const iconEmits = {
/**
* @description 点击图标时触发
*/
click: () => true,
}
export type IconProps = ExtractPropTypes<typeof iconProps>
export type IconEmits = typeof iconEmits
+45
View File
@@ -0,0 +1,45 @@
<script lang="ts" setup>
import { iconEmits, iconProps } from './icon'
import { useIcon } from './composables'
// 依赖tn-icon样式(由于uniapp在小程序端支持svg有点问题,所以这里还是使用iconfont)
// #ifdef APP-PLUS
import '@tuniao/tn-icon/dist/https/index.css'
// #endif
// #ifndef APP-PLUS
import '@tuniao/tn-icon/dist/index.css'
// #endif
const props = defineProps(iconProps)
const emits = defineEmits(iconEmits)
const { isImg, iconClass, iconStyle } = useIcon(props)
// 图标点击事件
const handleClick = () => {
emits('click')
}
</script>
// #ifdef MP-WEIXIN
<script lang="ts">
export default {
options: {
// 在微信小程序中将组件节点渲染为虚拟节点,更加接近Vue组件的表现(不会出现shadow节点下再去创建元素)
virtualHost: true,
},
}
</script>
// #endif
<template>
<view :class="[iconClass]" :style="iconStyle" @tap="handleClick">
<!-- 图片图标 -->
<image v-if="isImg" class="image" :src="name" :mode="imgMode" />
<!-- 正常图标 -->
<text v-else :class="['icon', `tn-icon-${name}`]" />
</view>
</template>
<style lang="scss" scoped>
@import '../../../theme-chalk/src/icon.scss';
</style>
@@ -0,0 +1,3 @@
import type Icon from './icon.vue'
export type IconInstance = InstanceType<typeof Icon>