背景
界面很长,屏幕不能一下装下所有内容,如果以进入首页就把所有内容都加载完的话所需时间较长,会影响用户体验,所以可以当用户浏览到时再去加载。
代码
新建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>