簡體   English   中英

在 vue.js 中渲染子組件之前等待父組件安裝/准備好

[英]Wait until parent component is mounted / ready before rendering child in vue.js

在我的 SPA 應用程序中,我有一個<app-view>包裝器,它處理基本應用程序代碼(加載用戶數據、渲染導航欄和頁腳等),並有一個用於渲染實際頁面的slot 僅當用戶數據可用時才會呈現插槽

創建此包裝器是因為某些頁面需要不同的基本代碼,因此我無法再將此基本代碼保留在包含<router-view>的主應用程序中。

我嘗試查看 vue-router 是否提供高級選項或建議用於切換基本代碼的設計模式,但沒有找到任何內容。

問題是子組件將在父組件安裝之前呈現,即在父組件決定不呈現子組件之前(因為它正在加載用戶數據)。 這會導致像undefined as no attribute foo這樣的錯誤。

正因為如此,我正在尋找一種方法來推遲子渲染,直到它的父被掛載。

我有一個類似的問題,雖然不是 SPA。 我有需要來自父級數據的子組件。 問題是數據只會在父級完成安裝后生成,所以我最終在子級中得到了空值。

我就是這樣解決的。 我使用v-if指令僅在父級完成安裝后才安裝子級。 (在mounted()方法中)見下面的例子

<template>
  <child-component v-if="isMounted"></child-component>
</template>
<script>
  data() {
     isMounted: false
  }, mounted() {
     this.isMounted = true
  }
</script>

之后,孩子可以從父母那里獲取數據。 它有點無關,但我希望它能給你一個想法。 投反對票前請三思。

在嘗試了幾個選項后,看起來我需要咬緊牙關明確定義我的組件所依賴的數據,如下所示:

<app-view>
  <div v-if='currentProfile'>
    ...
  </div>
</div>

currentProfile從 vuex store getter 接收,並在app-view獲取)

對於任何想要在父組件從 API 調用獲取數據后立即顯示子組件的人,您應該使用以下內容:

<template>
  <child-component v-if="itemsLoaded"></child-component>
</template>

<script>
  data() {
     itemsLoaded: false
  },
  methods: {
      getData() {
          this.$axios
              .get('/path/to/endpoint')
              .then((data) => {
                  // do whatever you need to do with received data
                  
                  // change the bool value here
                  this.itemsLoaded = true
          })
          .catch((err) => {
              console.log(err)
          })
      },
  }, 
  mounted() {
     this.getData()

     // DONT change the bool value here; papa no kiss
     this.itemsLoaded = true
  }
</script>

如果你嘗試改變mounted()方法中的布爾值this.itemsLoaded = true ,在調用getData()方法后,你會得到不一致的結果,因為你可能會也可能不會收到this.itemsLoaded = true之前的數據被執行。

您實際上可以將v-if放在組件中的<slot>標簽上。

 new Vue({ el: '#app', render: function(createElement) { return createElement( // Your application spec here { template: `<slotty :show="showSlot"><span> here</span></slotty>`, data() { return { showSlot: false } }, components: { slotty: { template: `<div>Hiding slot<slot v-if="show"></slot>.</div>`, props: ['show'] } }, mounted() { setTimeout(() => this.showSlot = true, 1500); } } ); } })
 <script src="//unpkg.com/vue@latest/dist/vue.js"></script> <div id="app"> </div>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM