Composition API逻辑复用

47 阅读1分钟

子组件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