一、动态组件
父组件(在这个组件做动态切换的动作)
<template>
<div class="container">
<p v-for="item in data" class="tab" @click="tab(item)">{{ item.name }}</p>
</div>
<component :is="com"></component>
</template>
<script setup lang="ts">
import {ref,reactive, shallowRef} from 'vue'
import A from './A.vue'
import B from './B.vue'
import C from './C.vue'
const tab = (val:any)=>{
com.value = val.comN
}
/* 这里用ref的话会报警告:
runtime-core.esm-bundler.js:40 [Vue warn]: Vue received a Component which was made a reactive object.
This can lead to unnecessary performance overhead, and should be avoided by marking the component with `markRaw` or using `shallowRef` instead of `ref`.
Component that was made reactive:
*/
**这是因为reactive 会进行proxy 代理 而我们组件代理之后毫无用处 节省性能开销 推荐我们使用shallowRef 或者 markRaw 跳过proxy 代理**
const com = shallowRef()
const data = reactive([
{
name:'A组件',
comN:shallowRef(A) //这里直接写A也会包上面的警告 也可以用markRaw(A)
},
{
name:'B组件',
comN:shallowRef(B)
},
{
name:'C组件',
comN:shallowRef(C)
}
])
</script>
二、插槽
1.匿名插槽
子组件:
//A组件
<template>
<div class="container">
<footer>
<slot></slot>
</footer>
</div>
</template>
父组件:
<A>
<template v-slot>匿名插槽</template>
</A>
2.具名插槽
子组件:
<template>
<div class="container">A组件
<header>
<slot name="header"></slot>
</header>
<section>
<slot name ='section'></slot>
</section>
<footer>
<slot></slot>
</footer>
</div>
</template>
父组件:
<template>
<A>
<template v-slot:header>
我在上层
</template>
<!-- 具名插槽的简写形式 -->
<template #section>中层</template>
<template #default>默认</template>
</A>
</template>
3.作用域插槽
子组件:
<template>
<div class="container">A组件
<footer>
<div v-for="item in 100">
<slot :info="item"></slot>
</div>
</footer>
</div>
</template>
父组件:
<template>
<A>
<template #default="{info}">{{info}}</template>
</A>
</template>
4.动态插槽
插槽可以是一个变量名
<A>
<template #[name]>
<div>23</div>
</template>
</A>
const name = ref('header')