Composition API实现逻辑复用的步骤:
- 抽离逻辑代码到一个函数,这个函数命令约定为
useXXX
格式(这点同React Hooks) - 在
setup
中引用函数useXXX
举下例子,定义一个获取当前鼠标位置的方法
- 第一种,直接使用
ref
定义的useMousePosition
:
这种方式,导出和导入都可以随意解构
// useMousePosition.js
import { ref, onMounted, onUnmounted } from 'vue'
// 1. 定义一个函数,抽离逻辑,命名使用 useXXX
function useMousePosition() {
// 使用ref定义
const x = ref(0)
const y = ref(0)
function update(e) {
console.log(x.value, y.value);
x.value = e.pageX
y.value = e.pageY
}
onMounted(() => {
console.log('开始监听鼠标划动事件');
window.addEventListener('mousemove', update)
})
onUnmounted(() => {
console.log('解除监听鼠标划动事件');
window.removeEventListener('mousemove', update)
})
return {
x,
y
}
}
// 导出这个函数
export default useMousePosition
<!-- 在任意一个组件,都可以调用这个方法 -->
<template>
<p>mouse position: {{x}}, {{y}}</p>
</template>
<script>
import useMousePosition from './useMousePosition'
export default {
name: 'MousePosition',
setup() {
// useMousePosition是使用ref定义变量的,这种可以解构
const { x, y } = useMousePosition()
console.log(x, y)
return {
x, y
}
}
}
</script>
- 第二种,使用
reactive
定义鼠标坐标对象
这种导出的方式,在组件中导入时是不能解构的
import { onMounted, onUnmounted, reactive } from 'vue'
export function useMousePosition2() {
// 使用reactive定义
const mouse = reactive({
x: 0,
y: 0
})
function update(e) {
mouse.x = e.pageX
mouse.y = e.pageY
}
onMounted(() => {
console.log('开始监听鼠标划动事件');
window.addEventListener('mousemove', update)
})
onUnmounted(() => {
console.log('解除监听鼠标划动事件');
window.removeEventListener('mousemove', update)
})
return {
mouse
}
}
<template>
<!-- 使用对象方式显示信息 -->
<p>mouse position2: {{mouse.x}}, {{mouse.y}}</p>
</template>
<script>
import { useMousePosition2 } from './useMousePosition'
export default {
name: 'MousePosition',
setup() {
// useMousePosition2是使用reactive定义的,这种不可以解构
const { mouse } = useMousePosition2()
return {
mouse
}
}
}
</script>
- 第三种,使用
toRefs
使用这种方式,可以将reactive
对象,解构为ref
对象
export function useMousePosition3() {
// 使用reactive定义
const mouse = reactive({
x: 0,
y: 0
})
function update(e) {
mouse.x = e.pageX
mouse.y = e.pageY
}
onMounted(() => {
console.log('开始监听鼠标划动事件');
window.addEventListener('mousemove', update)
})
onUnmounted(() => {
console.log('解除监听鼠标划动事件');
window.removeEventListener('mousemove', update)
})
// 这里,使用toRefs解构成ref对象
return toRefs(mouse)
}
<template>
<p>mouse position: {{x}}, {{y}}</p>
</template>
<script>
import { useMousePosition3 } from './useMousePosition'
export default {
name: 'MousePosition',
setup() {
// 使用reactive定义鼠标坐标对象,然后通过toRefs将其解构成ref对象
const { x, y } = useMousePosition()
console.log(x, y)
return {
x, y
}
}
}
</script>
三种方式都可以实现,但是我们一般使用时,都会返回ref
对象,所以比较建议使用第一种和第三种,尽量不使用第二种
网友评论