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`.
reactive
和ref
這種都是遞歸監聽對象中的所有屬性,子屬性等,現在我們需要的僅僅是當最外層的currentComponent.value
變化時,也就是我們重新設置一個組件時vue發生響應,而不是當組件中的一個屬性變化時都觸發響應,所以我們應該使用shallowRef
,這個不會遞歸監聽,只是監聽最外層value
的變化。
transition必須只有單根子節點
[Vue warn]: Component inside <Transition> renders non-element root node that cannot be animated.
Vue3中的transition必須只有單根子節點,component
、keep-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>