如何在Vue3中获取递归组件的引用?

k5ifujac  于 2023-03-24  发布在  Vue.js
关注(0)|答案(1)|浏览(176)

我有一个组件(Group),它可以有递归组件。在这个组件中还有另一个组件(ButtonsContainer). ButtonsContainer组件公开了聚焦第一个和最后一个按钮的函数。我想要的是获得第一个组和最后一个组的引用,包括递归的。我怎么能实现这一点呢?我尝试了一个递归函数,但超过了最大调用堆栈大小。
下面是Group组件。我省略了ButtonsContainer组件,因为它没有特殊的功能,只是在网格中显示按钮。
Component Group

<script setup lang="ts">

const props = defineProps<{
    group: Group
}>();

const buttonsContainerRef = ref<InstanceType<typeof ButtonsContainer> | null>(null);
const firstGroupRef       = ref<InstanceType<typeof Group> | null>(null);
const lastNestedGroupRef  = ref<InstanceType<typeof Group> | null>(null);

function getLastButtonsContainerRef(): Ref<InstanceType<typeof ButtonsContainer> | null> | undefined {
    if (props.group.groups.length > 0) {
        // return getLastButtonsContainerRef(); // still does not work:(
        getLastButtonsContainerRef();
    } else {
        return buttonsContainerRef;
    }
}
</script>

<template>
    <ul>
        <li v-if="group.buttons.length > 0 && !props.group.collapsed">
            <ButtonsContainer
                :buttons="group.buttons"
                ref="buttonsContainerRef"
            />
        </li>
        <li
            v-if="group.groups.length > 0 && !props.group.collapsed"
            v-for="nestedGroup in group.groups"
            :key="nestedGroup.uuid"
        >
            <Group
                :group="nestedGroup"
                class="nested-group"
            />
        </li>
    </ul>
</template>

如何获取第一组和最后一组(包括嵌套组)的引用?欢迎提供帮助。谢谢!

gudnpqoy

gudnpqoy1#

要获取嵌套的refs,您需要自己遍历树。
没有现成的解决方案。
下面是一个非常基本的refs示例,其中包含所有嵌套的子元素。

const { createApp, ref } = Vue;

const CompB = {
  props: ['id'],
  setup(props) {
    const name = "CompB"
    return { name } 
  },
  template: '<div class="b">CompB, id:<b>{{id}}</b></div>'
}

const CompA = {
  components: { CompB },
  props: ['id'],
  setup(props) {
    const name = "CompA"
    const child = ref(null)   
    return { name, child } 
  },
  template: '<div class="a">CompA, id:<b>{{id}}</b><CompB ref="child" :id="`${id}.1`" /></div>'
}

const App = { 
  components: { CompA },
  setup(props) {
    const refs = ref([])
    const showRefs = (ref) => {
       if (!ref) {
          for(var i = 0; i < refs.value.length; i++) {
            console.log(`Name: ${refs.value[i].name}, id: ${refs.value[i].id}`);
            if (refs.value[i].child) showRefs(refs.value[i].child)
          }
       } else {
          console.log(`Name: ${ref.name}, id: ${ref.id}`);
       }
    }
    return { refs, showRefs } 
  }
}
const app = createApp(App)
app.mount('#app')
#app { line-height: 2; }
[v-cloak] { display: none; }
.a { 
  background-color: lightblue;
  margin: 4px;
  padding: 4px;
 }
.b { 
  background-color: lightyellow;
  margin: 4px;
  padding: 4px;
}
<div id="app" v-cloak>
<button @click="showRefs()">Show refs</button><br/>
<comp-a v-for="n in 3" :id="n" ref="refs"></comp-a>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>

相关问题