Vue3+Vite+TS坑


shallowRef和ref

vue2中經常這樣寫

<component :is="currentComponent" @componentChange="onComponentChange"></component>

如果上了composition-api,那么很可能會用ref(component)來實現這個動態更換組件的操作。

const currentComponent = ref(Component1);
currentComponent.value = Component2;

但這樣做之后得到一個warning,說是檢測到我們把一個Component弄成了reactive對象,可能會導致不必要的性能開銷。

Vue received a Component which was made a reactive object. This can lead to unnecessary performance overhead, and should be avoided by marking the component with `markRaw` or using `shallowRef` instead of `ref`. 

reactiveref這種都是遞歸監聽對象中的所有屬性,子屬性等,現在我們需要的僅僅是當最外層的currentComponent.value變化時,也就是我們重新設置一個組件時vue發生響應,而不是當組件中的一個屬性變化時都觸發響應,所以我們應該使用shallowRef,這個不會遞歸監聽,只是監聽最外層value的變化。

transition必須只有單根子節點

[Vue warn]: Component inside <Transition> renders non-element root node that cannot be animated. 

Vue3中的transition必須只有單根子節點,componentkeep-alive等標簽不會渲染出節點,而在我的組件中又有非單根的組件。所以出現了這個錯誤。

解決辦法就是盡量把組件寫成單根。

父組件無法給子組件設置屬性

場景:<script setup lang="ts">

<template>
  <div class="simple-top-bar">
    <!-- 給子組件設置 id -->
    <IconTitleBanner id="icon-and-title" />
    <LanguageSelector class="language-selector" />
  </div>
</template>

<script setup lang="ts">
import LanguageSelector from "@/components/public/LanguageSelector.vue";
import IconTitleBanner from "@/components/public/IconTitleBanner.vue";
</script>

<style scoped>
.simple-top-bar {
  display: flex;
  flex-direction: row;
}
/* 通過id來找到子組件,設置屬性 */
#icon-and-title {
  flex: 1;
}
</style>

子組件

<template>
  <div class="icon-and-title">
    <img src="@assets/imgs/doge-icon-21.png" alt="" />
    <h2 class="web-title">DOGE Admin</h2>
  </div>
  <div></div>
</template>

<script setup lang="ts"></script>

<style scoped>
.icon-and-title img {
  display: inline-block;
  width: 40px;
  height: 40px;
  margin-right: 10px;
}
.icon-and-title h2 {
  display: inline-block;
  color: white;
  font-size: 1.4em;
  line-height: 40px;
}
</style>

結果發現樣式設不上去,id就沒綁定上去,父組件的scope也沒綁定到子組件上

手動添加id和scope后樣式被應用了

解決

sorry,我是傻逼,我注意到控制台有這樣一條消息

不能自動繼承非prop屬性,因為我們的組件被渲染成Fragment或文本根節點

Vue3中的多根組件就叫Fragment組件,詳見:片段

然后原因就是因為我寫錯了,不小心多寫了個div,半小時白費。。。

子組件

<template>
  <div class="icon-and-title">
    <img src="@assets/imgs/doge-icon-21.png" alt="" />
    <h2 class="web-title">DOGE Admin</h2>
  </div>
- <div></div>
</template>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM