【VueUse】超越基本功能的高级 Vue 元素操作

在vue开发中我们经常需要操作DOM元素,从简单的添加类到动态创建元素,这些操作都是不可避免的。而在VueUse库中,Elements相关API函数为我们提供了一系列强大而灵活的工具,帮助我们更轻松地处理DOM元素。无论是优雅地处理元素、动态渲染元素还是简化复杂的DOM操作,VueUse Elements都能够成为您的得力助手。

        在本文将带您深入探索VueUse Elements,揭示其背后的神秘面纱,并展示如何利用这些强大的API函数提升您的Vue项目至新的高度。让我们一起踏上这场关于VueUse Elements的探索之旅吧!

目录

useActiveElement(跟踪焦点元素)

useDocumentVisibility(跟踪文档可见状态)

useDraggable(拖拽元素)

useDropZone(拖放区域)

useElementBounding(响应边界数据)

useElementSize(获取指定元素宽高)

useResizeObserver(监听元素内容和边框尺寸变化)

useElementVisibility(跟踪元素可见性)

useIntersectionObserver(指定元素交集变化)

useMouseInElement(跟踪鼠标指定元素状态)

useMutationObserver(监听DOM树修改)

useWindowFocus(跟踪窗口焦点)

useWindowScroll(获取窗口的滚动位置)

useWindowSize(获取窗口尺寸)

最后总结


useActiveElement(跟踪焦点元素)

响应式 document.activeElement。什么意思呢?就是跟踪文档中当前处于焦点的元素。具体来说,useActiveElement函数会返回一个Ref对象,该对象的值为当前处于焦点的元素。这意味着,当用户在页面上点击、输入或以其他方式与页面交互时,useActiveElement将提供当前活动元素的信息。如下:

<template><input v-for="i in 6" :key="i" type="text" :data-id="i" :placeholder="`${i}`"><br>当前聚焦的元素:{{ key }}
</template><script setup lang="ts">
import { watch, computed } from 'vue'
import { useActiveElement } from '@vueuse/core'const activeElement = useActiveElement()
const key = computed(() => activeElement.value?.dataset?.id || 'null')watch(activeElement, (el) => {console.log(activeElement.value?.dataset)
})
</script>

最终得到的结果如下:

useDocumentVisibility(跟踪文档可见状态)

响应式跟踪 document.visibilityState。什么意思呢?就是跟踪文档的可见性状态,允许开发者监测页面是否处于可见状态,从而可以根据不同的可见性状态来执行相应的操作。例如,在开发通知系统或者数据同步功能时,可以利用useDocumentVisibility函数来检测用户是否正在浏览页面,从而决定是否发送通知或执行数据同步操作,以避免在用户不可见时造成不必要的打扰或消耗额外的资源。如下:

<template><div class="use-document-visibility">{{ hello }}</div>
</template><script lang="ts" setup>
import { ref, watch } from 'vue'
import { useDocumentVisibility } from '@vueuse/core'const visibility = useDocumentVisibility()const hello = ref('最小化页面或切换标签然后返回!')
watch(visibility, (current, previous) => {if (current === 'visible' && previous === 'hidden') {hello.value = '欢迎回家!'}
})
</script>

最终得到的结果如下:

useDraggable(拖拽元素)

使元素可拖拽。什么意思呢?就是使元素能够响应拖拽操作,允许开发者将其应用于某个元素,从而使该元素具有拖拽功能。一旦应用了该函数,用户便可以通过鼠标或触摸屏对元素进行拖拽操作,移动元素到所需位置。如下:

