当前位置: 首页 > Web前端 > vue.js

Nuxt3实战系列网络请求

时间:2023-04-01 02:11:35 vue.js

Nuxt3提供了4种异步获取数据的方式useAsyncDatauseLazyAsyncData(useAsyncData+lazy:true)useFetchuseLazyFetch(useFetch+lazy:true)这4种方式中最核心的是useAsyncData和useFetch。这两个方法不同于Nuxt2中的asyncData和fetch。接下来,让我们仔细看看这两种方法。useAsyncData我们知道,在Nuxt2中,asyncData方法类似于一个生命周期函数,在server或route更新之前被调用。该方法的参数是当前页面的上下文对象。我们一般使用asyncData方法获取数据返回给当前组件,避免客户端正在执行请求导致的数据延迟问题。exportdefault{data(){return{project:'default'}},asyncData(context){return{project:'nuxt'}}}在Nuxt3中,useAsyncData可以看作是对异步数据获取场景的封装,以及成为主动调用功能,原则上可以随时调用。//Usageconst{data:Ref,//返回的数据resultpending:Ref,//是否处于请求状态refresh:(force?:boolean)=>Promise,//MandatoryRefreshdataerror?:any//请求失败返回的错误信息}=useAsyncData(key:string,//唯一key保证同次请求数据获取和去重fn:()=>Object,//一个返回值异步函数options?:{lazy:boolean,server:boolean}//options.lazy,加载路由后是否请求异步方法,默认为false//options.server,是否在服务端请求数据,默认为true//options.default,一个工厂函数,在异步请求之前设置数据的默认值(对lazy:true选项特别有用)//options.transform,一个改变fn返回结果的函数//options.pick,onlyspecifiedfromthearraykey)从api的设计可以看出useAsyncData并没有limit我们发起网络请求的方式,它也暴露了请求状态,增加了刷新控制,重复获取数据的去重控制。用法示例如下:useFetch在Nuxt2中,fetch方法用于在渲染页面之前填充应用程序的状态树(store)数据。它类似于asyncData方法,只是它不设置组件的数据。在Nuxt3中,useFetch实际上是对useAsyncData和$fetch的封装,提供一种更方便的封装方法。与useAsyncData相比,它主要做了以下两件事:会根据url和fetch参数自动生成一个key,同时推断出API的响应类型。也就是说,不需要手动指定密钥。它实现了网络请求的具体方法,使用$fetch发起请求,意味着不需要手动实现网络请求的逻辑。//useFetch用法const{data:Ref,pending:Ref,refresh:(force?:boolean)=>Promise,error?:any}=useFetch(url:string,options?)//options(继承自unjs/ofetchoptions和AsyncDataOptions)//useAsyncData的options中没有以下参数//options.method:请求方法//options.query:url路径参数//options.params:queryAliasofparameters//options.body:请求体参数,//options.headers:请求头的配置//options.baseURL:请求的基本Url地址在实战应用中不难发现useFetch已经具备了网络请求的所有核心功能,虽然这个Api主要用于服务端请求,但也支持客户端请求,稍微改动一下封装就可以同时用于服务端和客户端请求。这样我们就不需要像axios那样引入额外的请求库了。场景一:如何处理带有错误码的数据响应通常我们的接口不会直接返回数据,而是返回一个带有错误码和错误信息的对象,比如这样://response:{data:{age:1},code:1}在这样的返回结构下,useFetch获取到的数据并不是我们真正想要的数据const{data}=awaituseFetch('/api/user/info',{method:'get'})console.log(data)//此时data是一个被Ref包裹的对象{data:{age:1},code:1}constuserInfo=unref(data).data//要得到真正的数据,需要先unref,然后获取数据,我们希望在接口返回的时候对数据进行转换。其实useFetch提供了相关的option参数。我们可以修改const{data:userInfo}=awaituseFetch('/api/user/info',{method:'get',//处理方法1onResponse({response}){response._data={...response._data.data,}},//处理方法2//transform:(res)=>{//returnres.data//},})场景二:如何只在客户端发起请求这个场景一般用于静态构建部署,但是页面上的一些内容在构建的时候是不能静态的。这时候可以使用server:false参数//异步获取当前用户信息const{data:userinfo}=awaituseMyFetch('/api/auth/userinfo',{server:false})注意:在这个case,如果你想直接在脚本中获取userinfo的内部值是不可能的!官方文档也做了相应的解释:如果你没有在服务器上取过数据(比如设置了server:false),那么直到hydration完成后才会去取数据。这意味着即使您在客户端等待useFetch,中的数据也将保持为空。如果你必须在脚本中获取数据怎么办?这里我想到了两种解决方案:使用$fetch发起请求,使用watch监听userinfo的值变化场景三:如何将请求结果转化为无响应数据这种场景一般用于客户端发起的请求,而我们也不需要在页面上渲染响应数据,只是为了做一些逻辑判断或者处理数据。useFetch请求后的返回值默认是一个ref对象,我们要先获取内部值。const{data}=awaituseMyFetch('/api/get-actiocn-token')//data是一个被Ref包裹的对象,需要使用unref获取内部值consttokenInfo=unref(data)如果要直接获取原始数据,原生不支持useFetch(或者我还不知道怎么实现)。我们只能用$fetch来实现。请求统一封装针对以上三种场景,作者分享了自己的封装思路,即在composables目录下实现一个useMyFetch方法来处理一些通用逻辑importtype{NitroFetchRequest}from'nitropack'importtype{FetchOptions,FetchResponse}from'ofetch'importtype{UseFetchOptions}from'nuxt/dist/app/composables/fetch'functiontransFormResponse({response}:any){//处理后端携带错误码response的数据if(response._data&&response._data.code)returnPromise.reject(response._data)response._data={...response._data.data,}}/***封装简单请求场景的$fetch*@paramrequest*@paramopts*@returns*/exportfunctionuseClientFetch(request:NitroFetchRequest,opts?:FetchOptions){return$fetch>(request,{onResponse:transFormResponse,...opts,})}/**复制代码*提取useFetch的通用配置*@paramrequest*@paramopts*@returns*/exportfunctionuseMyFetch(request:NitroFetchRequest,opts?:UseFetchOptions){returnuseFetch(request,{onResponse:transFormResponse,...opts,})}/***实现更方便的post请求*@paramrequest*@paramopts*@returns*/useMyFetch.get=(request:NitroFetchRequest,opts?:UseFetchOptions)=>{returnuseMyFetch(request,{method:'get',...opts,})}/***实现更方便的post请求*@paramrequest*@paramopts*@returns*/useMyFetch.post=(request:NitroFetchRequest,opts?:UseFetchOptions)=>{returnuseMyFetch(request,{method:'post',...opts,})}结语博客原文地址:Nuxt3实战系列网络请求文章联系作者:imwty2023(微信),iwhitney@163.com(电子邮件)