Adakah tiada cara untuk mengendalikan kandungan slot dalam Vue 3 dengan pasti?
P粉714844743
P粉714844743 2023-08-30 08:47:17
0
2
483
<p>Saya sedang memindahkan pangkalan kod Vue 2 ke Vue 3. </p> <pre class="brush:php;toolbar:false;"><card> <template #default> <pengepala kad> <tajuk peringkat="3">Tajuk</tajuk> </card-header> <kad-badan v-for="b dalam bodyCount" :key="'b' + b"> Badan {{ b }} </card-body> <pengaki kad v-for="f dalam footerCount" :key="'f' + f"> <teks>Pengaki {{ f }}</text> </card-footer> </template> </kad></pre> <p>Komponen Kad mempunyai fungsi pemaparan yang memanggil <kod>ini.$slots.default()</code>. Walau bagaimanapun, dalam Vue 3 ini mengembalikan kandungan yang berbeza daripada dalam Vue 2. Jadi jika saya melakukan <code>console.log(this.$slots.default())</code> - Saya mendapat tatasusunan dengan 3 elemen, [nod v jenis "header", taipkan Nod v daripada Simbol(Fragmen), nod v jenis Simbol(Fragmen)]</p> <p>Secara lebih khusus, ia tidak mengenali pengaki/badan kad sebagai komponen, sebaliknya saya melihat simbol (serpihan) dalam jenis. Pengepala kad sebenarnya baik kerana ia tidak berada di dalam gelung v-untuk. </p> <p>Terdapat logik di dalam fungsi pemaparan komponen kad yang perlu mengetahui berapa banyak komponen teks/pengaki yang ada padanya. Jadi saya perlu dapat memberitahu jenis komponen. Adakah ini tidak boleh dilakukan dalam Vue 3? Saya boleh mengagak ini ada kaitan dengan v-for di sini, tetapi saya tidak pasti bagaimana sebenarnya untuk mendapatkan v-nod akhir. Dalam contoh ini, bukannya 3 elemen, saya mahu tatasusunan mengandungi pengepala kad + semua badan kad + semua pengaki kad. </p>
P粉714844743
P粉714844743

membalas semua(2)
P粉865900994

Reka bentuk komponen kad anda tidak kelihatan bermakna bagi saya. Saya cadangkan anda pertimbangkan semula.

Ini ialah slot render taman permainan yang ringkas

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>

Sila ambil perhatian amaran. Vue tidak akan memaparkan card-header di sini kerana ia tidak dapat menghuraikannya.

[Vue warn]: Failed to resolve component: card-header
If this is a native custom elemen

Jika anda boleh mengakses data, mengapa lulus slots操作card-body/card-footer项目直接通过bodyCount?

Jika ia kelihatan tidak munasabah pada saya.

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

Ternyata - serpihan boleh dikembangkan melalui sifat Kanak-kanak pada setiap elemen tatasusunan. Jadi dalam kes ini, v-for menghasilkan nod v, yang merupakan serpihan, tetapi kita boleh membuat kesimpulan lebih lanjut dengan melihat sifat Kanak-kanak.

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan