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="">
标签:el,绑定,observer,04,鲜儿,元素,binding,指令,vue3 From: https://www.cnblogs.com/jzhFlash/p/16646102.html