I have a generic component linked to a computed value to simulate routing. There is a current page property, and three links, whenever the user clicks on a link, that property gets updated via the renderPage.
Before switching to <script setup>
the code worked fine, now, the generic component doesn't seem to do anything.
Here's the code:
<script setup>
import { computed, ref } from "vue";
import HomePage from "./components/HomePage.vue";
import LoginPage from "./components/LoginPage.vue";
import UsersPage from "./components/UsersPage.vue";
const currentPage = ref("Home");
const renderPage = computed(() => `${currentPage.value}Page`)
function showHomePage() {
currentPage.value = "Home";
}
function showLoginPage() {
currentPage.value = "Login";
}
function showUsersPage() {
currentPage.value = 'Users';
}
</script>
<template>
<header class="header">
<span class="logo">
<img src="@/assets/vue-heart.png" width="30" />C'est La Vue
</span>
<nav class="nav">
<a href="#" @click.prevent="showHomePage">Home</a>
<a href="#" @click.prevent="showUsersPage">Users</a>
<a href="#" @click.prevent="showLoginPage">Login</a>
</nav>
</header>
<component :is="renderPage" />
</template>
The generic component is able to render the components properly if set manually, but whenever linked to the renderPage
computed property, it doesn't work anymore.
The renderPage
when added inside a mustache works as expected, updating the string as it should.
import HomePage from "./components/HomePage.vue";
make a variable HomePage
, not something in the the template context named HomePage
. To refer to an imported component by name, make an object containing components by name:
const components = {HomePage, LoginPage, UserPage};
Then use it in the template:
<component :is="components[renderPage]" />
But better is to reference the components directly:
<script setup>
import { computed, ref } from "vue";
import HomePage from "./components/HomePage.vue";
import LoginPage from "./components/LoginPage.vue";
import UsersPage from "./components/UsersPage.vue";
const renderPage = ref(HomePage);
</script>
<template>
<header class="header">
<span class="logo">
<img src="@/assets/vue-heart.png" width="30" />C'est La Vue
</span>
<nav class="nav">
<a href="#" @click.prevent="renderPage = HomePage">Home</a>
<a href="#" @click.prevent="renderPage = UserPage">Users</a>
<a href="#" @click.prevent="renderPage = LoginPage">Login</a>
</nav>
</header>
<component :is="renderPage" />
</template>