如何解决Vue 3如何获取有关$ children的信息
这是我在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)
解决方法
对于想要完整代码的人:
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/>
,
哦,我解决了:
slots.default().filter(child => child.type.name === 'Tab')
,
这是我现在的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>
,
如果您复制粘贴的代码与我相同
然后将一个创建的方法添加到“ tab”组件中,该方法会将自身添加到其父级的tabs数组中
created() {
this.$parent.tabs.push(this);
},
,
我对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")
}
}
)
,
在 3.x 中,$children 属性被移除并且不再受支持。相反,如果您需要访问子组件实例,他们建议使用 $refs。作为数组
https://v3.vuejs.org/guide/migration/children.html#_2-x-syntax
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。