I'm have an issue where buttons and links jitter on state change (when clicking on the "Sign Out" button). I tried both v-if and v-show and the jitter persists. Video of the issue: https://www.veed.io/view/89672f51-f55c-411c-883f-440b02cfa4de?panel=share Reproduction: https://stackblitz.com/edit/nuxt-starter-a8hntf?file=app%2Fcomposables%2FuseStoreAuth.ts.
<div>
<div>
<button @click="setColorTheme()">
<IconDarkMode />
</button>
<div v-if="!signedIn && !pending">
<NuxtLink to="/sign-in">
<span>Sign In</span>
<IconSignIn />
</NuxtLink>
</div>
</div>
<div
v-if="signedIn && !pending">
<NuxtLink to="/profile">
<span>Profile</span>
<IconProfile />
</NuxtLink>
<button to="/sign-in" @click="signOut">
<span>Sign Out</span>
<IconSignOut />
</button>
</div>
</div>
I also have a 300ms delay for signedIn
state in signOut function to wait until page transition ends, but jitter still persists.
if (res.ok) {
const data = await res.json();
state.successMessage = data.message;
if (route.path === '/') {
window.location.reload();
} else {
window.location.href = '/';
}
setTimeout(() => {
state.signedIn = data.signedIn;
}, 300);
}
Looking for a possible solution.
The solution is recommended by @Estus Flask in the comments above.
Regarding the UI element jitter:
It's "pending" condition that forces the layout to jump. It's not needed there if you need transitions, i.e. either one of these divs with v-ifs should exist in the layout an any moment of time.
Regarding the buttons changing before page transition starts:
You need to use separate state for UI that will differ from
store.signedIn
and use to promises for correct control flow. I.eonSignOutClick = async () => { await store.signOut(); uiSignedIn.value = store.signedIn }
. Also,navigateTo
androuter
methods return promises, you may want to await them too.