v3 图片懒加载 自定义指令封装

141 阅读3分钟

根据项目需要 后端返回数据懒加载路由 封装完 又要根据页面获取图片 封装一个自定义指令获取图片 如果图片加载失败 则用 默认图片 每次打开页面只请求一次 \

1.V2全局

import ScreenFull from '@/components/FUllScreen' 
// 使用插件 
const MyPlugin = { install(Vue) { Vue.component(PageTool.name, PageTool)
// console.log('插件注册,调用install,传入的参数是', Vue) 
// 在Vue的构造器的原型上添加这个功能
// 添加全局过滤器,组件,
Vue.component(ScreenFull.name, ScreenFull) } } 
export default MyPlugin

main.js

import MyPlugin from '@/plugin' Vue.use(MyPlugin)

2.在v3

常规 是这样的

import Carousel from './carousel.vue'
const myPlugin = { install (app) {
// app为vue的实例 // app.component('组件名',组件对象)
app.component(Carousel.name, Carousel) } }
export default myPlugin

下面 在 main.js

// 引入全局组件 
import myPlugin from '@/components/index' 
createApp(App).use(store).use(router).use(myPlugin).mount('#app')

而我写的 是这样的 在vue3里面 用 V2的install
Vue.js 的插件应该暴露一个 install 方法。这个方法的第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象:

export default {
install(Vue){

  // 注册时F开头 是函数  其他的 是对象
    Vue.directive('lazy', {
      // v3的注册指令 钩子跟v2有很大不一样
      // el  是 要 监听 的dom 元素 binding是
      mounted (el, binding) {
        const defaultImg = '@/assets/images/200.png'
        // 对懒加载 的封装  懒加载 必用api浏览器 提供
        const observer = new IntersectionObserver(
          ([{ isIntersecting }]) => {
            if (isIntersecting) {
              console.log(el, binding, 265995595)
              // 判断 图片是否 正常加载  如果 图片是坏的
              // 则 函数 调用  附一张 新的默认图片
              el.onerror = function () {
                el.src = defaultImg
              }
              el.src = binding.valve
              // 监听过一次就不在监听dom 相当于 lodash里面的.stop
              observer.unobserve(el)
            }
          },
          { threshold: 0.01 }
        )
        // 监听dom
        observer.observe(el)
      }
    })
    }
    }
    

关于 IntersectionObserver API解读:

1.用法

是以new的形式声明一个对象,接收两个参数callbackoptions

const io = new IntersectionObserver(callback, options)

io.observe(DOM)
const options = {
  root: null,
  rootMargin: 0,
  thresholds: 1,
}
const io = new IntersectionObserver(entries => {
  console.log(entries)
  // Do something
}, options)

2.callback

callback是添加监听后,当监听目标发生滚动变化时触发的回调函数。接收一个参数entries,即IntersectionObserverEntry实例。描述了目标元素与root的交叉状态。具体参数如下:

属性说明
boundingClientRect返回包含目标元素的边界信息,返回结果与element.getBoundingClientRect() 相同
intersectionRatio返回目标元素出现在可视区的比例
intersectionRect用来描述root和目标元素的相交区域
isIntersecting返回一个布尔值,下列两种操作均会触发callback:1. 如果目标元素出现在root可视区,返回true。2. 如果从root可视区消失,返回false
rootBounds用来描述交叉区域观察者(intersection observer)中的根.
target目标元素:与根出现相交区域改变的元素 (Element)
time返回一个记录从 IntersectionObserver 的时间原点到交叉被触发的时间的时间戳

表格中加粗的两个属性是比较常用的判断条件:isIntersectingintersectionRatio

IntersectionObserverEntry打印的值

3.options

options是一个对象,用来配置参数,也可以不填。共有三个属性,具体如下:

属性说明
root所监听对象的具体祖先元素。如果未传入值或值为null,则默认使用顶级文档的视窗(一般为html)。
rootMargin计算交叉时添加到根(root)边界盒bounding box的矩形偏移量, 可以有效的缩小或扩大根的判定范围从而满足计算需要。所有的偏移量均可用像素(px)或百分比(%)来表达, 默认值为"0px 0px 0px 0px"。
threshold一个包含阈值的列表, 按升序排列, 列表中的每个阈值都是监听对象的交叉区域与边界区域的比率。当监听对象的任何阈值被越过时,都会触发callback。默认值为0。

4.方法

介绍了这么多配置项及参数,差点忘了最重要的,IntersectionObserver有哪些方法? 如果要监听某些元素,则必须要对该元素执行一下observe

方法说明
observe()开始监听一个目标元素
unobserve()停止监听特定目标元素
takeRecords()返回所有观察目标的IntersectionObserverEntry对象数组
disconnect()使IntersectionObserver对象停止全部监听工作