Search code examples
vuejs3vue-composition-apivue-script-setup

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


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.


Solution

  • 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>