automated_uniapp/uni_modules/cool-ui/components/cl-avatar/cl-avatar.vue
2025-01-09 16:16:11 +08:00

102 lines
1.8 KiB
Vue

<template>
<view
:class="['cl-avatar', `cl-avatar--${shape}`]"
:style="[{ height: parseRpx(size), width: parseRpx(size) }, baseStyle]"
@click="tap"
>
<slot v-if="$slots.default || $slots.$default"> </slot>
<template v-else>
<slot name="placeholder" v-if="!src">
<view class="cl-avatar__placeholder">
<text
:class="{
'cl-icon-my': !name,
}"
:style="{ fontSize: parseRpx(size / 2) }"
>{{ name[0] }}</text
>
</view>
</slot>
<slot name="error" v-else-if="isError">
<view class="cl-avatar__error"> Error </view>
</slot>
<image
class="cl-avatar__target"
:src="src"
:mode="mode"
:lazy-load="lazyLoad"
@error="handleError"
@load="handleLoad"
v-else
/>
</template>
</view>
</template>
<script lang="ts">
import { defineComponent, ref } from "vue";
import { type PropType } from "vue";
import { useStyle, useTap } from "../../hooks";
export default defineComponent({
name: "cl-avatar",
props: {
// 图片地址
src: String,
// 名称
name: {
type: String,
default: "",
},
// 懒加载
lazyLoad: Boolean,
// 头像大小
size: {
type: Number,
default: 80,
},
// 形状
shape: {
type: String as PropType<"circle" | "square">,
default: "circle",
},
// 裁剪模式
mode: {
type: String,
default: "scaleToFill",
},
},
emits: ["error", "load"],
setup(_, { emit }) {
// 是否加载失败
const isError = ref(false);
// 处理加载
function handleLoad(e: Event) {
isError.value = false;
emit("load", e);
}
// 处理错误
function handleError(e: Event) {
isError.value = true;
emit("error", e);
}
return {
isError,
handleLoad,
handleError,
...useTap(emit),
...useStyle(),
};
},
});
</script>