<template><div class="use-draggable" ref="el" :style="style" style="position: fixed;"><div class="title">标题</div>我的位置:{{ x }}, {{ y }}</div>
</template><script setup lang="ts">
import { ref } from 'vue'
import { useDraggable } from '@vueuse/core'const el = ref(null)
const { x, y, style } = useDraggable(el, {initialValue: { x: 40, y: 40 }, // 初始位置})
</script><style scoped lang="scss">
.use-draggable {border: 1px solid #e5e5e5;border-radius: 4px;background: #fff;color: #333;padding: 10px 20px;.title {line-height: 32px;font-size: 14px;font-weight: bold;}
}
</style>

最终得到的结果如下:

useDropZone(拖放区域)

创建一个可以放置文件的区域。什么意思呢?就是让一个元素成为“拖放区域”,从而可以接收用户拖放的文件或其他数据。这个区域可以接收用户从文件系统或其他来源拖放过来的内容。通过这个函数,你可以监听各种拖放相关的事件,比如当用户开始拖拽、拖拽进入区域、拖拽在区域内移动以及拖放操作完成等。场景应用于文件上传组件、拖放式接口、图片管理工具等。如下:

<template><div ref="dropZoneRef" class="drop-zone" :class="{ 'over': isOverDropZone }">拖拽文件到这个地方 {{ isOverDropZone }}</div><ul v-if="state.name"><li>{{ state.name }}</li><li>{{ state.size }}</li><li>{{ state.type }}</li></ul><img src="./assets/1.jpg" alt="" style="width: 100px; height: 100px;">
</template><script lang="ts" setup>
import { ref, reactive } from 'vue'
import { useDropZone } from '@vueuse/core'const dropZoneRef = ref<HTMLDivElement>()
let state = reactive({}) as anyfunction onDrop(files: any) {state = files[0]console.log(state)
}
const { isOverDropZone } = useDropZone(dropZoneRef, onDrop)
</script><style>.drop-zone {width: 500px;border: 2px dashed #ccc;padding: 20px;text-align: center;}.drop-zone.over {background-color: #f0f0f0;}
</style>

最终得到的结果如下:

useElementBounding(响应边界数据)

让HTML元素的bounding box 响应式。什么意思呢?就是可以获取指定元素的位置、宽度、高度等边界信息。这对于实现响应式布局或者对元素进行定位、动画等操作非常有用。当元素的边界发生变化时(例如窗口大小变化导致元素位置或尺寸变化),相关的响应式数据也会自动更新,从而保持界面的同步性。这里我们搭配上文讲解到的拖拽元素的API一起使用,如下:

<template><div ref="el" class="use-element-bounding" :style="style" style="position: fixed;">位置信息:<br />x: {{ x }}<br />y: {{ y }}<br />top: {{ top }}<br />left: {{ left }}<br />right: {{ right }} <br />bottom: {{ bottom }}<br />width: {{ width }}<br/>height: {{ height }}<br/></div>
</template><script lang="ts" setup>
import { ref } from 'vue'
import { useElementBounding, useDraggable } from '@vueuse/core'const el = ref(null)const { x, y, style } = useDraggable(el, {initialValue: { x: 40, y: 40 }, // 初始位置
})const { top, right, bottom, left, width, height } = useElementBounding(el, {reset: true, // 组件卸载时重置边界信息windowResize: true, // 监听窗口大小调整事件windowScroll: true, // 监听窗口滚动事件immediate: true, // 组件挂载时立即调用
})
</script><style scoped>
.use-element-bounding {background: #e5e5e5;border: 1px solid #ccc;padding: 10px;border-radius: 4px;width: 200px;height: 200px;color: #333;user-select: none;
}
</style>

最终得到的结果如下:

useElementSize(获取指定元素宽高)

元素尺寸大小响应式。什么意思呢?就是获取指定元素的宽度和高度,这对于布局和样式计算非常有用。基于元素的尺寸信息,你可以根据需要动态地调整布局和样式。例如,可以根据元素的宽度和高度选择合适的样式或者调整其他元素的位置和大小。如下:

<template><div>width: {{ width }}<br>height: {{ height }}</div><textarea ref="el" class="use-element-size"></textarea>
</template><script lang="ts" setup>
import { ref } from 'vue'
import { useElementSize } from '@vueuse/core'const el = ref(null)
const { width, height } = useElementSize(el)
</script><style scoped>
.use-element-size {background: #e5e5e5;border: 1px solid #ccc;padding: 10px;border-radius: 4px;width: 200px;height: 200px;color: #333;
}
</style>

最终得到的结果如下:

useResizeObserver(监听元素内容和边框尺寸变化)

监听元素内容和边框尺寸的变化。什么意思呢?就是用于观察指定元素的大小变化,并在大小变化时执行相应的回调函数。如下:

<template><div>{{ text }}</div><textarea class="use-resize-observer" ref="el"></textarea>
</template><script lang="ts" setup>
import { ref } from 'vue'
import { useResizeObserver } from '@vueuse/core'const el = ref(null)
const text = ref('')useResizeObserver(el, (entries) => {const entry = entries[0]const { width, height } = entry.contentRecttext.value = `width: ${width}, height: ${height}`
})
</script><style>
.use-resize-observer {width: 200px;height: 200px;background: #ccc;
}
</style>

最终得到的结果如下: 

useResizeObserver 和 useElementSize 都是 VueUse 中用于监测元素大小变化的函数,但它们之间有一些区别

实现原理

1)useElementSize 则是通过监听 window 的 resize 事件以及元素的 scroll 事件,并结合获取元素的 clientWidth 和 clientHeight 属性来计算元素的大小变化。

2)useResizeObserver 使用的是 Resize Observer API,它能够在元素大小变化时立即触发回调函数。
浏览器支持

1)useElementSize 的实现方式则更依赖于浏览器的 resize 和 scroll 事件,可能存在一些兼容性问题。
2)Resize Observer API 的支持程度较高,大多数现代浏览器都支持。

