vue3-自定义hook函数

1,152 阅读1分钟

hooks函数类似于vue2中的混入mixins

视频

src\App.vue

<template>
    <h2>自定义hook函数操作</h2>
    <h2>x:{{x}},y:{{y}}</h2>
    <hr>
    <!-- 对象数据 -->
    <h3 v-if="loading">正在加载中...</h3>
    <h3 v-else-if="errorMsg">错误信息:{{errorMsg}}</h3>
    <ul v-else>
        <li>id:{{data.id}}</li>
        <li>address:{{data.address}}</li>
        <li>distance:{{data.distance}}</li>
    </ul>
    <hr>
    <!-- 数组数据 -->
    <ul v-for="item in data" :key="item.id">
        <li>id:{{item.id}}</li>
        <li>title:{{item.title}}</li>
        <li>price:{{item.price}}</li>
    </ul>
</template>

<script lang="ts">
import { defineComponent, watch } from 'vue'
// 点击鼠标获取当前位置
import useMousePosition from './hooks/useMousePosition'
// 请求方法封装
import useRequest from './hooks/useRequest'

// 定义接口,约束对象的类型
interface IAddressData {
    id: number
    address: string
    distance: string
}
interface IProductData {
    id: number
    title: string
    price: number
}

export default defineComponent({
    name: 'App',
    setup() {
        const { x, y } = useMousePosition()

        // 对象数据
        // const { loading, data, errorMsg } = useRequest<IAddressData>('/data/address.json')
        // 数组数据
        const { loading, data, errorMsg } = useRequest<IProductData[]>(
            '/data/products.json'
        )

        watch(data, () => {
            if (data.value) {
                console.log(data.value.length)
            }
        })

        return { x, y, loading, data, errorMsg }
    },
})
</script>

src\hooks\useMousePosition.ts

import { onBeforeUnmount, onMounted, ref } from 'vue'

export default function() {
    const x = ref(-1)
    const y = ref(-1)

    // 点击事件回调函数
    const clickHandler = (event: MouseEvent) => {
        x.value = event.pageX
        y.value = event.pageY
    }

    // 页面加载完毕,添加事件
    onMounted(() => {
        window.addEventListener('click', clickHandler)
    })

    // 页面卸载之前,卸载事件
    onBeforeUnmount(() => {
        window.removeEventListener('click', clickHandler)
    })

    return { x, y }
}

src\hooks\useRequest.ts

import { ref } from 'vue'
import axios from 'axios'

export default function<T>(url: string) {
    const loading = ref(true)
    const data = ref<T | null>(null)
    const errorMsg = ref('')
    axios
        .get(url)
        .then((response) => {
            loading.value = false
            data.value = response.data
        })
        .catch((error) => {
            loading.value = false
            errorMsg.value = error.message || '未知错误'
        })

    return { loading, data, errorMsg }
}

public\data\address.json

{
    "id": 1,
    "address": "上海市松江区",
    "distance": "1000m"
}

public\data\products.json

[
    {
        "id": "001",
        "title": "华为手机",
        "price": 3000
    },
    {
        "id": "002",
        "title": "小米手机",
        "price": 2000
    }
]