链接上一篇文章: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的作用就是让这个两个异步组件同时加载,都完成后在进行其他的加载。