子组件index.vue
<template>
<p>mouse position {{ x }} {{ y }}</p>
<!-- <p>mouse position {{ state.x }} {{ state.y }}</p> -->
</template>
<script setup>
// import useMousePosition from "./useMousePosition";
import useMousePosition2 from "./useMousePosition";
// const { x, y } = useMousePosition();
// const state = useMousePosition2()
//这里如果useMousePosition2的返回值没有包裹toRefs的话,这里的x,y会丢失响应性。
const { x, y } = useMousePosition2();
</script>
useMousePosition.js 逻辑复用部分
import { reactive, ref, onMounted, onUnmounted,toRefs } from 'vue'
// function useMousePosition() {
// const x = ref(0)
// const y = ref(0)
// function update(e) {
// x.value = e.pageX
// y.value = e.pageY
// }
// onMounted(() => {
// console.log('useMousePosition mounted')
// window.addEventListener('mousemove', update)
// })
// onUnmounted(() => {
// console.log('useMousePosition unMounted')
// window.removeEventListener('mousemove', update)
// })
//由于x,y是ref类型,所以可以在使用的组件中直接使用,不丢失响应性。
// return {
// x,
// y
// }
// }
function useMousePosition2() {
const state = reactive({
x: 0,
y: 0
})
function update(e) {
state.x = e.pageX
state.y = e.pageY
}
onMounted(() => {
console.log('useMousePosition mounted')
window.addEventListener('mousemove', update)
})
onUnmounted(() => {
console.log('useMousePosition unMounted')
window.removeEventListener('mousemove', update)
})
//这里使用了toRefs进行返回,可以在使用的组件中进行返回值的解构,然后直接在模板中使用解构后的值。
//如果直接返回state,就只能在使用的组件模板中用state.x去访问,这样也可保持响应性。
return toRefs(state)
}
// export default useMousePosition
export default useMousePosition2