hooks
useVModels 优化父子组件数据的双向绑定
// 原生vue用法
const emit = defineEmits(['update:modelValue', 'update:age'])
const changeInfo = () => {
// 触发父组件值更新
emit('update:modelValue', 'Tom')
emit('update:age', 30)
}
// vueuse升级版
import { useVModels } from '@vueuse/core'
const { foo, bar } = useVModels(props)
console.log(foo.value) // props.foo
foo.value = 'foo' // emit('update:foo', 'foo')
useFullScreen 全屏展示DOM元素
import { useFullscreen } from '@vueuse/core'
const { isFullscreen, enter, exit, toggle } = useFullscreen(el)
el 要通过 ref 绑定 DOM 元素。
解构出来的值:
- isFullscreen: Boolean,表示 el 是否为全屏展示。
- enter, exit, toggle: 方法,分别对应 el 进入,退出和切换全屏。
watchDebounced 防抖
import { watchDebounced } from '@vueuse/core'
watchDebounced(
source,
() => { console.log('changed!') },
{ debounce: 500, maxWait: 1000 },
)
debounce是每次事件触发时,延迟的时间,延迟时间之内事件再次被触发则重新计时。
maxWait是最长等待时间,就是即使事件持续在被触发,到达此时也会执行一次。
watchThrottled 节流
import { watchThrottled } from '@vueuse/core'
watchThrottled(
source,
() => { console.log('changed!') },
{ throttle: 500 },
)
节流和防抖的目的都是为了减少请求数量,节流和防抖的区别是定时执行,到时间就执行被触发的事件,throttle是时长。
useIntersectionObserver 检测元素是否可见
// target表示被监听的DOM元素的 ref
// 第二个参数是回调函数,用于通知监听的动作(回调函数的第一个形参isIntersecting表示被监听的元素已经进入了可视区)
// 3、表示配置选项
// stop 是停止观察是否进入或移出可视区域的行为
const { stop } = useIntersectionObserver(
// target 是观察的目标dom容器,必须是dom容器,而且是vue3.0方式绑定的dom对象
target,
// isIntersecting 是否进入可视区域,true是进入 false是移出
// observerElement 被观察的dom,可选参数
([{ isIntersecting }], observerElement) => {
// 在此处可根据isIntersecting来判断,然后做业务,常见的有长列表、懒加载等。
},
)
利用 useIntersectionObserver 实现懒加载指令
import { useIntersectionObserver } from '@vueuse/core'
export default {
mounted(el) {
const imgSrc = el.src
el.src = ''
const { stop } = useIntersectionObserver(el, ([{ isIntersecting }]) => {
if (isIntersecting) {
el.src = imgSrc
stop()
}
})
}
}
useScrollLock 滚动锁定
import { useScrollLock } from '@vueuse/core'
const isLocked = useScrollLock(el)
isLocked.value = true // lock
isLocked.value = false // unlock
将需要锁定滚动的元素 el 传入,返回一个控制滚动锁定的 ref 对象。
onClickOutside 监听元素外部的点击
<template>
<div ref="target">
Hello world
</div>
<div>
Outside element
</div>
</template>
<script setup>
import { ref } from 'vue'
import { onClickOutside } from '@vueuse/core'
const target = ref(null)
onClickOutside(target, (event) => console.log(event))
</script>
常用于模态框和下拉框的关闭,在回调函数中修改 v-if 绑定的值为 false 即可。
useWindowSize 响应式屏幕尺寸
import { useWindowSize } from '@vueuse/core'
const { width, height } = useWindowSize()
useEventListener 添加事件监听器
import { useEventListener } from '@vueuse/core'
useEventListener(element, 'visibilitychange', (evt) => {
console.log(evt)
})
三个参数分别是:
- 元素:可以是 DOM 元素或者 ref
- 事件
- 回调函数
可以调用返回的方法来取消监听器的注册。
import { useEventListener } from '@vueuse/core'
const cleanup = useEventListener(document, 'keydown', (e) => {
console.log(e.key)
})
cleanup()
useElementBounding 获取元素边框的信息(宽高和位置)
<script setup>
import { ref } from 'vue'
import { useElementBounding } from '@vueuse/core'
const el = ref(null)
const { x, y, top, right, bottom, left, width, height } = useElementBounding(el)
</script>
useScroll 获取滚动条信息
<script setup>
import { useScroll } from '@vueuse/core'
const el = ref(null)
const { x, y, isScrolling } = useScroll(el)
</script>