写点什么

如何手撸一个 Vue 3.0 异步函数 API?

  • 2019-08-02
  • 本文字数:2030 字

    阅读完需:约 7 分钟

如何手撸一个Vue 3.0异步函数API?

在上次 Xebia 知识交流(Xebia Knowledge Exchange )活动中,我们用 Vue 函数 API 进行了实验,并创建了 vue-async-function,这个函数现在就可以用于你的 Vue 项目!让我们深入研究,看看它会为我们带来什么。

Vue 异步函数的背景

不久前,React 团队发布了 React Hooks。这是一种管理 React 组件中状态的新方法,无需使用传统的类语法。Vue.js 团队希望在下一个主要版本的 Vue 引入类似的语法。他们创建了一份提案 / 公开讨论文档 ,并正在开发与提案保持同步的实现。尽管这一实现仍处于激烈的讨论之中,但还是可以作为 Vue2 的插件来使用。


Xebia 知识交流活动中,我们的目标是分享知识,激励他人。幸运的是,React Async 的创建者 Gert 也加入了我们的行列,他认为,从他的库中重新实现 useAsyncuseFetch hook 是个不错的主意。我们继续开发,不到一个小时,我们就成功地重新实现了这两个函数的基本版本。

开发过程

完成安装说明后,让我们以单文件组件格式来创建一个新组件:


<template>  <h2>useAsync example</h2></template> <script>export default {};</script>
复制代码


现在,我们将介绍一个要调用的异步函数:


// ... template
<script>async function loadStarship({ id }) { const headers = { Accept: "application/json" }; const res = await fetch(`https://swapi.co/api/starships/${id}/`, { headers }); if (!res.ok) throw new Error(res); return res.json();}
export default {};</script>
复制代码


函数 loadSpaceship 将从 Star Wars API 获取一些数据。如果获取成功,它将返回 JSON 格式的数据,否则将抛出。


现在,我们想要:


  • 在组件创建时调用此函数。

  • 显示加载指示器。

  • 提供有关数据可用性的数据。

  • 由于某种原因获取失败。


如果没有 Vue 函数 API,你现在需要添加:


  • 一种 data 方法,用于准备加载、错误和数据反应属性。

  • 一种 created 生命周期方法,用于调用更新反应属性的函数。


随着时间的推移,这些可能会与其他生命周期和数据问题混合在一起。如此一来,会使你的代码更难以理解,也降低了它的可重用性。当然,你已经有了某些设计模式来区分这些问题,例如,通过混合或继承。Vue 函数 API 提供了一种以直观的方式区分这些问题的新方法。让我们来看看是如何工作的:


<template>  <div>    <h2>useAsync example</h2>    <div v-if="isLoading">Loading...</div>    <div v-else-if="error">Error!</div>    <div v-else>{{ data }}</div>  </div></template>
<script>import { value, onCreated } from "vue-function-api";
// ... same loadStarship function
export default { setup() { const isLoading = value(true); const error = value(null); const data = value(null);
onCreated(async () => { try { const result = await loadStarship({ id: 2 }); data.value = result; } catch (e) { error.value = e; } finally { isLoading.value = false; } });
return { isLoading, error, data, }; } };</script>
复制代码


我们可以通过错误处理来扩展这个示例代码,并使用其他生命周期方法来使它更好。然而,这并不是 Vue 函数 API 的意义所在。在 setup 函数中,我们现在讲数据和生命周期问题组合在一起。更好的是,我们可以把他们放在不同的函数中。这是区分不同问题的首选方法,这就是 vue-function-api 的用武之地。

useAsync 与 useFetch

让我们看看使用 useAsync 时,这个示例代码是什么样的:


// ... same template
<script>import { useAsync } from "vue-async-function";
// ... same loadStarship function
export default { setup() { const { data, error, isLoading } = useAsync(loadStarship, { id: 2 }); return { data, error, isLoading }; }};</script>
复制代码


