Loading

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>
posted @ 2021-10-28 14:41  yudoge  阅读(1904)  评论(0编辑  收藏  举报