是否沒有辦法可靠地處理 Vue 3 中的槽內容?
P粉714844743
P粉714844743 2023-08-30 08:47:17
0
2
400
<p>我目前正在將 Vue 2 程式碼庫遷移到 Vue 3。 </p> <pre class="brush:php;toolbar:false;"><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></pre> <p>Card 元件有一個呼叫 <code>this.$slots.default()</code> 的渲染函數。然而,在 Vue 3 中,這會傳回與 Vue 2 中不同的內容。因此,如果我執行<code>console.log(this.$slots.default())</code> - 我會得到一個包含3 個元素的數組,[類型為「header」的v 節點,類型為Symbol(Fragment) 的v 節點,類型為Symbol(Fragment) 的v 節點]</p> <p>更具體地說,它不會將卡頁腳/卡體識別為組件,而是我在類型中看到符號(片段)。 Card-header 實際上很好,因為它不在 v-for 循環中。 </p> <p>卡片組件的渲染函數內部有一個邏輯,需要知道它有多少個正文/頁腳組件。所以我需要能夠分辨組件類型。這在 Vue 3 中不可能嗎?我可以猜測這與這裡的 v-for 有關,但我不確定如何實際獲得最終結果 v-nodes。在此範例中,我希望陣列包含卡頭 所有卡體 所有卡頁腳,而不是 3 個元素。 </p>
P粉714844743
P粉714844743

全部回覆(2)
P粉865900994

你的卡片組件的設計對我來說看起來沒有意義。我建議你重新考慮一下。

這是簡單的遊樂場渲染槽

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

如果您可以存取數據,為什麼要透過slots操作card-body/card-footer專案直接透過bodyCount

如果對我來說看起來不合理。

const { createApp, h } = Vue;

const CardHeader = {
    template: '<div class="card-header">card-header: <slot></slot></div>'
}
const CardBody = {
    template: '<div class="card-body">card-body: <slot></slot></div>'
}
const CardFooter = {
    template: '<div class="card-footer">card-footer: <slot></slot></div>'
}

const Card = {
  components: {
    CardHeader, CardBody, CardFooter
  },
  setup(props, { attrs, slots, emit, expose }) {
      //console.log(slots.default())
      return () => [           
          h('label', 'Card'),
          h('div', 'Slots:'),
          h('div', {}, slots.default()),
      ]
  }
}

const App = { 
  components: { Card, CardHeader, CardBody, CardFooter },
  data() {
    return {
      bodyCount: ['a','b'],
      footerCount: ['a','b']
    }  
  }
}
const app = createApp(App)
app.mount('#app')
#app { line-height: 2; }
[v-cloak] { display: none; }
label { font-weight: bold; }
.card-header, .card-body, .card-footer {
  border: 1px solid #F0F0F0;
}
<div id="app">
<card>
    <template #default>
        <card-header>
            <div level="3">Header</div>
        </card-header>
        bodyCount: {{bodyCount.length}}
        <card-body
            v-for="b in bodyCount"
            :key="'b' + b">
            Body {{ b }}
        </card-body>
        footerCount: {{footerCount.length}}
        <card-footer
            v-for="f in footerCount"
            :key="'f' + f">
            <text>Footer {{ f }}</text>
        </card-footer>
    </template>
</card>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
P粉440453689

事實證明 - 可以透過陣列每個元素上的 Children 屬性來展開片段。因此,在這種情況下,v-for 會產生一個 v 節點,它是一個片段,但我們可以透過查看 Children 屬性來推斷更多內容。

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!