增加一个lazy加载图片的组件

This commit is contained in:
CounterFire2023 2024-06-25 16:19:04 +08:00
parent 427ca61d7a
commit cb1183a5ed
4 changed files with 110 additions and 3 deletions

View File

@ -3,7 +3,7 @@
<div class="card-top" v-if="nftData">
<!-- @click="toDetail" -->
<div class="card-img" @click="toDetail">
<img :src="nftData.image" alt="图片">
<LazyLoadImg :src="nftData.image" :src-placeholder="placeholderImg" alt="图片"/>
</div>
<div class="card-name">
<div>Cotnesford park</div>
@ -35,6 +35,8 @@ import SellDialog from "@/components/Dialogs/sellDialog.vue"
import {PassportWallet} from "@/wallet/passPort.js"
import { useDetailStore } from "@/store/detail"
import { apiGetPrice } from "@/utils/marketplace"
import LazyLoadImg from "@/components/lazyloadimg"
import placeholderImg from '@/assets/img/marketplace/GenesisHeroes_NFT.png'
// import BuyDialog from "@/components/Dialogs/buyDialog.vue"
import {

View File

@ -2,7 +2,7 @@
<div class="cards">
<div class="card-top" v-if="nftData" @click="toDetail">
<div class="card-img">
<img :src="nftData.nft.image" alt="图片">
<LazyLoadImg :src="nftData.nft.image" :src-placeholder="placeholderImg" alt="图片" />
</div>
<div class="card-name">
<div>Cotnesford park</div>
@ -34,6 +34,8 @@ import BuyDialog from "@/components/Dialogs/buyDialog.vue"
import {priceCalculated} from "@/configs/priceCalculate.js"
import { useDetailStore } from "@/store/detail"
import { useImmutableStore } from "@/store/immutable"
import LazyLoadImg from "@/components/lazyloadimg"
import placeholderImg from '@/assets/img/marketplace/GenesisHeroes_NFT.png'
import {
useMarketplaceStore
} from "@/store/marketplace"

View File

@ -0,0 +1,101 @@
import { reactive, h, computed, ref, onMounted, onBeforeUnmount } from "vue";
export default {
props: {
src: {
type: String,
required: true
},
srcPlaceholder: {
type: String,
default:
"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
},
srcset: {
type: String
},
intersectionOptions: {
type: Object,
default: () => ({})
},
usePicture: {
type: Boolean,
default: false
}
},
inheritAttrs: false,
setup(props, { attrs, slots, emit }) {
const root = ref(null);
const state = reactive({
observer: null,
intersected: false,
loaded: false
});
// Computed
const srcImage = computed(() =>
state.intersected && props.src ? props.src : props.srcPlaceholder
);
const srcsetImage = computed(() =>
state.intersected && props.srcset ? props.srcset : false
);
// Methods
const load = () => {
if (
root.value &&
root.value.getAttribute("src") !== props.srcPlaceholder
) {
state.loaded = true;
emit("load", root.value);
}
};
const error = () => emit("error", root.value);
// Hooks
onMounted(() => {
if ("IntersectionObserver" in window) {
state.observer = new IntersectionObserver((entries) => {
const image = entries[0];
if (image.isIntersecting) {
state.intersected = true;
state.observer.disconnect();
emit("intersect");
}
}, props.intersectionOptions);
state.observer.observe(root.value);
}
});
onBeforeUnmount(() => {
if ("IntersectionObserver" in window && state.observer) {
state.observer.disconnect();
}
});
return () => {
const img = h("img", {
ref: root,
src: srcImage.value,
srcset: srcsetImage.value || null, // set to null explicitly if falsy
...attrs,
class: [
attrs.class,
"v-lazy-image",
{ "v-lazy-image-loaded": state.loaded }
],
onLoad: load,
onError: error
});
return props.usePicture
? h(
"picture",
{ ref: root, onLoad: load },
state.intersected ? [slots.default, img] : [img]
)
: img;
};
}
};

View File

@ -5,7 +5,7 @@
<div class="content">
<div class="top-left">
<div class="top-left-img">
<img :src="detailData.image" alt="">
<LazyLoadImg :src="detailData.image" :src-placeholder="placeholderImg" alt="" />
</div>
</div>
<div class="top-right">
@ -145,12 +145,14 @@ import { nftDetail } from "@/utils/marketplace"
import {priceCalculated} from "@/configs/priceCalculate.js"
import { BlockChain } from "@/components/chain/BlockChain"
import {walletStore} from "@/store/wallet";
import LazyLoadImg from "@/components/lazyloadimg"
const router = useRouter();
const localWalletStore = walletStore()
const props = defineProps({
address: String,
tokenid: String
})
import placeholderImg from '@/assets/img/marketplace/GenesisHeroes_NFT.png'
const detailData = ref(null)
// const detailData = window.history.state.nftData
// console.log(detailData)