vue3图片懒加载

背景

界面很长,屏幕不能一下装下所有内容,如果以进入首页就把所有内容都加载完的话所需时间较长,会影响用户体验,所以可以当用户浏览到时再去加载。

代码

新建index.ts文件

src下新建directives文件夹,并新建Index.ts文件

javascript 复制代码
import { useIntersectionObserver } from '@vueuse/core'
import { install } from 'element-plus'

export const lazyPlugin = {
    install(app){
        // 懒加载指令逻辑

        // 定义全局指令
        // 这个属于图片懒加载部分
        app.directive('img-lazy',{
            mounted(el, binding){
                // el: 指令绑定的那个元素 img
                // binding: binding.value 指令等于号后面绑定的表达式的值 图片url
                const {stop} =useIntersectionObserver(
                    el,
                    ([{isIntersecting}]) => {
                        // 第一次赋值之后,就不用再监听了 -> stop()
                        // 防止内存的浪费
                        if(isIntersecting){
                            el.src = binding.value
                            stop()
                        }
                    },
                )
            }
        })
    }
}

修改main.ts文件

javascript 复制代码
import './assets/main.css'

import { createApp } from 'vue'
import { createPinia } from 'pinia'

import App from './App.vue'
import router from './router'

// 引入初始化样式文件
import '@/styles/common.scss'
// 引入图片延迟加载
import { lazyPlugin } from '@/directives/index'

const app = createApp(App)

app.use(createPinia())
app.use(router)
// 使用图片延迟加载插件
app.use(lazyPlugin)

app.mount('#app')

HomeHot.vue

index.ts文件中定义的名字叫img-lazy,在这里使用的时候用 v-img-lazy,后面跟图片对应路径

html 复制代码
<script setup lang="ts" name="HomeHot">
import HomePanel from './HomePanel.vue'
import { getHotAPI } from '@/apis/home'
import { onMounted, ref } from 'vue'

const hotList = ref([])
const getHotList = async () => {
    const res = await getHotAPI()
    console.log(res)
    hotList.value = res.data.result
}
onMounted(() => getHotList())


</script>

<template>
    <HomePanel title="人气推荐" sub-title="人气爆款 不容错过">
        <ul class="goods-list">
            <li v-for="item in hotList" :key="item.id">
                <RouterLink to="/">
                    <img v-img-lazy="item.picture" alt="">
                    <p class="name">{{ item.title }}</p>
                    <p class="desc">{{ item.alt }}</p>
                </RouterLink>
            </li>
        </ul>
    </HomePanel>
</template>

<style scoped lang='scss'>
.goods-list {
    display: flex;
    justify-content: space-between;
    height: 426px;

    li {
        width: 306px;
        height: 406px;
        transition: all .5s;

        &:hover {
            transform: translate3d(0, -3px, 0);
            box-shadow: 0 3px 8px rgb(0 0 0 / 20%);
        }

        img {
            width: 306px;
            height: 306px;
        }

        p {
            font-size: 22px;
            padding-top: 12px;
            text-align: center;
        }

        .desc {
            color: #999;
            font-size: 18px;
        }
    }
}
</style>
相关推荐
摸鱼仙人~23 分钟前
Vue中markdown-it基础使用教程
前端·javascript·vue.js
落魄江湖行30 分钟前
入门篇二:Nuxt 4路由自动生成:告别手动配置路由的日子
前端·vue.js·typescript·nuxt4
xiaotao1312 小时前
第八章:实战项目案例
前端·vue.js·vite·前端打包
源码站~4 小时前
基于Spring Boot+Vue3的烹饪交流学习系统 设计与实现
java·vue.js·spring boot·后端·mysql·毕业设计·毕设
小小小米粒4 小时前
原生 JS:数据和视图「分离」,必须手动同步原生 JS 里,数据是数据,视图是视图,两者完全没关系
前端·javascript·vue.js
摸鱼仙人~4 小时前
纯前端 Vue 实现共享预览链接方案
前端·javascript·vue.js
摸鱼仙人~4 小时前
前端开发中“共享预览链接”场景-企业级最简方案:Vue + 极简后端(2 接口 1 张表)
前端·javascript·vue.js
摇滚侠14 小时前
JAVA 项目教程《苍穹外卖-12》,微信小程序项目,前后端分离,从开发到部署
java·开发语言·vue.js·node.js
打瞌睡的朱尤21 小时前
建立vue项目
vue.js