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
對象,所以比較建議使用第一種和第三種,儘量不使用第二種
</article>