I'm facing an issue with nuxt 3 where when I deployed my website using SSG, the first route which is the index route loaded 2 components so for example
if I had index.vue like this
<template>
<Component1 />
<Component2 />
</template>
it would show like this
<template>
<Component1 />
<Component1 />
<Component2 />
<Component2 />
</template>
and this only applies to the main route (/) and when I switch to any other route then come back the problem seems to be fixed but when I refresh it always generates double components.
Related
Let's say I want to create my own Link.
const Link = ({ href, style }) => {
return <a href={href} class={style}>
<Slot />
</a>
}
Now I want to use this Link in the Menu of my website, and the Menu component is imported inside the main layout.
// main layout
<Menu />
<Slot />
<Footer />
Here, I get this error:
[vite] Internal server error: can not be rendered because one of its ancestor is already a .
This goes against the HTML spec: https://html.spec.whatwg.org/multipage/dom.html#interactive-content
Why does this happen? It's because inside the main layout, we practically included another <Slot /> by including <Menu /> which contains <Link /> components.
So, what do you think we should do here?
If we ask all developers to specify the name of the slot, that's highly inefficient and dirty:
<Link href="/">
<span q:slot='link'>About us</span>
</Link>
This is very ugly and inefficient. I don't have many slots in my Link component. I have one Slot. I should not be specifying a name for it.
What should I do?
I have a global sidebar component TheSidebar.vue:
<template>
<aside>
<slot></slot>
</aside>
</template>
In Blogs.vue (a page component) I try to register two components.
<template>
<div>
<h1>Experiences</h1>
<TheSidebar>
<SearchBlog />
<CategoryCheckboxFilter />
</TheSidebar>
<ExperienceList />
</div>
</template>
It seems like I cannot register two components in a slot?
Is this a good setup anyway and who do I have to achieve this?
Update
It's just working fine now and I can register more than one component in a <slot />. I think some webpack building issue before.
I want to load 3 Components at a time like that:
<app-header />
<app-main />
<app-footer />
But I want to load Router View also in this page.
<app-header />
<router-view />
<app-footer />
While I will click on the router-link then <app-main /> will be vanish and <router-view /> will be visible.
Is there any better way to handle it without if or show?
You can pass router-view via slot to your app-main component like this:
<app-header />
<app-main>
<router-view/>
</app-main>
<app-footer />
Also you need to insert a slot tag in your app-main component like this:
<template>
<!-- your code -->
<slot></slot>
<!-- ... -->
</template>
For more details visit https://v2.vuejs.org/v2/guide/components-slots.html
I am design an Vuejs app which page render based on route.
e.g. for
route = /, Component = Main.vue
<template>
<div>
<toolbar :user="user"></toolbar>
<app-content></app-content>
</div>
</template>
route = /:user, Component = User.vue
<template>
<div>
<toolbar :user="user"></toolbar>
<userHeader></userHeader>
<app-content></app-content>
</div>
</template>
When the page is show, the toolbar component will fetch data from server, the problem is, when the page go from / to /user, the data fetching data X 2 because that are 2 toolbar components in the app itself.
How should resolve this issue ? is that any way to reuse share component instances like toolbar ?
or should i put the design in one whole component instead ? ( use v-if to show hide the additional component)
You should be having <toolbar /> outside of <router-view></router-view>.
So your code should look like:
<div id="app">
<toolbar user="user" />
<router-view />
</div>
With this <toolbar /> won't change even if you change your routes, and will result in data fetching for a single time only.
Reading the Vue Router documentation, the way to achieve route transitions is by doing:
<transition>
<router-view></router-view>
</transition>
But the problem is that VuePress is handling all the routing behind the scenes, so I can't figure out where to put that transition component.
Is there anyway to do this in VuePress?
You need to create your own theme or eject default.
In your Page.vue component wrap <Content /> component in <transition>
<transition name="fade">
<Content :custom="false"/>
</transition>
If you want to change something except <Content /> part, use binding
<transition name="header-fade" mode="out-in">
<header v-bind:key="$page.key">
<h1>{{ $page.title }}</h1>
</header>
</transition>
As far as I know –
Router transitions won't be possible, because as soon as you run 'vuepress build' the whole site will be static.
So no more routing is done and therefore the page will reload new content instead of dynamically adding it.