vue3学习之异步请求Suspense

我爱海鲸 2023-01-15 18:27:57 vue、前端

简介Suspense

链接上一篇文章:vue3学习之Typescript对vue3的加持

Suspense相关用法

Suspense是Vue3推出的一个内置的特殊组件

如果使用Suspense,要返回一个promise

1、现在我们来添加两个组件

DogShow.vue

<template>
  <img :src="result && result.message">
</template>
<script lang="ts">
import axios from 'axios'
import { defineComponent } from 'vue'
export default defineComponent({
  async setup() {
    const rawData = await axios.get('https://dog.ceo/api/breeds/image/random')
    return {
      result: rawData.data
    }
  }
})
</script>

AsyncShow.vue

<template>
  <h1>{{result}}</h1>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
  setup() {
    return new Promise((resolve) => {
      setTimeout(() => {
        return resolve({
          result: 42
        })
      }, 3000)
    })
  }
})
</script>

app.vue 代码如下:

<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png">
    <h1>{{count}}</h1>
    <h1>{{double}}</h1>
    <h1>x:{{x}}</h1>
    <h1>y:{{y}}</h1>
    <ul>
      <li v-for="number in numbers" :key="number">
        <h1>{{number}}</h1>
      </li>
    </ul>
    <h1>{{person.name}}</h1>
    <p>{{error}}</p>
    <Suspense>
      <template #default>
        <div>
          <async-show />
          <dog-show />
        </div>
      </template>
      <template #fallback>
        <h1>Loading !...</h1>
      </template>
    </Suspense>
    <button @click="openModal">Open Modal</button><br/>
    <modal :isOpen="modalIsOpen" @close-modal="onModalClose"> My Modal !!!!</modal>
    <h1 v-if="loading">Loading!...</h1>
    <img v-if="loaded" :src="result[0].url" style="width: 100px;height: 100px"  alt="">
    <button @click="increase">赞+1</button><br/>
    <button @click="updateGreeting">Update Title</button>
  </div>
</template>

<script lang="ts">
  // 响应式对象引入,计算函数引入
import { ref,computed,reactive,toRefs,onUpdated,watch ,onErrorCaptured} from 'vue'
import useMousePosition from './hooks/useMousePosition'
import useURLLoader from './hooks/useURLLoader'
import Modal from './components/Modal.vue'
import AsyncShow from './components/AsyncShow.vue'
import DogShow from './components/DogShow.vue'

interface DataProps {
  count: number;
  double: number;
  increase: () => void;
  numbers: Array<number>,
  person: {name ? :string}
}

  interface DogResult {
    message: string;
    status: string;
  }

  interface CatResult {
    id: string;
    url: string;
    width: number;
    height: number;
  }
export default{
  name: 'App',
  components: {
    Modal,
    AsyncShow,
    DogShow
  },
  setup() {
    const error = ref(null)
    onErrorCaptured((e: any) => {
      error.value = e
      return true
    })
    onUpdated(() => {
      // console.log('onUpdated');
    })
    // onRenderTracked((event) => {
    //   console.log(event);
    // })

    const data: DataProps  = reactive({
      count: 0,
      increase: () => { data.count++},
      double: computed(() => data.count * 2),
      numbers: [0,1,2],
      person: {}
    })
    const { x, y } = useMousePosition()
    const { result, loading, loaded } = useURLLoader<CatResult[]>('https://api.thecatapi.com/v1/images/search?limit=1')
    const greetings = ref('')
    const updateGreeting = () => {
      greetings.value += 'Hello! '
    }
    watch(result, () => {
      if (result.value) {
        console.log('value', result.value)
      }
    })

    data.numbers[0] = 5;
    data.person.name = 'haijin';
    const refData = toRefs(data)
    const modalIsOpen = ref(false)
    const openModal = () => {
      modalIsOpen.value = true
    }
    const onModalClose = () => {
      modalIsOpen.value = false
    }
    return {
      ...refData,
      greetings,
      updateGreeting,
      x,
      y,
      result,
      loading,
      loaded,
      modalIsOpen,
      openModal,
      onModalClose
    }
  }
};
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

Suspense的作用就是让这个两个异步组件同时加载,都完成后在进行其他的加载。

你好:我的2025