首页 > 其他分享 >vue3的composition API如何使用async语句

vue3的composition API如何使用async语句

时间:2023-06-11 09:55:42浏览次数:49  
标签:const setup await onMounted console API vue3 async

问题:
在setup 使用aysnc,生命函数钩子和函数必须出现在await 语句前面,否者会出现组件无法渲染以及内存泄漏的问题。

import { ref, watch, onMounted, onUnmounted } from 'vue' 
 export default defineAsyncComponent({   
     async setup() {     
     const counter = ref(0)      
     watch(counter, () => console.log(counter.value))          
     onMounted(() => console.log('Mounted'))     
      // the await statement     
      await someAsyncFunction() // <-----------     
       // 无法运行    
      onUnmounted(() => console.log('Unmounted'))      
        //无法自动销毁导致内存泄漏(no auto-dispose)     
      watch(counter, () => console.log(counter.value * 2))   
        } 
    })

在await 语句使用以下函数:

有限制(no auto-dispose):

  • watch / watchEffect
  • computed
  • effect
    无法运行:
  • onMounted / onUnmounted / onXXX
  • provide / inject
  • getCurrentInstance

  • 产生bug的原因

onMounted 这个钩子注册了组件挂载的监听器
is a hook that registers a listener when the current component gets mounted.
在composition api中,lifecycle钩子函数是当作全局函数使用的,以onMouted 为例,
onMounted 这个钩子监听到组件挂载才会执行注册在onMounted 内的函数。
那么onMounted 是如何监听,在vue内部框架中,要挂载组件component时,会将组件component存储为全局变量。
伪代码:

let currentInstance = null  
export function mountComponent(component) {   
    const instance = createComponent(component)       // 组件实例存至全局变量   
    currentInstance = instance   
    //组件setup调用   
    component.setup() 
}

setup伪代码:

setup() {      
function onMounted(fn) {   
     if (!currentInstance) {    
         warn(`"onMounted" can't be called outside of component setup()`)    
         return  
     } 
 // 在当前组件上注册onMounted函数   
     currentInstance.onMounted(fn) 
     }  
 }

但是造成async bug的原因是什么,首先js是个单线程语言,执行完一行代码再执行下一行代码。
而异步的话会引入下面这种情况:

//伪代码 
currentInstance = instance 
await component.setup()  
currentInstance = prev

在await 时间,其他组件的创建可能会修改全局变量,这样最后会导致一团混乱。
如果不用await 语句,像普通函数一样调用会产生什么结果?

async function setup() {   
    console.log(1)   
    await someAsyncFunction()   
    console.log(2) 
}  
console.log(3) 
setup() 
console.log(4)   
// output: 3 1 4 (awaiting) 2

这种方法导致await还未执行完,就执行下一行。同样无法正确绑定组件。
解决方案
解决方案一:
await语句放到setup函数最下面
解决方案二:
1.将async转成sync reactive

//await 
const data = await fetch('https://xxx.com/').then(r => r.json())  
const user = data.user  
//修改: 
const data = ref(null)  fetch('https://xxx.com/')   
                        .then(r => r.json())   
                        .then(res => data.value = res)  
const user = computed(() => data?.user)

2.显示绑定实例
生命周期钩子函数是可以接受第二个参数(组件实例)。

async setup() {     
 
const instance = getCurrentInstance()      
await someAsyncFunction() // <-----------      
    onUnmounted(() => console.log('Unmounted'), 
    instance // <--- pass the instance to it     
    )  
}

但是这里有个缺陷,除钩子函数像watch ,computed 等是没法接受示例参数。
3.使用vueuse提供的工具函数
useAsyncState :

import { useAsyncState } from '@vueuse/core'  
const { state, ready } = useAsyncState(async () => {   
   const { data } = await axios.get('https://api.github.com/')   
   return { data } 
   }
)  
const user = computed(() => state?.user) 

useFetch

import { useFetch } from '@vueuse/core' 
 const { data, isFetching, error } = useFetch('https://api.github.com/')  
