ivue-material-plus
Version:
A high quality UI components Library with Vue.js
1 lines • 7.16 kB
Source Map (JSON)
{"version":3,"file":"index2.mjs","sources":["../../../../../src/components/ivue-avatar/index.vue"],"sourcesContent":["<template>\r\n <span :class=\"wrapperClasses\" :style=\"wrapperStyles\" ref=\"wrapper\">\r\n <!-- 图片 -->\r\n <slot name=\"img\">\r\n <img\r\n :class=\"`${prefixCls}-img`\"\r\n v-if=\"src\"\r\n :src=\"src\"\r\n @error=\"handleImageError\"\r\n />\r\n </slot>\r\n <!-- icon -->\r\n <slot name=\"icon\">\r\n <ivue-icon v-if=\"icon\">{{ icon }}</ivue-icon>\r\n </slot>\r\n <!-- text -->\r\n <span\r\n :class=\"`${prefixCls}-text`\"\r\n :style=\"slotStyles\"\r\n ref=\"text\"\r\n v-if=\"$slots.default\"\r\n >\r\n <slot></slot>\r\n </span>\r\n </span>\r\n</template>\r\n\r\n<script lang=\"ts\">\r\nimport {\r\n defineComponent,\r\n computed,\r\n onMounted,\r\n reactive,\r\n ref,\r\n watch,\r\n nextTick,\r\n onUpdated,\r\n} from 'vue';\r\nimport { colorable } from '../../utils/mixins/colorable';\r\nimport { oneOf } from '../../utils/assist';\r\nimport IvueIcon from '../ivue-icon/index.vue';\r\n\r\n// type\r\nimport type { Props, Data } from './types/avatar';\r\n\r\nconst prefixCls = 'ivue-avatar';\r\n\r\nexport default defineComponent({\r\n name: prefixCls,\r\n emits: ['on-error'],\r\n props: {\r\n /**\r\n * 类型\r\n *\r\n * @type {String}\r\n */\r\n shape: {\r\n validator(value: string) {\r\n return oneOf(value, ['circle', 'square']);\r\n },\r\n default: 'circle',\r\n },\r\n /**\r\n * 链接\r\n *\r\n * @type {String}\r\n */\r\n src: {\r\n type: String,\r\n default: '',\r\n },\r\n /**\r\n * 图标\r\n *\r\n * @type {String}\r\n */\r\n icon: {\r\n type: String,\r\n default: '',\r\n },\r\n /**\r\n * 大小\r\n *\r\n * @type {Number,String}\r\n */\r\n size: {\r\n type: [Number, String],\r\n },\r\n /**\r\n * 颜色\r\n *\r\n * @type {String | Array}\r\n */\r\n color: {\r\n type: [String, Array],\r\n default: '',\r\n },\r\n },\r\n setup(props: Props, { emit, slots }) {\r\n // mixins\r\n const { setBackgroundColor } = colorable(props);\r\n\r\n // dom\r\n const text = ref<HTMLDivElement>();\r\n const wrapper = ref<HTMLDivElement>();\r\n\r\n // data\r\n const data = reactive<Data>({\r\n /**\r\n * 是否显示slot\r\n *\r\n * @type {Boolean}\r\n */\r\n isSlotShow: false,\r\n /**\r\n * slot缩放大小\r\n *\r\n * @type {Number}\r\n */\r\n slotScale: 1,\r\n /**\r\n * slot宽度\r\n *\r\n * @type {String}\r\n */\r\n slotWidth: 0,\r\n });\r\n\r\n // computed\r\n\r\n // 外层样式\r\n const wrapperClasses = computed(() => {\r\n const _class = setBackgroundColor(props.color).class;\r\n\r\n return [\r\n prefixCls,\r\n _class,\r\n {\r\n [`${prefixCls}-${props.shape}`]: true,\r\n },\r\n ];\r\n });\r\n\r\n // 外层样式\r\n const wrapperStyles = computed(() => {\r\n const _style = setBackgroundColor(props.color).style;\r\n\r\n // 大小\r\n let sizeStyle = {};\r\n\r\n // 是否有大小\r\n if (props.size) {\r\n const regexp = new RegExp(/[a-zA-Z]/g);\r\n\r\n // 是否有单位\r\n const isUnit = regexp.test(`${props.size}`);\r\n\r\n const size = !isUnit ? `${props.size}px` : props.size;\r\n\r\n // 样式\r\n sizeStyle = {\r\n height: size,\r\n width: size,\r\n lineHeight: size,\r\n };\r\n }\r\n\r\n return [sizeStyle, _style];\r\n });\r\n\r\n // slot样式\r\n const slotStyles = computed(() => {\r\n let style = {};\r\n\r\n if (data.isSlotShow) {\r\n style = {\r\n position: 'absolute',\r\n transform: `scale(${data.slotScale})`,\r\n display: 'inline-block',\r\n left: `calc(50% - ${Math.round(data.slotWidth / 2)}px)`,\r\n };\r\n }\r\n\r\n return style;\r\n });\r\n\r\n // methods\r\n\r\n // 图片加载错误\r\n const handleImageError = (event: Event) => {\r\n emit('on-error', event);\r\n };\r\n\r\n // 文字缩放\r\n const setTextScale = () => {\r\n data.isSlotShow = !props.src && !props.icon && !slots.src && !slots.icon;\r\n\r\n // 有默认插槽\r\n if (text.value) {\r\n // 获取slot宽度\r\n data.slotWidth = text.value.offsetWidth;\r\n // 获取父级宽度\r\n const fatherWidth = wrapper.value.getBoundingClientRect().width;\r\n\r\n // 计算缩放大小\r\n if (fatherWidth - 8 < data.slotWidth) {\r\n data.slotScale = (fatherWidth - 8) / data.slotWidth;\r\n } else {\r\n data.slotScale = 1;\r\n }\r\n }\r\n };\r\n\r\n // watch\r\n\r\n // 监听大小\r\n watch(\r\n () => props.size,\r\n () => {\r\n nextTick(() => {\r\n setTextScale();\r\n });\r\n }\r\n );\r\n\r\n // onMounted\r\n onMounted(() => {\r\n // 文字缩放\r\n setTextScale();\r\n });\r\n\r\n // onUpdated\r\n onUpdated(() => {\r\n const slot = slots.default ? slots.default() : null;\r\n\r\n if (slot) {\r\n // 文字缩放\r\n setTextScale();\r\n }\r\n });\r\n\r\n return {\r\n prefixCls,\r\n // dom\r\n text,\r\n wrapper,\r\n // data\r\n data,\r\n // computed\r\n wrapperClasses,\r\n wrapperStyles,\r\n slotStyles,\r\n\r\n // methods\r\n handleImageError,\r\n };\r\n },\r\n components: {\r\n IvueIcon,\r\n },\r\n});\r\n</script>\r\n"],"names":["_resolveComponent","_openBlock","_createElementBlock","_normalizeClass","_normalizeStyle","_createCommentVNode","_renderSlot","_createBlock","_withCtx"],"mappings":";;;;;;+BACEA,iBAuBO,WAAA,CAAA,CAAA;AAvB6B,EAAA,OAAAC,SAAA,EAAA,EAAAC,kBAAA,CAAE,MAAa,EAAA;AAAA,IAAE,KAAA,EAAIC,cAAS,CAAA,IAAA,CAAA,cAAA,CAAA;AAAA,IAAA,KAAA,EAAAC,cAAA,CAAA,IAAA,CAAA,aAAA,CAAA;AAAA,IAChE,GAAA,EAAA,SAAA;AAAA,GACA,EAAA;AAAA,IAGaC,mBAAA,gBAAA,CAAA;AAAA,IAAAC,WAAA,IAAA,CAAA,MAAA,EAFX,KAKE,EAAA,IAAA,MAAA;AAAA,MAAA,IAAA,CAAA,GAAA,IAAAL,SAJM,EAAA,qBAAK,KAAS,EAAA;AAAA,QAEnB,GAAK,EAAA,CAAA;AAAA,QACL,KAAK,EAAAE,cAAA,CAAA,CAAA,EAAA,IAAA,CAAA,SAAA,CAAA,IAAA,CAAA,CAAA;AAAA,QAAA,KAAA,IAAA,CAAA,GAAA;AAAA;8BAGV,IAAAE,kBAAA,CAAa,QAAA,IAAA,CAAA;AAAA,KACb,CAAA;AAAA,IACuBA,mBAAA,QAAA,CAAA;AAAA,IAAAC,WAAA,IAAA,CAAA,MAAA,EAArB,MAA6C,EAAA,IAAA,MAAA;AAAA,MAAf,IAAA,CAAA,QAAAL,SAAA,EAAA,EAAAM,YAAA,oBAAA,EAAA,EAAA,GAAA,EAAA,CAAA,EAAA,EAAA;AAAA,QAAA,OAAA,EAAAC,QAAA,MAAA;AAAA;;;YAEhCH,kBAAa,CAAA,MAAA,EAAA,IAAA,CAAA;AAAA,KAKL,CAAA;AAAA,IAJRA,mBAAA,QAAA,CAAA;AAAA,IAAA,KAAA,MAAA,CAAA,OAAA,IAAAJ,SACQ,EAAA,qBAAK,MAAS,EAAA;AAAA,MACnB,GAAK,EAAA,CAAA;AAAA,MACN,KAAI,EAAAE,cAAA,CAAM,CAAA,EAAA,IAAA,CAAA,SAAA,CAAA,KAAA,CAAA,CAAA;AAAA,MAAA,KAAA,EAAAC,cAAA,CAAA,IAAA,CAAA,UAAA,CAAA;AAAA,MAGV,GAAA,EAAA,MAAA;AAAA,KAAA,EAAA;AAAA;;;;;;;;"}