可复用 & 组合
大约 2 分钟
可复用 & 组合
Teleport
Teleport
是 Vue 3.0
新特性之一。
Teleport 可以将模板渲染至指定 DOM 节点,不受父级 style、v-show 等属性影响,但 data、prop 数据依旧能够共用的技术;类似于 React 的 Portal。
虽然不受
v-show
影响, 但是v-if
的优先级还是比teleport
高的
index.html
<!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-vue-ts 学习</title>
</head>
<body>
<div id="app"></div>
<div class="teleport_class_test"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
lessContent.vue
<script setup lang="ts">
import A from "./A.vue";
import B from "./B.vue";
import C from "./C.vue";
import Dialog from "../../components/Dialog.vue";
// import Loading from '../../components/Loading/loading.vue' 异步化组件后就不能这样直接引入使用了
import { reactive, markRaw, ref, defineAsyncComponent } from "vue";
const Loading = defineAsyncComponent(
() => import("../../components/Loading/loading.vue")
);
type Tabs = {
name: string;
comName: any;
};
type Com = Pick<Tabs, "comName">;
const data = reactive<Tabs[]>([
{
name: "我是 A 组件",
comName: markRaw(A),
},
{
name: "我是 B 组件",
comName: markRaw(B),
},
{
name: "我是 C 组件",
comName: markRaw(C),
},
]);
let current = reactive<Com>({
comName: data[0].comName,
});
const switchCom = (item: Tabs) => {
current.comName = item.comName;
};
// 动态插槽相关
let name = ref("dialog_header");
</script>
<template>
<div class="content_layout">
<teleport to=".teleport_class_test">
<div class="loading">loading...</div>
</teleport>
<!-- 异步组件测试 -->
<Suspense>
<template #default>
<Loading></Loading>
</template>
<template #fallback>
<div>加载中...</div>
</template>
</Suspense>
<!-- 插槽测试 -->
<Dialog>
<!-- 具名插槽 -->
<template v-slot:dialog_header>
<div>摆</div>
</template>
<!-- 匿名插槽 -->
<!-- <template v-slot="{data}"> -->
<!-- 简写: -->
<template #default="{ data }">
<div>姓名: {{ data.name }} 年龄: {{ data.age }}</div>
</template>
<!-- 具名插槽 -->
<!-- 简写: -->
<template #dialog_footer>
<div>摸了</div>
</template>
<!-- 动态插槽 -->
<template #[name]> 动态插槽演示 </template>
</Dialog>
<div class="tab">
<div :key="item.name" v-for="item in data" @click="switchCom(item)">
{{ item.name }}
</div>
</div>
<component :is="current.comName" />
<div class="content_layout-items" :key="item" v-for="item in 100">
{{ item }}
</div>
</div>
</template>
<style lang="less" scoped>
.content_layout {
flex: 1;
margin: 20px;
border: 1px solid #ccc;
overflow: auto;
&-items {
padding: 20px;
border: 1px solid #ccc;
}
}
.tab {
display: flex;
flex: 1;
flex-direction: row;
div {
flex: 1;
padding: 10px;
border: 1px solid #ccc;
cursor: pointer;
&:hover {
background: #eee;
}
}
}
.loading {
position: absolute;
right: 10px;
top: 10px;
background: greenyellow;
}
</style>