一、检查子组件类型
需求:检查子组件类型,如果错误就报错
<template>
<div>
Tabs组件
<component :is="defaults[0]"/> <!--展示子组件的第0项-->
<component :is="defaults[1]"/>
</div>
</template>
<script lang="ts">
import Tab from './Tab.vue';
export default {
name: 'Tabs',
setup(props, context) {
const defaults = context.slots.default(); //获取子组件
defaults.forEach((tag) => {
if (tag.type !== Tab) {
throw new Error('Tabs的子标签必须是Tab');
}
});
return {defaults};
}
};
</script>
每一个Tab.vue最终都会导出成一个对象===context.slots.default().type
用JS获取插槽内容:defaults = context.slots.default()
二、生命周期钩子
- onMounted:挂载之后之后执行此函数(第一次渲染)
- unUpdated:更新执行 (第一次渲染后的每次更新)
- watchEffect:挂载更新都会执行,但是watchEffect会在onMounted之前执行一次
如果需求是挂载之后都执行(onMounted,unUpdated)可用:
onMounted(()=>{
watchEffect(()=>{})
})
三、ref
声明内部数据
<Switch :value="xxx"/>
const xxx = ref('false')
return {xxx}
获取HTML元素
<div class="wheel-tabs-nav" ref="container"></div>
const container = ref<HTMLDivElement>(null); //HTMLDivElement获取元素的类型
const {left} = container.value.getBoundingClientRect(); //获取container左坐标
HTMLDivElement:typeScript泛型
getBoundingClientRect()获取元素的宽高和位置,例如:bottom,height,left,right,top,width,x,y
简单获取整个DIV
<div ref="container"></div>
setup(props, context){
const container = ref<HTMLDivElement>(null);//可理解为放div元素的容器
const {left: left1} = container.value.getBoundingClientRect(); //获取整个div的左坐标
}
//console.log(container.value) 打出来看看
获取复杂的动态div
<div class="wheel-tabs-nav-item"
v-for="(t,index) in titles" :key="index"
:class="{selected:t===selected}" @click="select(t)"
:ref="el=>{ if (el) navItems[index]=el}">{{ t }}
</div>
setup(props, context){
const navItems = ref<HTMLDivElement[]>([]);
const divs = navItems.value; //获取nav的div
}
四、动态组件 :is
<component :is="current" :key="current.props.title"/>
props: {
selected: {
type: String
}
},
setup(props, context){
const defaults = context.slots.default();//获取插槽
const titles = defaults.map((tag) => {
return tag.props.title; //拿到Tab.title(插槽)内容
});
const current = computed(() => {
return defaults.find(tag => tag.props.title === props.selected); //插槽内容===选中内容
});
}
网友评论