Vue 3 cli-service 应用程序:当从其他组件导入带有插槽的组件时,出现“在渲染函数之外调用插槽“默认””警告

hyp*_*hor 3 slots vue.js vuejs3 vue-composition-api

MCVE

我有一个Tabpane将插槽作为输入的组件。从模板导入后,它会按预期工作。

<Tabpane>
    <div caption="I am div 1">Div 1</div>
    <div caption="I am div 2">Div 2</div>
</Tabpane>
Run Code Online (Sandbox Code Playgroud)

但是,当从其他组件导入时(Composite在示例中),它会触发以下警告:

Slot "default" invoked outside of the render function:
this will not track dependencies used in the slot. Invoke the slot function inside the render function instead. 
Run Code Online (Sandbox Code Playgroud)
Slot "default" invoked outside of the render function:
this will not track dependencies used in the slot. Invoke the slot function inside the render function instead. 
Run Code Online (Sandbox Code Playgroud)

hyp*_*hor 5

解决了。

问题是我是slots.default()从内部调用的setup,但不是在返回的渲染函数内调用。

该组件也反映了一种非常初级的反应性方法。现在我更了解了。旧的有问题的解决方案仍然存在src/components/Tabpane.vue

不触发警告的正确解决方案是:

// src/components/Tabpane2.vue

<script>
import { defineComponent, h, reactive } from "vue";

export default defineComponent({
  name: "Tabpane2",
  props: {
    width: {
      type: Number,
      default: 400,
    },
    height: {
      type: Number,
      default: 200,
    },
  },
  setup(props, { slots }) {
    const react = reactive({
      selectedTab: 0,
    });
    return () =>
      h("div", { class: ["vertcont"] }, [
        h(
          "div",
          {
            class: ["tabs"],
          },
          slots.default().map((tab, i) =>
            h(
              "div",
              {
                class: {
                  tab: true,
                  selected: i === react.selectedTab,
                },
                onClick: () => {
                  react.selectedTab = i;
                },
              },
              [tab.props.caption]
            )
          )
        ),
        h(
          "div",
          {
            class: ["slotscont"],
            style: {
              width: `${props.width}px`,
              height: `${props.height}px`,
            },
          },
          slots.default().map((slot, i) =>
            h(
              "div",
              {
                class: {
                  slot: true,
                  active: react.selectedTab === i,
                },
              },
              [slot]
            )
          )
        ),
      ]);
  },
});
</script>

<style>
.tab.selected {
  background-color: #efe;
  border: solid 2px #afa !important;
  border-bottom: transparent !important;
}
.tab {
  background-color: #eee;
}
.tabs .tab {
  padding: 5px;
  margin: 2px;
  border: solid 2px #aaa;
  border-radius: 8px;
  border-bottom: transparent;
  cursor: pointer;
  user-select: none;
  transition: all 0.5s;
  color: #007;
}
.tabs {
  display: flex;
  align-items: center;
  margin-left: 5px;
}
.vertcont {
  display: flex;
  flex-direction: column;
  margin: 3px;
}
.slotscont {
  position: relative;
  overflow: scroll;
  padding: 5px;
  border: solid 1px #777;
}
.slot {
  visibility: hidden;
  position: absolute;
}
.slot.active {
  visibility: visible;
}
</style>
Run Code Online (Sandbox Code Playgroud)