Using <component> :is in Vue <script setup>

Viewed 829

I want a button to toggle between two views on click. The code is:

<template>
  <button @click="switchSheet">{{ currentSheet }}</button>
  <component :is="sheetView" :key="componentKey" />
</template>

<script setup>
import DisplaySheetClassrooms from "./components/ds-classrooms.vue";
import DisplaySheetChromebooks from "./components/ds-chromebooks.vue";

let sheetView = DisplaySheetClassrooms;
let currentSheet = ref("HS Classrooms");

const switchSheet = () => {
  if (sheetView == DisplaySheetClassrooms) {
    sheetView = DisplaySheetChromebooks;
    currentSheet.value = "HS Chromebooks";
  } else {
    sheetView = DisplaySheetClassrooms;
    currentSheet.value = "HS Classrooms";
  }
};

Documentation states

":is can contain either:

the name string of a registered component, OR
the actual imported component object"

I am using the actual imported component but looking at Devtools switchView never changes value on click. I also tried it with string quotes and still no good. I tried solution here but it did not work for me. Could somebody clarify how to get this working . Thanks in advance.

1 Answers

This seems to work for me:

Use a components object and have the component name key (sheetView in your case) used to target the key in the component :is value

example:

<template>
  <button @click="switchSheet">{{ currentSheet }}</button>
  <component :is="components[currentSheet]" :key="currentSheet" />
</template>

<script setup>
import DisplaySheetClassrooms from "./components/ds-classrooms.vue";
import DisplaySheetChromebooks from "./components/ds-chromebooks.vue";

let currentSheet = ref("DisplaySheetChromebooks");

// create an object key (doesn't need to be a ref)
const components = {
  DisplaySheetChromebooks,
  DisplaySheetClassrooms,
}

const switchSheet = () => {
  if (currentSheet === "DisplaySheetClassrooms) {
    currentSheet = "DisplaySheetChromebooks";
  } else {
    currentSheet = "DisplaySheetClassrooms";
  }
};
</script>
Related