1、异步请求组件 Suspense
Suspense是Vue3推出的一个内置的特殊组件,有两个template slot,刚开始会渲染一个fallback内容,直到达到某个条件以后才会渲染正式的内容。
如果使用Suspense,在setup( )中需要返回一个promise,而不是直接返回一个对象。
Async1.vue
<template>
<h1>{{result}}</h1>
</template>
<script>
import { defineComponent } from "vue";
export default defineComponent({
setup() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({
result: "异步组件"
});
}, 2000)
})
}
})
</script>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
使用时
<template>
<div>
<Suspense>
<template #default>
<async-one />
</template>
<template #fallback>
<h1>Loading...</h1>
</template>
</Suspense>
</div>
</template>
<script>
import AsyncOne from '../../components/Async1.vue'
export default {
name: "suspense",
components:{
AsyncOne
}
}
</script>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
Suspense 中可以添加多个异步组件,template default包裹多个组件,等这些个result都加载好了一起进行展示。
<template>
<div>
<Suspense>
<template #default>
<div>
<async-one />
<async-two />
</div>
</template>
<template #fallback>
<h1>Loading...</h1>
</template>
</Suspense>
</div>
</template>
<script>
import AsyncOne from '../../components/Async1.vue'
import AsyncTwo from '../../components/Async2.vue'
export default {
name: "suspense",
components:{
AsyncOne,
AsyncTwo
}
}
</script>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
异步请求错误处理onErrorCaptured
在异步请求中必须要作的一件事情,就是要捕获错误,因为我们没办法后端给我们返回的结果,也有可能服务不通,所以一定要进行捕获异常和进行处理。
在vue3.x的版本中,可以使用onErrorCaptured这个钩子函数来捕获异常,钩子函数要求我们返回一个布尔值,代表错误是否向上传递
Async.vue
<template>
<h1>{{result}}</h1>
</template>
<script>
import { defineComponent } from "vue";
export default defineComponent({
setup() {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject({
result: "异步组件"
});
}, 2000)
})
}
})
</script>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
<template>
<div>
<Suspense>
<template #default>
<async-one />
</template>
<template #fallback>
<h1>Loading...</h1>
</template>
</Suspense>
</div>
</template>
<script>
import { onErrorCaptured } from "vue";
import AsyncOne from '../../components/Async1.vue'
export default {
name: "suspense",
components:{
AsyncOne
},
setup() {
onErrorCaptured((error) => {
console.log(error);
return true;
})
return {};
}
}
</script>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
2、Teleport
Teleport 是一种能够将我们的模板移动到 DOM 中 Vue app 之外的其他位置的技术
如果我们嵌套在 Vue 的某个组件内部,那么处理嵌套组件的定位、z-index 和样式就会变得很困难。
使用Teleport 就可以方便的解决组件间 css 层级问题
要使用teleport,首先要在页面上添加一个元素,我们要将模态内容移动到该页面
<!-- index.html -->
<body>
<div id="app"></div>
<div id="modal-container"></div>
</body>
- 1
- 2
- 3
- 4
- 5
我们将模态内容包装在 teleport 组件中,还需要指定一个 to 属性,以标识目标元素,此处为#modal-container
<template>
<div>
<teleport to="#modal-container" v-if="show">
<div class="modal-container">
弹窗内容
</div>
</teleport>
<van-button type="primary" @click="openDialog">弹窗</van-button>
</div>
</template>
<script>
import {
ref
} from "vue"
export default {
name: 'teleport',
setup() {
const show = ref(false);
const openDialog = () => {
show.value = true;
setTimeout(() => { // 弹窗的显示时常
show.value = false;
}, 1500)
}
return {
show,
openDialog
}
}
}
</script>
<style scoped>
.modal-container {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
padding: 10px 20px;
background: black;
border-radius: 40px;
opacity: 0.7;
color: white;
font: normal 16px/20px arial;
}
</style>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
在同一目标上使用多个teleport
<template>
<div>
<teleport to="#modal-container" v-if="show">
<div class="modal-container">
弹窗内容
</div>
</teleport>
<teleport to="#modal-container" v-if="show">
<div class="modal-container">
弹窗内容2
</div>
</teleport>
<van-button type="primary" @click="openDialog">弹窗</van-button>
</div>
</template>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
对于这种情况,多个teleport组件可以将其内容挂载到同一个目标元素。顺序将是一个简单的追加——稍后挂载将位于目标元素中较早的挂载之后
源码:https://gitee.com/smallgrey/new-features-of-vue3
微信公众号:趣享编程