🗒️最佳实践

解构

VueUse 中的大多数函数都会返回一个 refs object,可以使用 ES6 的 object destructure 语法来获取需要的内容。

import { useMouse } from '@vueuse/core'

// "x" and "y" are refs
const { x, y } = useMouse()
console.log(x.value)

const mouse = useMouse()
console.log(mouse.x.value)

如果更喜欢将它们用作 object properties,则可以使用 reactive() unwrap refs。

import { reactive } from 'vue'
import { useMouse } from '@vueuse/core'

const mouse = reactive(useMouse())

// "x" and "y" will be auto unwrapped, no `.value` needed
console.log(mouse.x)

副作用清理

与 Vue 的 watch 类似,computed 也会被 disposed(释放)在组件 unmounted 的时候,VueUse 的函数也会自动清除副作用。

比如,在组件 unmounted 时,useEventListener 会调用 removeEventListener。所有的 VueUse 函数都遵循此约定。

// will cleanup automatically
useEventListener('mousemove', () => {})

为了手动处理副作用,一些函数会返回一个 stop handler,比如 watch

const stop = useEventListener('mousemove', () => {})

// unregister the event listener manually
stop()

并非所有的函数都会返回 stop handler,因此更通用的解决方法是使用 Vue 的 effectScope API。

import { effectScope } from 'vue'

const scope = effectScope()

scope.run(() => {
  // ...
  useEventListener('mousemove', () => {})
  onClickOutside(el, () => {})
  watch(source, () => {})
})

// all composables called inside `scope.run` will be disposed
scope.stop()

Reactive 参数

在 Vue 中,我们使用 setup() 函数来构建 data 和 logic 之间的连接。为了使其灵活,大多数 VueUse 函数还接受参数的 refs,因为 refs 是 reactive 的。

useTitle 举例,如下:

Non-Reactive 参数

composable(可组合项)useTitle 可以获取和设置当前页面的 document.title 属性。

const isDark = useDark()
const title = useTitle('Hello')

console.log(document.title) // "Hello"

watch(isDark, () => {
  title.value = isDark.value ? '🌙 Good evening!' : '☀️ Good morning!'
})

Ref 参数

也可以给 useTitle 传入 ref 而不是使用返回的 ref。

const isDark = useDark()
const title = computed(() => isDark.value ? '🌙 Good evening!' : '☀️ Good morning!')

useTitle(title)

Reactive Getter 参数

自 VueUse 9.0,引入了一种新的约定,用于传递 Reactive Getter 参数,这对于 reactive objects 和 Reactivity Transform 非常有效。

const isDark = useDark()

useTitle(() => isDark.value ? '🌙 Good evening!' : '☀️ Good morning!')

Last updated