精确度

由于 Resize Observer API 是专门用于监测元素大小变化的 API,因此在性能和精确度上可能会优于通过 resize 和 scroll 事件计算大小的方法。

使用场景

1)如果你的项目需要考虑到一些老版本浏览器的兼容性,并且对性能要求不是特别高,可以考虑使用 useElementSize。

2)如果你需要在元素大小变化时立即触发回调函数,并且希望在现代浏览器中使用,则可以选择 useResizeObserver。

综上所述

useResizeObserver 更适合现代化的项目,并且提供了更好的性能和精确度,而 useElementSize 则更适合需要考虑兼容性和性能要求不那么严格的项目。

useElementVisibility(跟踪元素可见性)

跟踪元素在视口中的可见性。什么意思呢?就是用于检测元素的可见性,可以帮助你监听指定元素的可见状态,即当元素进入或离开视窗时,相关的可见性状态会被更新。通过检测元素的可见性,你可以延迟加载页面中的图片、视频或其他资源,从而提高页面的加载性能和用户体验。当元素进入视窗时,再开始加载相应的内容。

举个经典的例子,当你电脑浏览b站视频的时候,你想刷一下评论区,当你鼠标滚动,原本的视频离开可视窗口的那一瞬间,右下角会给你打开一个小窗口,当你回到原本的视频窗口后,小窗口就会消失,就是这个道理!

案例代码如下:

<template><div class="use-element-visiblity"><div ref="target" class="target">向下滚动到可视区域</div><div class="tips-zone">提示内容{{ targetIsVisible }}</div></div>
</template><script lang="ts" setup>
import { ref } from 'vue'
import { useElementVisibility } from '@vueuse/core'const target = ref(null)
const targetIsVisible = useElementVisibility(target)
</script><style scoped lang="scss">
.use-element-visiblity {height: 100%;height: 200vh;background-color: #eee;.target {width: 200px;height: 200px;background-color: red;}.tips-zone {position: fixed;bottom: 20px;right: 20px;z-index: 9;border: 2px dashed #ccc;padding: 20px;}
}
</style>

最终得到的结果如下:

useIntersectionObserver(指定元素交集变化)

