进入可视区加载数据:
首页有很多模块,如果一次性加载所有数据,很卡,,当移动到要显示的地方,才加载数据
使用 vueuse 库中 useIntersectionObserver
方法,, 传入要监听的元素 target 和监听到这个target去加载的数据api,,, 返回api请求的数据
import { useIntersectionObserver } from '@vueuse/core'
import { ref } from 'vue'
/**
* 懒加载组件数据,, 当组件进入可视区,再去加载
* @param {Element} target 被监听的DOM
* @param {Function} apiFn 发请求的api
*/
export const useLazyData = (target, apiFn) => {
// api请求的数据
const data = ref([])
// stop停止观察
const { stop } = useIntersectionObserver(
// target 要监听的元素
target, ([{ isIntersecting }], observerElement) => {
if (isIntersecting) {
// 进入可视区
stop()
apiFn().then(res => {
data.value = res.result
})
}
}, {
// 触发的门槛,,只要相交就触发
threshold: 0
})
return data
}
vue3中获取dom节点:
先声明一个响应式变量,,然后将这个响应式变量,指向你要绑定的节点
引入全局动画,,取名字为fade,,
有的函数,参数中需要传入另一个函数,,但是直接写函数名只能传入一个不带参数的函数,,可以用箭头函数返回一个带参数的函数
const brands = useLazyData(target, () => findBrand(10))
img标签的事件:
- load : 当图像成功加载并完全显示
- error : 如果图像加载失败
图片懒加载:
监听图片是否进入可视区,,,先将图片src制空,等待图片进入可视区后,将图片的url赋值给src,,,加载图片
使用到的方法: IntersectionObserver
是浏览器原生提供的构造函数,,用来监听某个DOM是否进入可视区,,, ,返回一个observer监听器,,,
// 创建一个监听器
const observer = new IntersectionObserver(callback,options)
// 开始观察某个元素,, 可以同时观察多个
observer.observe(element1)
observer.observe(element2)
// 停止观察某个元素
observer.unobserve(xxx)
IntersectionObserver 中的参数:
- callback : 监听触发的回调
- callback的参数是一个数组,,因为可以同时监听多个元素,,每个元素都是一个IntersectionObserverEntry 对象,,这个对象中有很多属性,,比如:
isIntersecting
: 判断是否相交
- callback的参数是一个数组,,因为可以同时监听多个元素,,每个元素都是一个IntersectionObserverEntry 对象,,这个对象中有很多属性,,比如:
- options : 配置对象,,可以配置 threshold ,,触发的门槛,进入多少,触发
引用:https://blog.csdn.net/qq_38629292/article/details/127200527
图片懒加载,,自定义了一个指令: v-lazy
- vue3 自定义指令,,, vue3中自定义指令的钩子和组件的钩子是一样的:
mounted()钩子中:- 第一个参数: 当前指令的DOM
- 第二个参数: binding : 是当前指令传入的值
import XtxSkeleton from '@/components/library/xtx-skeleton'
import XtxCarousel from '@/components/library/xtx-carousel'
import XtxMore from '@/components/library/xtx-more'
import defaultImg from '@/assets/images/default.png'
export default {
install (app) {
// 导入组件
app.component(XtxSkeleton.name, XtxSkeleton)
app.component(XtxCarousel.name, XtxCarousel)
app.component(XtxMore.name, XtxMore)
app.directive('lazy', {
mounted (el, binding) {
const observer = new IntersectionObserver(([{ isIntersecting }]) => {
if (isIntersecting) {
// 加载之后不观察,不能重复加载
observer.unobserve(el)
// 指定传递的参数
const imgUrl = binding.value
el.src = imgUrl
// 图片加载失败,设置默认图片
el.onerror = () => {
el.src = defaultImg
}
}
}, {
threshold: 0
})
// 观察这个元素
observer.observe(el)
}
})
}
}
面包屑组件:
vue中创建html内容方式:
- el选项 直接绑定 html节点
- template 选项
- render() 函数动态渲染 ,, render中传入一个函数
createElement
也可以写成h
,h(你要创建的标签,{标签的属性对象},z子节点)
如果render存在,vue不会从template选项和el选项,创建指定元素,,而是使用render
获取组件插槽中的内容: this.$slots.default()
, default表示获取的默认插槽,,默认插槽的名字叫default
面包屑组件: 使用render动态创建dom,,最后一个节点没有 箭头
问题
进入可视区加载数据