场景和指令用法
实现思路和步骤
1.熟悉指令语法
2.3.4判断图片是否进入视口并测试
过程
用法
<script setup lang="ts">
import { useIntersectionObserver } from '@vueuse/core'
import { shallowRef, useTemplateRef } from 'vue'
const target = useTemplateRef<HTMLDivElement>('target')
const targetIsVisible = shallowRef(false)
const { stop } = useIntersectionObserver(
target,
([entry], observerElement) => {
targetIsVisible.value = entry?.isIntersecting || false
},
)
</script>
<template>
<div ref="target">
<h1>Hello world</h1>
</div>
</template>
指令用法
<script setup lang="ts">
import { vIntersectionObserver } from '@vueuse/components'
import { shallowRef, useTemplateRef } from 'vue'
const root = useTemplateRef<HTMLDivElement>('root')
const isVisible = shallowRef(false)
function onIntersectionObserver([entry]: IntersectionObserverEntry[]) {
isVisible.value = entry?.isIntersecting || false
}
</script>
<template>
<div>
<p>
Scroll me down!
</p>
<div v-intersection-observer="onIntersectionObserver">
<p>Hello world!</p>
</div>
</div>
<!-- with options -->
<div ref="root">
<p>
Scroll me down!
</p>
<div v-intersection-observer="[onIntersectionObserver, { root }]">
<p>Hello world!</p>
</div>
</div>
</template>
代码
import {createApp} from 'vue'
import {createPinia} from 'pinia'
import App from 'App.vue'
import router from './router'
//引入初始化样式文件
import '@/styles/common.scss'
//先导入进来
import { useIntersectionObserver } from '@vueuse/core'
const app = createApp(App)
app.use(createPinia())
app.use(router)
app.mount('#app')
//定义全局指令
app.directive('img-lazy',{
mounted(el,binding) {
//el:指令绑定的元素 img
//binding:binding.value 指令等于号后面绑定的表达式的值 图片url
console.log(el,binding.value)
useIntersectionObserve(
el,
//isIntersecting是一个布尔值
([{isIntersecting}]) => {
console.log(isIntersecting)
},
)
}
})
判断出来了
5.如果图片进入视口,发送图片资源请求
import {createApp} from 'vue'
import {createPinia} from 'pinia'
import App from 'App.vue'
import router from './router'
//引入初始化样式文件
import '@/styles/common.scss'
//先导入进来
import { useIntersectionObserver } from '@vueuse/core'
const app = createApp(App)
app.use(createPinia())
app.use(router)
app.mount('#app')
//定义全局指令
app.directive('img-lazy',{
mounted(el,binding) {
//el:指令绑定的元素 img
//binding:binding.value 指令等于号后面绑定的表达式的值 图片url
console.log(el,binding.value)
useIntersectionObserve(
el,
//isIntersecting是一个布尔值
([{isIntersecting}]) => {
console.log(isIntersecting)
if(isIntersecting) {
//进入视口区域
el.src=binding.value
}
},
)
}
})
<script setup>
import HomePanel from './HomePanel.vue'
import {findNewAPI} from '@/apis/home'
//获取数据
const newlist = ref([])
const getNewList = async() => {
const res = await findNewAPI()
newList.value = res.result
}
onMounted(() => getNewList())
</script>
<template>
<homePanel title="新鲜好物" sub-title="新鲜出炉 品质靠谱">
<ul class="goods-list">
<li v-for="item in newList" :key="item.id">
<RouterLink to="/">
<img v-img-lazy="item.picture" alt="" />
<p class="name">{{ item.name }}</p>
<p class="price">¥{{ item.price }}</p>
</RouterLink>
</li>
</ul>
</HomePanel>
// <!-- 下面是插槽主体内容模版
// <ul class="goods-list">
// <li v-for="item in newList" :key="item.id">
// <RouterLink to="/">
// <img :src="item.picture" alt="" />
// <p class="name">{{ item.name }}</p>
// <p class="price">¥{{ item.price }}</p>
// </RouterLink>
// </li>
// </ul>
// -->
</template>
<style scoped lang='scss'>
.goods-list {
display: flex;
justify-content: space-between;
height: 406px;
li {
width: 306px;
height: 406px;
background: #f0f9f4;
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;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.price {
color: $priceColor;
}
}
}
</style>