TabsDemo.vue组件
<template>
<Tabs>
<Tab title="导航1">内容1</Tab>
<Tab title="导航2">内容2</Tab>
</Tabs>
</template>
<script lang="ts">
import Tabs from '../lib/Tabs.vue'
import Tab from '../lib/Tab.vue'
export default {
components: {
Tabs,
Tab
}
}
</script>
Tab.vue
<template>
<div>Tab 组件</div>
</template>
Tabs.vue
<template>
<div>Tabs 组件</div>
</template>
1、检查Tabs组件中子组件Tab的类型
Tabs.vue
<template>
<div>Tabs 组件</div>
</template>
<script lang="ts">
export default {
setup(props,context){ //组件信息包含在context中
console.log({...context})
}
}
</script>

打印出插槽中slots.default()方法,能看到传入两个节点内容
setup(props,context){ //组件信息包含在context中
console.log({...context.slots.default()})
}

这里打印出来0和1分别代表TabsDemo中传入的Tab两个节点,分别打印出这两个节点出来
setup(props,context){
console.log({...context.slots.default()[0]})
console.log({...context.slots.default()[1]})
}

这里显示一堆东西其实是一个虚拟节点东西,我们将它显示在页面中出来的就是我们需要的Tab组件内容。
Tabs组件:
<template>
<div>
Tabs 组件
<component :is="defaults[0]"></component>
<component :is="defaults[1]"></component>
</div>
</template>
<script lang="ts">
export default {
setup(props,context){
const defaults=context.slots.default()
return{defaults}
}
}
</script>

刚刚说打印出来的虚拟节点中有个type类型,如果说这个类型和我们Tab相等,说明传入的标签就是一个Tab标签。
<script lang="ts">
import Tab from './Tab.vue'
export default {
setup(props,context){
const defaults=context.slots.default()
console.log(defaults[0].type === Tab) //判断标签是否为Tab
return{defaults}
}
}
</script>

2、当我们修改成传入标签是div时,检查的类型是错误的。
TabsDemo.vue组件:
<template>
<Tabs>
<div title="导航1">内容1</div>
<div title="导航2">内容2</div>
</Tabs>
</template>

3、如何提示让Tabs子标签必须是Tab组件
Tabs组件:
<template>
<div>
Tabs 组件
<component :is="defaults[0]"></component>
<component :is="defaults[1]"></component>
</div>
</template>
<script lang="ts">
import Tab from './Tab.vue'
export default {
setup(props,context){
const defaults=context.slots.default()
defaults.forEach((tag)=>{
if(tag.type !== Tab){ //判断是否Tab类型
throw new Error('Tab 子标签必须是 Tab')
}
})
return{defaults}
}
}
</script>
当我们修改成传入标签是div时,打印出一个错误信息,要求我们传入子标签是Tab组件,这叫预防性编程。
TabsDemo.vue组件:
<template>
<Tabs>
<div title="导航1">内容1</div>
<div title="导航2">内容2</div>
</Tabs>
</template>

网友评论