Files
lingji-work-fe/src/components/img-lazy-load/index.vue

91 lines
1.7 KiB
Vue
Raw Normal View History

<template>
<div class="img-lazy" v-lazy:background-image="imgSrc" :key="src" :class="imgClass" :style="style" />
</template>
<script setup>
import { ref, onMounted, watch, computed } from 'vue';
const emit = defineEmits(['click']);
const props = defineProps({
width: {
type: [String, Number],
},
height: {
type: [String, Number],
},
loadingSize: {
type: [String],
default: '5',
},
errorSize: {
type: [String],
default: '5',
},
fit: {
type: [String],
default: 'cover',
},
src: {
type: String,
},
customImg: {
type: String,
},
});
const style = computed(() => {
return {
'background-size': props.fit,
width: props.width ? parseInt(props.width) + 'px' : undefined,
height: props.height ? parseInt(props.height) + 'px' : undefined,
};
});
const imgClass = computed(() => {
return {
['loading-size-' + props.loadingSize]: true,
};
});
const imgSrc = computed(() => {
return props.innerSrc || props.src;
});
const innerSrc = ref('');
watch(
() => props.customImg,
() => {
innerSrc.value = '';
if (props.customImg) {
const img = new Image();
img.src = props.src;
img.onerror = () => {
innerSrc.value = props.customImg;
};
img.onload = () => {
innerSrc.value = props.src;
};
}
},
{ immediate: true },
);
onMounted(() => {});
</script>
<style scoped lang="scss">
.img-lazy.block {
display: block;
}
.img-lazy {
display: inline-block;
overflow: hidden;
background-size: 100% 100%;
background-position: center center;
background-repeat: no-repeat;
@for $i from 0 to 10 {
&.loading-size-#{$i}[lazy='loading'] {
background-size: #{$i * 10 + '%'} !important;
}
}
}
</style>