时间:2022-07-26 10:03:08 | 栏目:vue | 点击:次
Teleport 官方文档
1.Vue 鼓励我们通过将 UI 和相关行为封装到组件中来构建我们的 UI。我们可以将它们相互嵌套以构建构成应用程序 UI 的树。
2.但是,有时组件模板的一部分在逻辑上属于该组件,而从技术角度来看,最好将模板的这部分移动到 DOM 中的其他位置,即 Vue 应用程序之外。
上面的话是不是看起来很懵逼,其实是翻译自 官方文档
其实我理解的 Teleport 就是将一个组件挂载在 Vue app 之外,我们知道,Vue 属于 SPA(单页面)应用。所有的渲染都在 id 为 app 的标签里面,这样的话,我们就创建一个和 app 是同级 的组件,并且通过 teleport 标签引用,就可以任意页面使用了
1.我们这里也是实现一个全局模态框
2.通过 父子组件通信 机制,来使用 teleport 的挂载的特性
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <link rel="icon" href="/favicon.ico" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Vite App</title> </head> <body> <div id="app"></div> <div id="modal"></div> <!-- 定义一个和 app 同级的标签 modal --> <script type="module" src="/src/main.ts"></script> </body> </html>
定义一个 Modal 组件
<template> <!-- teleport 有个一个 to 属性,挂载在 id为modal的标签上 --> <teleport to="#modal"> <div id="center" v-if="isOpen"> <div class="modal-header" v-if="title"> <h2>{{ title }}</h2> <hr /> </div> <div class="modal-content"> <!-- 我们使用插槽,来支持外部插入内容 --> <slot></slot> </div> <button @click="buttonClick">Close</button> </div> </teleport> </template> <script lang="ts"> // defineProps<{ msg: string }>() Vue3 setup 定义 props import { defineComponent } from 'vue'; export default defineComponent({ props: { isOpen: Boolean, title: String }, // 验证 emits: { 'close-modal': null // (payload: any) => { // return payload.type === 'close' // } }, setup(props, context) { const buttonClick = () => { context.emit('close-modal'); } return { buttonClick } } }); </script> <style> #center { width: 200px; height: 200px; border: 2px solid black; background-color: white; position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%); } </style>
3.使用 Modal 组件
<script setup lang="ts"> import { ref } from 'vue'; import Modal from './components/Modal.vue'; const modalTitle = ref('你好,世界'); const modalIsOpen = ref(false); const openModal = () => { modalIsOpen.value = true; } const onModalClose = () => { modalIsOpen.value = false; } </script> <template> <img alt="Vue logo" src="./assets/logo.png" /> <div class="test-useURLLoader"> <button @click="openModal">modal</button> <Modal :title="modalTitle" :isOpen="modalIsOpen" @close-modal="onModalClose"> My modal </Modal> </div> </template> <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 官方文档
Waring
:作为 Vue3 中实验性的功能,随时都有可能修改,所以不建议用于生成环境的应用
是可以用来异步数据,它拥有一个本地的处理方法用来适配多种情形提供了二选一(加载完成 和 失败的插槽)
更详细的内容大家可以自行翻阅官方文档,我只是进行一部分的挑选
1.为了实现异步效果,我们可以使用 Promise 来实现异步操作。
2.我们定义如下组件 AsyncShow.vue
组件
<template> <!-- 等待3秒显示数据 --> <h1>{{ result }}</h1> </template> <script lang="ts"> import { defineComponent } from 'vue'; export default defineComponent({ setup() { return new Promise((resolve) => { setTimeout(() => { return resolve({ result: 43 }) }, 3000); }); } }); </script> <style> </style>
3.在 App.vue 里面使用该组件
<script setup lang="ts"> import AsyncShow from './components/AsyncShow.vue'; </script> <template> <img alt="Vue logo" src="./assets/logo.png" /> <div class="test-useURLLoader"> <!-- Promise 未执行完成时,就会显示 Loding... 执行完毕后,就会显示数值 --> <Suspense> <template #default> <AsyncShow /> </template> <template #fallback> <h2> Loading... </h2> </template> </Suspense> </div> </template> <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>