const user = computed(() => data?.user)

解决方案三:
vue社区有个提案,提供一个aysnc语法糖withAsyncContext ,这样就能在setup中使用async语法。

标签:const,setup,await,onMounted,console,API,vue3,async
From: https://www.cnblogs.com/aliceKurapika/p/17472541.html

相关文章

  • My First CRUD App With Fast API
    ImagebyauthorIt’sthedaybeforemyfastAPIlivestream.Idecidedtocreateaguideforthestreamandturnitintoablogpost.So,hereitis.Streamstructure:FastAPIvsDjangoInstallationCreateFirstAPP&RouteSwaggerUIPathParamete......
  • 【阿里巴巴中国站API接口系列】获得1688商品详情信息-item_get-获得1688商品详情调用
    ​    1688有开放商品详情API接口,使用前需要注册成为开发者并申请API权限。以下是简单的API使用步骤:1. 获取授权key和secret:在开放平台注册获取key和secret接入。2. 构建请求:通过API接口文档构建请求,包括传递必要参数和权限设置等。3. 发送请求:使用HTTP GET或POS......
  • 【淘宝api开发系列】获得商品详情API|item_get-获得淘宝商品详情调用示例教程
    ​淘宝商品详情是指在淘宝上展示的一个商品的详细信息,包括商品的名称、图片、价格、规格参数、用户评价等内容。在商家上传商品时,一般会根据实际情况填写商品信息,并可以添加多张图片来展示商品的外观和功能特点。同时,商家也可以在商品详情中编写文字描述,详细介绍商品的特点、优势......
  • 天猫数据API接口推荐:天猫数据接口哪里看?怎么使用?
    在天猫、淘宝等电商平台中,商家要想更好地进行数据分析,就需要借助一些专业的数据接口来掌握平台中的数据,并对其进行有效分析,从而能有利于品牌运营及品牌决策。而鲸参谋电商数据分析平台既可以在线使用,还可以提供接口,商家们可以在这一接口中查询到所需的信息,非常实用。接下来我们一起......
  • 取公共的APIURL​
    取公共的APIURL​项目新增common目录,里面有个common.js constcommon={getapiurl(){ varapiurl=uni.getStorageSync("apiurl"); if(apiurl==undefined||apiurl==''){ apiurl="http://product.niunan.net"; uni.setStorageSync......
  • Promise解决并发请求和async/await解决并发请求
    有的时候会出现一种情况,就是你需要调用多次API,因为可能调一次返回的数据量过大,占满了带宽就直接卡死,但是你又不想每次只调用一个,想每次调用多个,你就可以尝试下面的方法:使用Promise解决并发问题functionasyncconcurrentRequests(args,len=10){constrecordArr=0//......
  • jenkinsapi的基础用法
    前言:想要用脚本或代码来触发Jenkins工程?不妨看看这里~模块安装pipinstalljenkinsapi或者easy_installjenkinsapi基础案例fromjenkinsapi.jenkinsimportJenkinsjenkins=Jenkins("http://*****.com:8080/",username="****",password="****",......
  • 拥抱jsx,开启vue3用法的另一种选择
    ......
  • 解析隧道代理IP与API代理IP的区别
    隧道代理IP和API代理IP是两种常见的代理IP类型,它们在实现方式和使用场景上有一些区别。第一部分:隧道代理IP的特点和用途隧道代理IP:隧道代理IP(TunnelProxyIP)是通过在客户端和目标服务器之间建立一个隧道连接来实现代理的。具体来说,隧道代理IP会在客户端和目标服务器之间扮演中间人......
  • 初始vue3——第三天
    双向绑定基本用法在前端处理表单时,我们常常需要将表单输入框的内容同步给JavaScript中相应的变量。手动连接值绑定和更改事件监听器可能会很麻烦:<input:value="text"@input="event=>text=event.target.value">v-model指令帮我们简化了这一步骤:<inputv-model="text......