有没有办法在 Vue 3 中可靠地处理插槽内容?标题

问题描述 投票:0回答:1

我目前正在将 Vue 2 代码库迁移到 Vue 3。

<card>
    <template #default>
        <card-header>
            <title level="3">Header</title>
        </card-header>
        <card-body
            v-for="b in bodyCount"
            :key="'b' + b">
            Body {{ b }}
        </card-body>
        <card-footer
            v-for="f in footerCount"
            :key="'f' + f">
            <text>Footer {{ f }}</text>
        </card-footer>
    </template>
</card>

Card 组件有一个调用

this.$slots.default()
的渲染函数。但是在 Vue 3 中,它返回的内容与它在 Vue 2 中所做的不同。所以如果我这样做
console.log(this.$slots.default())
- 我得到一个包含 3 个元素的数组,[v-node with type: 'header', v-node with type: Symbol (片段),类型为:Symbol(Fragment)]

的 v 节点

更具体地说,它不会将卡片页脚/卡片主体识别为组件,而是我在类型中看到符号(片段)。 Card-header 实际上很好,因为它不在 v-for 循环中。

卡片组件的渲染函数内部有逻辑,需要知道它有多少 body/footer 组件。所以我需要能够分辨组件类型。这在 Vue 3 中是不可能的吗?我猜这与此处的 v-for 有关,但我不确定如何实际获得最终结果 v 节点。在这个例子中,我希望数组包含卡片标题+所有卡片主体+所有卡片页脚而不是 3 个元素。

vue.js vuejs3 vuejs-slots
1个回答
0
投票

你的卡片组件的设计对我来说没有意义。我建议你重新考虑一下。

这里是简单的游乐场渲染槽

const { createApp, h } = Vue;

const Card = {
  setup(props, { attrs, slots, emit, expose }) {
      return () => [           
          h('label', 'Card'),
          h('div', 'Slots:'),
          h('div', {}, slots.default()),
          h('div', {}, slots.header()),
          h('div', {}, slots.body()),
          h('div', {}, slots.footer())
      ]
  }
}

const App = { 
  components: { Card },
  data() {
    return {
    }  
  }
}
const app = createApp(App)
app.mount('#app')
#app { line-height: 2; }
[v-cloak] { display: none; }
label { font-weight: bold; }
<div id="app">
<card>
    <template #default>
       Default
        <card-header>
            <title level="3">Header</title>
        </card-header>
    </template>
    <template #header>
       Header
    </template>
    <template #body>
       Body
    </template>
    <template #footer>
       Footer
    </template>
</card>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>

注意警告。 Vue 不会在这里渲染

card-header
,因为它无法解析它。

[Vue warn]: Failed to resolve component: card-header
If this is a native custom elemen
© www.soinside.com 2019 - 2024. All rights reserved.