春风得意马蹄疾
一日看尽长安花

Vue3.0 Suspense组件

Suspense是Vue3.0推出的一个内置特殊组件,用来定义具有异步请求数据的组建的显示。如果使用Suspense,要setup函数中需要返回一个promise.

例1

新建AyncShow.vue文件,setup函数需要返回一个Promise对象

<template>
    <h1>{{result}}</h1>
</template>
<script lang="ts">
export default {
    setup(){
        return new Promise((resoluve)=>{
            setTimeout(()=>{
                resolve({result: 100})
            }, 2000)
        })
    }
}
</script>

在App.vue文件中使用

<template>
  <Suspense>
      <template #default> 
        <div>
          <AsyncShow/>
        </div>
      </template>
      <template #fallback>
        <h1>Loading...</h1>
      </template>
  </Suspense>
</template>

<script lang="ts">
import { defineComponent, ref, toRefs} from 'vue';
import AsyncShow from './components/AsyncShow.vue';
export default defineComponent({
  name: 'App',
  components: {
    AsyncShow
  }
});
</script>
  • Suspense组件内置了两个具名插槽slot,一个是default,用来显示异步组件请求成功的内容;一个是fallback用来显示异步组件请求响应前页面显示的内容
  • default插槽可以有多个组件,但是需要有一个根节点

例2

模拟发送异步请求完成之后,显示组件。这里先介绍一个好用的后端请求接口:https://dog.ceo/dog-api/ 来随机获取狗狗的图片。首先我们先封装一个ajax的get请求方法:

//ajax.ts
function getAjax(url: string){
    return new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest();
        xhr.open('GET', url, true);
        xhr.send();
        xhr.onreadystatechange = function(){
            if(xhr.readyState === 4){
                if(xhr.status === 200){
                    resolve(xhr.response)
                }else{
                    reject(xhr.response);
                }
            }
        }
        xhr.onerror = ()=>{
            reject(xhr.response);
        }
    });
}
export default getAjax;

再封装一个请求狗狗图片的组件

//DogShow.vue 
<template>
    <img :src="rawData">
</template>
<script lang="ts">
import {defineComponent} from 'vue';
import getAjax from '../ajax';
export default defineComponent({
    async setup(){
    const p = getAjax("https://dog.ceo/api/breeds/image/random");
    let rawData;
    await p.then((result) =>{
        const tmp = JSON.parse(result as string);
        if(tmp.status==="success"){
            rawData = tmp.message;
        }
    })
    return {
        rawData
    }
}
})
</script>

在App.vue中使用

<template>
  <Suspense>
      <template #default> 
        <div>
          <AsyncShow/><DogShow/>
        </div>
      </template>
      <template #fallback>
        <h1>Loading...</h1>
      </template>
  </Suspense>
  <p>{{error}}</p>
</template>

<script lang="ts">
import { defineComponent, ref, toRefs, onErrorCaptured} from 'vue';
import AsyncShow from './components/AsyncShow.vue';
import DogShow from './components/DogShow.vue';
export default defineComponent({
  name: 'App',
  components: {
    AsyncShow,
    DogShow
  },
  setup(){
    const error = ref(null);
    onErrorCaptured((e: any)=>{
      error.value = e;
      return true;
    })
    return{
      error,
    }
  }
});
</script>

在onErrorCaptured函数中监听了错误,比如我们的url故意写错验证一下。onErrorCaptured的时候不能在DogShow组件中catch异常,不然在父组件App.vue中无法捕获

Like
Like Love Haha Wow Sad Angry
赞(0) 打赏
未经允许不得转载:栗子纪blog » Vue3.0 Suspense组件
分享到: 更多 (0)
0 0 vote
Article Rating
Subscribe
提醒
guest
0 评论
Inline Feedbacks
View all comments

创作不易,打赏一下作者买瓶洗发露

支付宝扫一扫打赏

微信扫一扫打赏

0
Would love your thoughts, please comment.x
()
x