wangzhibo
4 天以前 10595d8632f959d0954d1939243196f4eed02372
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
<template>
    <view
        :class="['cl-avatar', `cl-avatar--${shape}`]"
        :style="[{ height: parseRpx(size), width: parseRpx(size) }, baseStyle]"
        @click="tap"
    >
        <slot v-if="$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>