这示例代码也太短了吧!我们还可以把它变得更短。获取数据是如此常见,以至于有个专门的 useFetch 函数:


// ... same template <script>import { useFetch } from "vue-async-function"; export default {  setup() {    const id = 2;    const { data, error, isLoading } = useFetch(`https://swapi.co/api/starships/${id}/`, {       headers: { Accept: "application/json" }    });    return { data, error, isLoading };  }};</script>
复制代码


额外好处是:当你使用 useAsync 时,还会收到一个 AbortcController.signal,当组件被销毁时,可以连接起来中止网络请求。如果你使用 useFetch,这个问题已经得到解决。

结论

新的 Vue 函数 API 带来了好处:经过深思熟虑的设计模式。编写可重用的 Vue 函数感觉更为直观,并且你可以轻松地与他人分享。开发 useAsyncuseFetch 函数帮助程序更顺利的执行。


有关代码或安装 npm 包,请参见 vue-async-function repo。参见示例 repo 中的更多示例代码。


英文原文:https://xebia.com/blog/next-generation-async-functions-with-vue-async-function/


2019-08-02 10:162897
用户头像

发布了 540 篇内容, 共 293.1 次阅读, 收获喜欢 1572 次。

关注

评论

发布
暂无评论
发现更多内容

数据与广告系列二:计算广告和推荐系统

黄崇远@数据虫巢

数据挖掘 大数据 互联网 广告 推荐系统

Tomcat学习分享

李印

tomcat

鄙视链 & 全栈

伯薇

学习 能力提升 全栈

MySQL实战四十五讲基础篇总结(四)

一个有志气的DB

MySQL 索引结构

Java 数据持久化系列之JDBC

程序员历小冰

Java JDBC 持久化

谈即时编译优化-以异常堆栈丢失为例

寻筝

谈谈我的云笔记使用之路

读钓

学习 个人成长 写作

宏在C++中的替代解决方案

老王同学

c++ 模板 template

《陆蓉行为金融学讲义》 - 读后感

石云升

读书笔记 投资 行为金融学 理性 公平

RabbitMQ-AMQP

云淡风轻

RabbitMQ

其实,还是让我挺震惊的,程序员的换行率竟然高达 40%

非著名程序员

程序员 程序人生 自我思考

音视频会议系统-Janus的安装与布署

音视频专家-李超

音视频 WebRTC

Algorithm week 1: Merge Two Sorted Lists

猫吃小怪兽

算法 链表 ARTS 打卡计划

ARTS week1

紫枫

ARTS 打卡计划

MySQL实战四十五讲基础篇总结(五)

一个有志气的DB

MySQL 索引

使用 webpack 搭建一个简单的 React 脚手架

张张张小烦

react.js

Spring Security密码登录流程源码分析

读钓

源码分析 spring security springboot

ARTS打卡Week 01

teoking

android WebRTC

时间管理的本质

史方远

职场 心理 成长

leetcode练级-两数之和

幸福三寸日光

算法 LeetCode js

MySQL实战四十五讲基础篇总结(六)

一个有志气的DB

MySQL 读写锁

【万字图文-原创】 | 学会Java中的线程池,这一篇也许就够了!

一枝花算不算浪漫

并发编程 jdk源码 线程池

云直播平台的选型与使用

音视频专家-李超

MySQL实战四十五讲基础篇总结(七)

一个有志气的DB

MySQL 性能

k8s 上运行我们的 springboot 服务之——我们的springboot能够在k8s上运行

柠檬

k8s istio springboot

编程入门整理

紫枫

读书笔记

关于工作的一点总结

李印

工作思路

谈谈控制感(9):提升控制感排名第一的武器

史方远

职场 心理 成长

从引用聊一聊 Java 垃圾回收

Rayjun

Java 引用 对象

ArrayList 源码分析

读钓

Java 源码分析 jdk源码

青春期的打油诗

李印

随笔

如何手撸一个Vue 3.0异步函数API?_语言 & 开发_Albert Brand_InfoQ精选文章