响应式监听目标元素的可见性。什么意思呢?就是监听指定元素与其祖先元素或视窗的交集变化。当元素进入或离开视窗,或者与祖先元素的交集变化时,相关的回调函数会被触发。如下:

<template><div class="use-intersection-observer"><div class="box"><div class="p1">向下滚动</div><div class="p2" ref="target">监听可视区域内容</div><div class="p3">最底部</div></div><div class="tip">元素在窗口内 {{ targetIsVisible }}</div></div>
</template><script lang="ts" setup>
import { ref } from 'vue'
import { useIntersectionObserver } from '@vueuse/core'const target = ref(null)
const targetIsVisible = ref(false)
const { stop } = useIntersectionObserver(target,([{ isIntersecting }], observerElement) => {targetIsVisible.value = isIntersecting}
)
</script><style scoped lang="scss">
.use-intersection-observer {width: 500px;.box {border: 2px dashed #ccc;height: 100px;overflow-y: auto;padding: 20px;.p1, .p3 {padding: 30px;}.p2 {margin-top: 100px;}}
}
</style>

最终得到的结果如下:

useMouseInElement(跟踪鼠标指定元素状态)

响应式获取鼠标相对于元素的位置。什么意思呢?就是用于跟踪鼠标在指定元素内的位置和状态,实时获取鼠标相对于指定元素的位置信息,包括水平和垂直方向的坐标,通过实时追踪鼠标在元素内的位置和状态,可以为用户提供更加灵活、智能的交互体验,从而增强用户对网页或应用的满意度。如下:

<template><div ref="el" class="use-mouse-in-element"><div ref="target" class="content">相对内容</div>位置信息:<br />x: {{ x }}<br />y: {{ y }}<br />sourceType: {{ sourceType }}<br />elementX: {{ elementX }}<br />elementY: {{  elementY }}<br />elementPositionX: {{ elementPositionX }}<br />elementPositionY: {{ elementPositionY }}<br />elementHeight: {{ elementHeight }}<br />elementWidth: {{  elementWidth }}<br />isOutside: {{  isOutside }}<br /></div>
</template><script lang="ts" setup>
import { ref } from 'vue'
import { useMouseInElement } from '@vueuse/core'const target = ref(null)
const { x, y, sourceType, elementX, elementY, elementPositionX, elementPositionY, elementHeight, elementWidth, isOutside 
} = useMouseInElement(target)
</script><style scoped lang="scss">
.use-mouse-in-element {background: #e5e5e5;border: 1px solid #ccc;padding: 10px;border-radius: 4px;width: 400px;color: #333;.content {color: #fff;background: #ddd;padding: 40px;}
}
</style>

最终得到的结果如下:

useMutationObserver(监听DOM树修改)

监听DOM树修改。什么意思呢?就是用于观察指定元素及其子元素的 DOM 变化,并在发生变化时执行相应的回调函数。如下:

<template><div><h2>DOM元素监视器</h2><div ref="targetElement">监视的元素</div><button @click="changeElement">改变元素</button>{{ messages }}</div>
</template><script lang="ts" setup>
import { ref } from 'vue'
import { useMutationObserver } from '@vueuse/core'const targetElement = ref()
const messages = ref<any[]>([])useMutationObserver(targetElement, (mutations) => {console.log('DOM元素发生变化:', mutations)if (mutations[0])  messages.value.push(mutations[0].attributeName) 
}, 
{ attributes: true });// 改变DOM元素的内容
const changeElement = () => targetElement.value.style.color = 'red'
</script>

最终得到的结果如下: 

useWindowFocus(跟踪窗口焦点)

使用 window.onfocus 和 window.onblur 事件响应式跟踪窗口焦点。什么意思呢?就是实时监测浏览器窗口的焦点状态,即浏览器窗口是处于激活状态(获得焦点)还是非激活状态(失去焦点)。如下:

<template><div>{{ message }}</div>
</template><script setup lang="ts">
import { ref, watch } from 'vue'
import { useWindowFocus } from '@vueuse/core'const startMessage = '💡单击文档之外的某个位置以取消聚焦。'
const message = ref(startMessage)
const focused = useWindowFocus()watch(focused, (isFocused) => {if (isFocused)message.value = startMessageelsemessage.value = 'ℹ 选项卡未聚焦'
})
</script>

最终得到的结果如下: 

useWindowScroll(获取窗口的滚动位置)

响应式获取窗口的滚动位置。什么意思呢?就是实时监测浏览器窗口的滚动位置,包括水平和垂直方向上的滚动距离,通过监听窗口的滚动事件,你可以实现一些响应式的效果,例如根据用户滚动位置展示或隐藏导航栏、懒加载页面内容、实现无限滚动加载等。如下:

<template><div class="showTip">滚动值:<br>X轴{{ x }} - y轴{{ y }}</div><div class="windowScroll"></div>
</template><script setup lang="ts">
import { useWindowScroll } from '@vueuse/core'
const { x, y } = useWindowScroll()
</script><style scoped lang="scss">
.showTip {width: 120px;height: 50px;background: #008c8c;position: fixed;bottom: 20px;right: 20px;
}
.windowScroll {width: 10000px;height: 200vh;background: #eee;
}
</style>

最终得到的结果如下: 

useWindowSize(获取窗口尺寸)

响应式获取窗口尺寸。什么意思呢?就是用于获取浏览器窗口的尺寸信息,通过监听窗口大小变化事件,你可以实现一些响应式的布局或样式,确保页面在不同设备或窗口尺寸下都能够正确展示。如下:

<template><div class="use-window-size">width: {{ width }}, height: {{ height }}</div>
</template><script lang="ts" setup>
import { useWindowSize } from '@vueuse/core'const { width, height } = useWindowSize()
</script>

最终得到的结果如下: 

最后总结

useActiveElement:监测和响应用户与页面的交互,自动聚焦输入框或执行验证操作。

useDocumentVisibility:管理页面的可见性状态,优化用户体验和应用程序性能。

useDraggable:实现元素的拖拽功能,从而增强了应用程序的交互性和可用性。

useDropZone:在 Vue 应用中实现拖放区域,从而提升应用的交互性和用户体验。

useElementBounding:获取和管理元素的边界信息,处理元素相关的操作和交互。

useElementSize:响应式的方式获取和管理元素的尺寸信息,处理元素相关的操作和交互。

useResizeObserver:监测元素大小的变化,并实时响应变化。

useElementVisibility:监测和响应元素的可见性变化,实现与可见性相关的功能和优化。

useIntersectionObserver:实现在元素可见状态变化时自动更新相关的界面内容或状态。

useMouseInElement:追踪和监测鼠标在指定元素内的位置和状态。

useMutationObserver:监测 DOM 变化,并实时响应变化。

useWindowFocus:监测浏览器窗口的焦点状态,实现一些交互效果改善用户体验。

useWindowScroll:实时监听浏览器窗口的滚动事件,实现一些响应式效果。

useWindowSize:实时获取和响应浏览器窗口的尺寸信息,实现响应式布局。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/659750.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Three.js 的优势

Three.js 是一个非常流行的基于 WebGL 的 JavaScript 库&#xff0c;用于在浏览器中创建和展示 3D 内容。以下是 Three.js 的一些主要优势&#xff0c;这些优势使得 Three.js 成为创建和展示 3D 内容的强大工具&#xff0c;无论是对于初学者还是经验丰富的开发者。北京木奇移动…

如何在Linux上安装Python?2024Python安装教程

在Linux上安装Python并不难&#xff0c;对于Ubuntu或Debian系统&#xff0c;使用命令sudo apt install python3&#xff1b;对于CentOS、Red Hat或Fedora系统&#xff0c;使用命令sudo yum install python3。 如何在Linux上安装Python&#xff1f; 确切的安装步骤有所不同&am…

【Qt】C1060 堆空间不足

原因 搜索之后发现可能是因为 Qt添加大量资源文件,编译时就会出现内存溢出。 但很奇怪之前编译好好的&#xff0c;突然报这个错。&#xff08;卸载qt重装后&#xff09; 解决 报错提示的类文件所在的根目录的.pro文件中添加 CONFIG resources_big

Python来计算 1,2,3,4 能组成多少个不相同且不重复的三位数?

我们今天的例子是 有 1&#xff0c;2&#xff0c;3&#xff0c;4 四个数字&#xff0c;它们能组成多省个互不相同且无重复的三位数&#xff1f;都分别是多少&#xff1f; 话不多说&#xff0c;我们先上代码 num 0 # 我们写了三个for循环&#xff0c;表示生成的三位数 for i…

浏览器预加载器如何使页面加载速度更快

预加载器&#xff08;也称为推测或前瞻预解析器&#xff09;可能是浏览器性能有史以来最大的改进。 那么什么是预加载器以及它如何提高性能呢&#xff1f; 浏览器如何加载网页 网页充满了依赖关系——在下载相关的CSS之前页面无法开始渲染&#xff0c;然后当遇到脚本时HTML解…

04 Docker练习赛从0开始到 docker 镜像提交

1.1 本地安装 docker 工具 这里以ubutun下安装docker为例,其他操作系统安装命令略有不同,可自行百度。(建议使用阿里源安装速度快) sudo apt install docker.io如果你本地有gpu,请继续执行如下命令以支持gpu调用: 注意: 英伟达对 docker 支持的 linux 发行版:https:/…

springcloud微服务搭建多数据源(mysql,oracle,postgres,等等)管理模块,支持通过注解方式切换不同类型的数据库

1.背景 同一套微服务管理系统&#xff0c;业务完全一样&#xff0c;但不同的客户可能要求使用自己熟悉的数据库&#xff0c;比如&#xff0c;mysql&#xff0c;oracle&#xff0c;postgres&#xff0c;还有一些国产数据库。如果能够将数据库模块独立出来&#xff0c;兼容各家的…

前端发起网络请求的几种常见方式(XMLHttpRequest、FetchApi、jQueryAjax、Axios)

摘要 前端发起网络请求的几种常见方式包括&#xff1a; XMLHttpRequest (XHR)&#xff1a; 这是最传统和最常见的方式之一。它允许客户端与服务器进行异步通信。XHR API 提供了一个在后台发送 HTTP 请求和接收响应的机制&#xff0c;使得页面能够在不刷新的情况下更新部分内容…

[C++][算法基础]最大不相交区间数量(贪心 + 区间问题2)

给定 &#x1d441; 个闭区间 [&#x1d44e;&#x1d456;,&#x1d44f;&#x1d456;]&#xff0c;请你在数轴上选择若干区间&#xff0c;使得选中的区间之间互不相交&#xff08;包括端点&#xff09;。 输出可选取区间的最大数量。 输入格式 第一行包含整数 &#x1d4…

一、OSPF基础

目录 1.路由协议的优先级 2.转发原则&#xff1a;最长匹配原则 3.负载分担 4.路由备份&#xff08;浮动路由&#xff09; 5.路由协议的分类 6.动态路由 7.距离矢量路由协议&#xff08;BGP&#xff0c;RIP&#xff09; 8.链路状态路由协议&#xff08;OSPF&#xff0c;I…

基于SpringBoot+Vue养老院管理系统设计与实现

一、前言介绍 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装养老院管理系统软件来发挥其高效地信息处理的作用&am…

HEVC/H.265视频编解码学习笔记–框架及块划分关系

前言 由于本人在学习视频的过程中&#xff0c;觉得分块单元太多搞不清楚其关系&#xff0c;因此本文着重记录这些分块单元的概念以及关联。 一、框架 视频为一帧一帧的图像&#xff0c;其编码的主要核心是压缩空间以及时间上的冗余。因此&#xff0c;视频编码有帧内预测和帧间…