React,Vue3自定义Hooks

11 篇文章 0 订阅

React自定义hooks是一种用于共享逻辑和状态逻辑的强大方式,可以帮助你在不同的组件之间复用代码。自定义hooks是普通的JavaScript函数,它们以"use"开头,并且可以调用React的内置hooks,如useState、useEffect、useContext等

在Vue3中,虽然没有像React中的自定义hooks一样的直接概念,但你可以使用Composition(组合式) API的功能来创建自己的可复用逻辑。你可以将逻辑封装到函数中,然后在组件中使用它们。

下面用React封装一个异步请求的Hooks

使用Vue封装一个自动获取焦点的

异步请求

import { useState, useEffect } from 'react';
import axios from 'axios';

function useAxios(url) {
  // 初始化状态
  const [data, setData] = useState(null); // 存储响应数据
  const [loading, setLoading] = useState(false); // 控制加载状态
  const [error, setError] = useState(null); // 存储错误信息

  useEffect(() => {
    // 创建异步请求函数
    const fetchData = async () => {
      setLoading(true); // 开始加载
      setError(null); // 清除之前的错误

      try {
        // 发起 GET 请求
        const response = await axios.get(url);
        setData(response.data); // 保存响应数据
      } catch (err) {
        setError(err); // 处理错误
      } finally {
        setLoading(false); // 完成加载
      }
    };

    // 调用异步请求函数
    fetchData();
  }, [url]); // 仅在 URL 改变时触发

  // 返回数据、加载状态和错误状态
  return { data, loading, error };
}

export default useAxios;

使用 Axios 进行异步请求的组件中使用这个自定义 hooks

import React from 'react';
import useAxios from './useAxios'; // 导入自定义 hooks

function MyComponent() {
  // 使用自定义 hooks,传入 API URL
  const { data, loading, error } = useAxios('https://api.example.com/data');

  if (loading) {
    return <div>Loading...</div>;
  }

  if (error) {
    return <div>Error: {error.message}</div>;
  }

  if (!data) {
    return null;
  }

  return (
    <div>
      {/* 在这里显示数据 */}
    </div>
  );
}

export default MyComponent;

Vue3 拖拽:

<template>
  <div ref="draggableElement" class="draggable-element">
    Drag me!
  </div>
</template>

<script>
import { ref, onMounted, onUnmounted } from 'vue';

// 创建自定义Composition API拖拽Hook
function useDraggable(elementRef) {
  const x = ref(0); // 存储元素的X坐标
  const y = ref(0); // 存储元素的Y坐标
  const isDragging = ref(false); // 控制拖拽状态

  // 处理鼠标按下事件
  const handleMouseDown = (event) => {
    isDragging.value = true;
    const element = elementRef.value;
    x.value = event.clientX - element.getBoundingClientRect().left;
    y.value = event.clientY - element.getBoundingClientRect().top;
    document.addEventListener('mousemove', handleMouseMove);
    document.addEventListener('mouseup', handleMouseUp);
  };

  // 处理鼠标移动事件
  const handleMouseMove = (event) => {
    if (isDragging.value) {
      const element = elementRef.value;
      element.style.left = event.clientX - x.value + 'px';
      element.style.top = event.clientY - y.value + 'px';
    }
  };

  // 处理鼠标释放事件
  const handleMouseUp = () => {
    isDragging.value = false;
    document.removeEventListener('mousemove', handleMouseMove);
    document.removeEventListener('mouseup', handleMouseUp);
  };

  // 在组件挂载时设置初始样式和事件监听
  onMounted(() => {
    const element = elementRef.value;
    element.style.position = 'absolute';
    element.style.cursor = 'grab';
    element.addEventListener('mousedown', handleMouseDown);
  });

  // 在组件卸载时移除事件监听
  onUnmounted(() => {
    const element = elementRef.value;
    element.removeEventListener('mousedown', handleMouseDown);
  });

  return { x, y };
}

export default {
  setup() {
    const draggableElement = ref(null);
    const { x, y } = useDraggable(draggableElement);

    return { x, y, draggableElement };
  },
};
</script>

<style scoped>
.draggable-element {
  width: 100px;
  height: 100px;
  background-color: lightblue;
}
</style>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值