vue3.x系列之封装响应式的hooks技巧

v3.x封装一个接口请求的hooks的,都应该很熟练了,那么要实现一个响应式的hooks该怎么做?

实现效果

代码实现

js 复制代码
<template>
  <div v-if="error">Oops! Error encountered: {{ error.message }}</div>
  <div v-else-if="data">
    Data loaded:
    <pre>{{ data }}</pre>
  </div>
  <div v-else>Loading...</div>
  <button @click="url = 'https://jsonplaceholder.typicode.com/todos/2'">发送</button>
</template>

<script setup>
import { useFetch } from "@/hooks/useFetch";
import { ref } from "vue";
let url = ref("https://jsonplaceholder.typicode.com/todos/1");
const { data, error } = useFetch(url);
</script>
js 复制代码
import { delay } from "lodash-es";
import { ref, watchEffect, toValue } from "vue";

export function useFetch(url) {
  const data = ref(null);
  const error = ref(null);
  function fetchData() {
    fetch(toValue(url))
      .then((res) => res.json())
      .then((res) => {
        delay(() => {
          data.value = res;
        }, 2000);
      })
      .catch((err) => (error.value = err));
  }
  watchEffect(() => {
    fetchData();
  });
  return { data, error };
}

技巧总结

  • 这里我们传入的是一个url接口的ref,不是普通的字符串数据
  • hooks里面接收的时候,接口请求使用toValue转为普通的字符数据
  • watchEffect监听副作用,当ref数据变化时,及时响应来发起新的请求
  • delay方法模拟接口请求延时效果,区分出请求中的状态

v3.x的几个工具方法isRef,unref,toRef的对比

js 复制代码
// isRef  判断是否是ref类型
let url = ref("https://jsonplaceholder.typicode.com/todos/1");
const str = "hello world";
console.log(isRef(url), "isRef");
console.log(isRef(str), "isRef");
js 复制代码
// unref 解包ref
const unRefUrl = unref(url);
console.log("unRefUrl", unRefUrl);
console.log(unref(str), "unRefStr");
js 复制代码
// toRef 包装ref,可以将值、refs 或 getters 规范化为 refs (3.3+)。
const toRefUrl = toRef(url);
console.log("toRefUrl", toRefUrl);
console.log(toRef(str), "toRefStr");
js 复制代码
const state = reactive({
  foo: 1,
  bar: 2
});
const foo = toRef(state, "foo");

const foo1 = ref(state.foo);

上面这个 ref 不会和 state.foo 保持同步,因为这个 ref() 接收到的是一个纯数值。

  • toRef和ref的区别如下图
相关推荐
憧憬成为web高手5 小时前
ACTF 12307复现
前端·bootstrap·html
wordbaby6 小时前
Axios 上传大文件崩溃:鸿蒙 RNOH 下 XHR 返回空响应头引发的"假失败"
前端·react native
wordbaby6 小时前
React Native 列表分页实战:下拉刷新与上拉加载的工程化方案
前端·react native
wordbaby7 小时前
脱离 Tab 栏的艺术:React Native 全屏子页面的导航架构实践
前端·react native·harmonyos
陈随易7 小时前
Redis 8.8发布,一定要更新
前端·后端·程序员
wordbaby7 小时前
React Native 新架构落地鸿蒙:跨三端政务级应用的工程实践与深度复盘
前端·react native·harmonyos
excel8 小时前
为什么我推荐使用 Termius:现代 SSH 工具的完整体验
前端·后端
ZC跨境爬虫9 小时前
模块化烹饪小程序开发日记 Day7:(菜谱详情接口开发与JSON数据读取全流程)
前端·javascript·css·ui·微信小程序·json
এ慕ོ冬℘゜9 小时前
JS 前端基础面试题
开发语言·前端·javascript
LaughingZhu9 小时前
Product Hunt 每日热榜 | 2026-05-25
前端·人工智能·经验分享·chatgpt·html