这是我在Tabs组件中具有VUE 2的旧代码:
created() {
this.tabs = this.$children;
}
标签:
<Tabs>
<Tab title="tab title">
....
</Tab>
<Tab title="tab title">
....
</Tab>
</Tabs>
VUE 3: 如何使用Composition API在Tabs组件中获取有关子级的一些信息?得到长度,遍历它们,并创建制表符标题,...等等?有任何想法吗? (使用合成API)
答案 0 :(得分:4)
对于想要完整代码的人:
Tabs.vue
<template>
<div>
<div class="tabs">
<ul>
<li v-for="tab in tabs" :class="{ 'is-active': tab.isActive }">
<a :href="tab.href" @click="selectTab(tab)">{{ tab.name }}</a>
</li>
</ul>
</div>
<div class="tabs-details">
<slot></slot>
</div>
</div>
</template>
<script>
export default {
name: "Tabs",
data() {
return {tabs: [] };
},
created() {
},
methods: {
selectTab(selectedTab) {
this.tabs.forEach(tab => {
tab.isActive = (tab.name == selectedTab.name);
});
}
}
}
</script>
<style scoped>
</style>
Tab.vue
<template>
<div v-show="isActive"><slot></slot></div>
</template>
<script>
export default {
name: "Tab",
props: {
name: { required: true },
selected: { default: false}
},
data() {
return {
isActive: false
};
},
computed: {
href() {
return '#' + this.name.toLowerCase().replace(/ /g, '-');
}
},
mounted() {
this.isActive = this.selected;
},
created() {
this.$parent.tabs.push(this);
},
}
</script>
<style scoped>
</style>
App.js
<template>
<Tabs>
<Tab :selected="true"
:name="'a'">
aa
</Tab>
<Tab :name="'b'">
bb
</Tab>
<Tab :name="'c'">
cc
</Tab>
</Tabs>
<template/>
答案 1 :(得分:2)
哦,我解决了:
slots.default().filter(child => child.type.name === 'Tab')
答案 2 :(得分:2)
这是我现在的Vue 3组件。我曾使用Provide获取子Tab
子组件中的信息。
<template>
<div class="tabs">
<div class="tabs-header">
<div
v-for="(tab, index) in tabs"
:key="index"
@click="selectTab(index)"
:class="{'tab-selected': index === selectedIndex}"
class="tab"
>
{{ tab.props.title }}
</div>
</div>
<slot></slot>
</div>
</template>
<script lang="ts">
import {defineComponent, reactive, provide, onMounted, onBeforeMount, toRefs, VNode} from "vue";
interface TabProps {
title: string;
}
export default defineComponent({
name: "Tabs",
setup(_, {slots}) {
const state = reactive({
selectedIndex: 0,
tabs: [] as VNode<TabProps>[],
count: 0
});
provide("TabsProvider", state);
const selectTab = (i: number) => {
state.selectedIndex = i;
};
onBeforeMount(() => {
if (slots.default) {
state.tabs = slots.default().filter((child) => child.type.name === "Tab");
}
});
onMounted(() => {
selectTab(0);
});
return {...toRefs(state), selectTab};
}
});
</script>
标签组件:
export default defineComponent({
name: "Tab",
setup() {
const index = ref(0);
const isActive = ref(false);
const tabs = inject("TabsProvider");
watch(
() => tabs.selectedIndex,
() => {
isActive.value = index.value === tabs.selectedIndex;
}
);
onBeforeMount(() => {
index.value = tabs.count;
tabs.count++;
isActive.value = index.value === tabs.selectedIndex;
});
return {index, isActive};
}
});
<div class="tab" v-show="isActive">
<slot></slot>
</div>
答案 3 :(得分:1)
如果您复制粘贴的代码与我相同
然后将一个创建的方法添加到“ tab”组件中,该方法会将自身添加到其父级的tabs数组中
created() {
this.$parent.tabs.push(this);
},
答案 4 :(得分:1)
我对IngridOberbüchler的组件进行了小幅改进,因为它不能与热重载/动态标签一起使用。
在Tab.vue中:
onBeforeMount(() => {
// ...
})
onBeforeUnmount(() => {
tabs.count--
})
在Tabs.vue中:
const selectTab = // ...
// ...
watch(
() => state.count,
() => {
if (slots.default) {
state.tabs = slots.default().filter((child) => child.type.name === "Tab")
}
}
)
答案 5 :(得分:0)
在 3.x 中,$children 属性被移除并且不再受支持。相反,如果您需要访问子组件实例,他们建议使用 $refs。作为数组
https://v3.vuejs.org/guide/migration/children.html#_2-x-syntax