vue3自定义hook函数


1、收集用户鼠标点击页面坐标的hook函数

1.1、创建一个hooks/useMousePosition.ts文件

import {
    
     ref, onMounted, onUnmounted } from 'vue';

/* 收集用户鼠标点击的页面坐标 */

export default function useMousePosition () {
    
    
  // 初始化坐标数据
  const x = ref(-1);
  const y = ref(-1);

  // 用于收集点击事件坐标的函数
  const updatePosition = (e: MouseEvent) => {
    
    
    x.value = e.pageX;
    y.value = e.pageY;
  };

  // 挂载后绑定点击监听
  onMounted(() => {
    
    
    document.addEventListener('click', updatePosition);
  });

  // 卸载前解绑点击监听
  onUnmounted(() => {
    
    
    document.removeEventListener('click', updatePosition);
  });
  return {
    
    x, y};
};

1.2、创建页面

<template>
	<div>
		<h2>x: {
   
   {x}}, y: {
   
   {y}}</h2>
	</div>
</template>

import {
    
     ref } from "vue";

/* 
在组件中引入并使用自定义hook
自定义hook的作用类似于vue2中的mixin技术
自定义Hook的优势: 很清楚复用功能代码的来源, 更清楚易懂
*/

import useMousePosition from './hooks/useMousePosition.js'

export default {
    
    
  setup() {
    
    
    const {
    
    x, y} = useMousePosition();
    return {
    
    
      x,
      y,
    };
  }
}

2、发ajax请求的hook函数

2.1、创建hooks/useRequest.ts文件

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

/* 使用axios发送异步ajax请求 */
export default function useUrlLoader<T>(url: string) {
    
    
  const result = ref<T | null>(null);
  const loading = ref(true);
  const errorMsg = ref(null);

  axios.get(url)
    .then(response => {
    
    
      loading.value = false;
      result.value = response.data;
    })
    .catch(e => {
    
    
      loading.value = false;
      errorMsg.value = e.message || '未知错误';
    });

  return {
    
    
    loading,
    result,
    errorMsg,
  };
};

2.2、创建页面

<template>
	<div class="about">
		<h2 v-if="loading">LOADING...</h2>
		<h2 v-else-if="errorMsg">{
   
   {errorMsg}}</h2>
		<!-- <ul v-else>
				<li>id: {
    
    {result.id}}</li>
				<li>name: {
    
    {result.name}}</li>
				<li>distance: {
    
    {result.distance}}</li>
		</ul> -->

		<ul v-for="p in result" :key="p.id">
			<li>id: {
   
   {p.id}}</li>
			<li>title: {
   
   {p.title}}</li>
			<li>price: {
   
   {p.price}}</li>
		</ul>
		<!-- <img v-if="result" :src="result[0].url" alt=""> -->
	</div>
</template>

import {
    
     watch } from "vue";
import useRequest from './hooks/useRequest';

// 地址数据接口
interface AddressResult {
    
    
  id: number;
  name: string;
  distance: string;
};

// 产品数据接口
interface ProductResult {
    
    
  id: string;
  title: string;
  price: number;
};

export default {
    
    
  setup() {
    
    
    // const {loading, result, errorMsg} = useRequest<AddressResult>('/data/address.json');
    const {
    
    loading, result, errorMsg} = useRequest<ProductResult[]>('/data/products.json');

    watch(result, () => {
    
    
      if (result.value) {
    
    
        console.log(result.value.length); // 有提示
      }
    });

    return {
    
    
      loading,
      result, 
      errorMsg
    };
  }
}

3、相关链接

自定义hook函数

猜你喜欢

转载自blog.csdn.net/weixin_51157081/article/details/121273878