【问题标题】:Is possible to have recurring slots in Vue?Vue 中可能有重复的插槽吗?
【发布时间】:2021-02-10 18:46:46
【问题描述】:

我已经设置了复制库:

https://github.com/devidwong/recurring-slot

我只使用 Vue 运行时,所以我不能附加 Vue.extend 的小提琴(需要模板编译器)

Vue 3 是相当新的东西。我将其用于探索目的。我不知道这是否适用于 Vue 2,但我只是想知道这个组件是否应该正常工作:

comment.template.html:

<div class="comment">
    <slot :currentComment="comment"></slot>
    <Comment v-for="reply in comment.replies" :key="reply.id" :comment="reply">
        <slot :currentComment="reply"></slot>
    </Comment>
</div>

用法:

cmets.template.html

<Comment v-for="comment in comments" :key="comment.id" :comment="comment">
    <template #default="{ currentComment }">
        <div>by {{ currentComment.author }}</div>
    </template>
</Comment>

对于结构:

comments: [
      {
        id: 1,
        author: 'Goodman',
        replies: [
          {
            id: 11,
            author: 'RepeatingMan',
            replies: [
              {
                id: 111,
                author: 'ExpectedMan',
                replies: [
                  {
                    id: 1111,
                    author: 'MelodyOfFuture',
                    replies: []
                  }
                ]
              }
            ]
          }
        ]
      }
    ]

我得到 Repeatimg man 渲染 3 次,而不是 ExpectedManMelodyOfFuture。在我看来,第二个插槽与第一个插槽获得相同的评论道具。 我希望有嵌套的 cmets 并只定义一次内部的东西。

这可能吗?

【问题讨论】:

  • 你想把作者显示在另一个之下吗?
  • 是的。如您所见,结构很好,但数据始终来自同一级别
  • 看看this有没有帮助
  • 很好,你指出我的代码和框,但如果你发布解决方案 - 你的评论组件不会重复

标签: javascript vue.js vuejs2 vue-component vuejs3


【解决方案1】:

repo 已更新

https://github.com/devidwong/recurring-slot

父母:

<Comment
      v-for="comment in comments"
      :key="comment.id"
      :comment="comment"
      :detailsComponent="CommentDetails"
    >
      <template #default="{ currentComment }">
        <CommentDetails
            :currentComment="currentComment"
        />
      </template>
    </Comment>

孩子:

<div class="comment">
    <slot :currentComment="comment"></slot>
    <Comment
        v-for="reply in comment.replies"
        :key="reply.id"
        :comment="reply"
        :detailsComponent="detailsComponent"
    >
      <template #default="{ currentComment }">
        <component
            :is="detailsComponent"
            :currentComment="currentComment"
            :detailsComponent="detailsComponent"
        />
      </template>
    </Comment>
  </div>

详情:

<div>
    by {{ currentComment.author }}
</div>

不要忘记将 CommentDetails(在父级中)声明为组件和数据条目:

{
components: {
    Comment,
    CommentDetails
},
data: () => ({
    CommentDetails,
    comments: [...]
})
}

【讨论】:

    【解决方案2】:

    不要通过 slot 再次将评论暴露给父组件,只需在 Comment 组件中打印作者姓名和评论即可:

    <div class="comment">
       {{comment.author}}
        <Comment v-for="reply in comment.replies" :key="reply.id" :comment="reply">
            <slot :currentComment="reply"></slot>
        </Comment>
    </div>
    

    父组件:

    <Comment v-for="comment in comments" :key="comment.id" :comment="comment">
    </Comment>
    

    LIVE DEMO

    在现场演示中,我尝试模拟 stackoverflow cmets 样式。

    【讨论】:

    • 这是解决方法。我想在父组件中定义&lt;h4&gt;{{ comment.author }}&lt;/h4&gt;(或任何类型的包装器),就像在普通(非重复)组件中一样。你能准确指出限制在哪里吗?我不创建应用程序 - 我探索和实验。存档的方法有很多
    • 不客气,this 我在父子组件中使用了命名作用域槽
    • 您通过定义细节两次(在父项和子项中)为无限渲染赢得了大奖 :)。我发现不需要一个插槽,也不需要命名插槽。细节也可以作为 prop 中的组件传递给 child - 所以现在它只定义一次。遗憾的是不在我想要的地方,但没关系(我不希望它有更多的孩子)。我从问题更新了回购。谢谢。
    • 不客气,好的,在重复出现的情况下,您应该使用渲染函数而不是模板,就像我使用 vue 3 github.com/boussadjra/vue3-router-tree构建组件时所做的那样@
    猜你喜欢
    • 2019-06-08
    • 1970-01-01
    • 2020-04-23
    • 2021-02-06
    • 2018-11-05
    • 1970-01-01
    • 1970-01-01
    • 2018-04-29
    • 2014-01-12
    相关资源
    最近更新 更多