翻译:在 Vue 中构建递归组件

原文地址:Building Recursive components in Vue


几天前,我想构建一个 Vue 组件,它能够显示嵌套节点树,但我们不知道确切的嵌套数量 - 因此它需要能够递归工作。我很惊讶网络上没有太多关于它的资源,所以我决定写一篇关于它的文章。

主要思想是让一个组件接受数据属性(目前数据结构未知)和另外两个属性用于summary open ;第一个用于定义details标签中使用的名称和显示的文本,第二个用于查看节点树是否打开。

我希望你会喜欢它:)

在 Vue 中构建递归组件

在此示例中,我使用 VueUse onClickOutside 工具函数来处理外部单击操作(我就是喜欢这个工具!)。

首先,让我们定义该组件将接受的 props:

ts
const props = defineProps({
    summary: {
        type: String,
        default: 'disclosure'
    },
    open: {
        type: Boolean,
        default: false
    },
    content: {
        type: Object,
        default: () => ({})
    }
})

接下来,让我们定义反应式引用和计算变量:

ts
const computedOpenState = ref(props.open)
const details = ref(null)
const hasNestedChildren = computed(() => props.content.children?.length)

最后,在脚本标签的最后,让我们添加函数来处理切换细节和外部点击:

ts
function toggleDetails(event: ToggleEvent) {
    computedOpenState.value = event.newState === 'open'
}

onClickOutside(details, () => (computedOpenState.value = false))

现在,让我们向组件添加一些模板。首先,如果嵌套内容没有更多嵌套子项,我们只想显示一个带有摘要名称的段落:

html
<p v-if="!hasNestedChildren">
  {{ summary }}
</p>

在其他情况下,我们想要利用 details HTML 标签:

html
<p v-if="!hasNestedChildren">
  {{ summary }}
</p>
<details
  v-else
  :open="computedOpenState"
  :name="summary"
  ref="details"
  @toggle="toggleDetails"
>
  ...
</details>

details 标签内,我们要添加以下代码来处理显示摘要和嵌套节点树:

html
<summary>
  {{ summary }}
</summary>
<template v-if="hasNestedChildren">
  <NodeTree
    v-for="(child, key) in content.children"
    :key
    :summary="child.summary"
    :content="child"
    @click="toggleChildren"
  />
</template>

下面,您可以看到该组件的完整代码:

最后,该组件可以像下面这样使用:

vue
<template>
    <NodeTree v-if="data" :content="data" :summary="data.summary" />
</template>

就是这样!您拥有完全正常工作的递归节点树组件:)

总结

干得好!您刚刚学习了如何构建递归 Vue 组件。

保重,下次再见!

And happy coding as always 🖥️

从本地到生产:使用 Docker 部署 Nuxt

翻译:在Vue单文件组件中使用两个script块

评论区

评论加载中...