程序员的资源宝库

网站首页 > gitee 正文

vue3项目-小兔鲜儿笔记-首页04

sanyeah 2024-04-13 16:20:52 gitee 4 ℃ 0 评论

1. 新了解CSS属性:object-fit

  • object-fit属性对图片进行剪切,保留原始比例

  • 一般用于img标签和video标签。

  • object-fit属性值:

    • fill 默认,不保证保持原有比例,内容拉伸填充整个内容容器

    • contain 保持原有尺寸比例,内容被缩放

    • cover 保持原有尺寸比例,但部分内容可能会被剪切

    • scale-down 保持原有尺寸比例,内容的尺寸取决于小的那个

    • none 保留原有元素内容的长度和宽度,也就是说内容不会被重置

 

 

 未加这个属性的图片:

 

 加了object-fit:cover之后的图片:

 

 

2. 新了解webapi:IntersectionObserver

  • IntersectionObserver接口提供了一种异步观察目标元素与祖先元素或顶级文档viewport的交集中变化的方法

  • 可实现的需求:

    • 当页面滚动时,懒加载图片或其他内容

    • 滚动到相应区域来执行相应任务

      // 创建观察者对象实例
      const observer = new IntersectionObserver(callbackFn, options)
      // callbackFn: 被观察的目标元素dom进入可视区和离开可视区的时候都会触发callbackFn
      // 它具有两个回调参数:entries, observer
      // - entries: 被观察的元素信息对象的数组[{元素信息}],一般用[{isIntersecting}],用这个isIntersection去判断元素是否进入区域和离开区域
      
      // options: 配置参数
      // - 有三个配置属性:root rootMargin threshold
      // - root 基于的滚动容器,不写默认指document
      // - rootMargin 容器有没有外边距,不写默认没有
      // - threshold 交叉的比例,可以理解为滚动到可视区域的多少才认为是进入了可视区域
      
      // observer观察者对象实例提供两个方法:
      // observe(dom),观察哪个dom
      // unobserve(dom),停止观察目标dom

       

应用场景:

1.实现数据懒加载

// 实现原理:通过web API IntersectionObserver 创建一个观察者对象,观察目标元素是否进入可视区域,进入之后才实现数据加载
import { ref, onMounted } from 'vue'

export const useLazyData = (apiFn) => {
  const result = ref([])
  const targetDom = ref(null)
  // 由于在vue3.0中,目标dom元素生成需要在挂载了组件之后,所以要在onMounted钩子中执行观察
  onMounted(() => {
    const observer = new IntersectionObserver(
      ([{ isIntersecting }]) => {
        if (isIntersecting) {
          // 进入了可视区域,停止观察目标元素
          observer.unobserve(targetDom.value)
            // 发送网络请求获取数据
          apiFn().then((res) => {
            result.value = res.result
          })
        }
      },
      {
        // 可视区域的交叉比例
        threshold: 0
      }
    )
    // 在挂载之后启用观察
    observer.observe(targetDom.value)
  })

  return {
    targetDom,
    result
  }
}

// 在新品推荐模块中使用:
...
<div class="home-new" ref="targetDom">
    ...
<script>
import {useLazyData} from "@/hooks";
const {targetDom, result} = useLazyData(findNew)
</script>

实现效果:

在未滚动到新品模块时,是不会发送网络请求的:

 

当滚动到新品推荐模块,observer认为元素进入了可视区,开始发送网络请求:

 

2.实现图片懒加载:

原理:先存储图片地址不在src上,当图片进入可视区时,再把图片地址赋值给img元素的src上。

自定义指令:对dom元素进行底层的操作

指令注册的方法:app.directive('指令名称',options)

一个自定义指令由一个包含类似组件生命周期的钩子的对象来定义,钩子函数会接收到指令所绑定的元素作为其参数:

  • created(el, binding, vnode, prevVnode):在绑定元素的attribute前调用

  • beforeMount(el, binding, vnode, prevVnode):在元素被插入DOM前调用

  • mounted(el, binding, vnode, prevVnode):在绑定元素的父组件及它自己所有的子节点都挂载完毕后调用

  • beforeUpdate(el, binding, vnode, prevVnode):在绑定元素的父组件更新前调用

  • updated(el, binding, vnode, prevVnode):在绑定元素的父组件更新后调用

  • beforeUnMount(el, binding, vnode, prevVnode):在绑定元素的父组件卸载前调用

  • unmounted(el, binding, vnode, prevVnode):在绑定元素的父组件卸载后调用

 

钩子的参数:

  • el:指令绑定的元素,可以用来直接操作dom

  • binding:一个对象,包含以下属性:

    • value:传递给指令的值,如v-my-directive="hello",通过binding.value获取到"hello"

    • oldValue:之前的值,仅在beforeUpdate和updated中可用,无论值是否更新

    • arg:传递给指令的参数,如v-my-directive:foo,binding.arg="foo"

    • modifiers:一个包含修饰符的对象,如v-my-directive.foo.bar,binding.modifiers = {foo: true, bar: true}

    • instance:使用该指令的组件实例

    • vnode:代表绑定元素的底层Vnode

    • prevVnode:之前的渲染中代表指令所绑定的元素的Vnode,仅在beforeUpdate和updated中使用

const defineDirective = (app) => {
  app.directive('lazy', {
    // 图片懒加载指令:v-lazy
    // 原理:先存储图片地址不在src上,当图片进入可视区后,再将存储的图片地址赋值给src
    mounted(el, binding) {
      // 创建一个观察者对象,用于观察当前使用指令的元素
      const observer = new IntersectionObserver(
        ([{ isIntersecting }]) => {
          if (isIntersecting) {
            // 已进入可视区,就停止观察元素
            observer.unobserve(el)
            // binding:指令=号右边的值,通过binding.value可取到
            el.onerror = () => {
              el.src = defaultImg
            }
            el.src = binding.value
          }
        },
        {
          // 交叉比例
          threshold: 0.01
        }
      )
      // 观察元素
      observer.observe(el)
    }
  })
}

// 在img上使用:
<img v-lazy="goods.picture" alt="">

 

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表