What I want to do is - the user clicks the router-link - this does not actually do a navigation but just refreshes the page with new data. This is no good for accessibility because the user does not know a navigation happened, but good for performance because full navigation not required.
So I would like some way to solve that problem.
The way I might naively expect to solve the problem is wait for navigation to be over and run a callback, or use a promise and when promise completes run code. The code running when navigation over would put the focus on some element at navigation finished.
I was hoping I could do something obvious like the following
<router-link :to="(router) => {
router.push('/').onComplete(() => {
code to set focus here
});
}"
but it doesn't look like that is possible.
How should I solve my problem, as close to this solution as possible please.
This sounds like you might be using the wrong tools for the job. If you aren't actually navigating, there's no good reason to use router link - if you purely want to have the aesthetics of a link, use <a>. And if you are just expecting data to be refreshed, don't use router.push but simply call the function you want by attaching a listener to the link. If you want to show some kind of loading animation during the data fetching, you could either just set a variable, or use a library like vue-wait
In your case this could be something like:
<a #click="onClick">Link to click</a>
...
data(){
return {
isLoading:false
}
}
methods:{
async onClick(){
this.isLoading=true
await fetch(...)
this.isLoading=false
}
}
To answer your original question as well - yes, it's possible to run code when a navigation is finished. There's quite a few ways to do it, but if you want to specifically run code after a router.push, you can do that - router.push is a promise. So router.push(...).then(...).catch() works as well
This is a follow up to #1458. I'm looking for some direction on how Nuxt expects this to be handled.
I have a menu. When I click on a nuxt-link in the menu, I want to have time to close the menu before the page transition happens. The thing is, I only want that to happen when you click on the nuxt-link in the menu, not every time I go to a certain route (as the previous issue described using a middlewear on the route).
So there are a few different ways to do this, and I'm curious what the "Nuxt" way is?
The way we currently do this, disable the nuxt-link and capture the click, then do a router.push().
<nuxt-link :to="path" event="disabled" #click.native="delayLoad"/>
// Methods
delayLoad(event) {
this.$store.commit("CLOSE_MENU")
setTimeout(()=>{
this.$router.push(event.target.pathname)
}, 2000)
}
Is this a good idea? I just always have an aversion to hijacking nuxt-link and browser navigation like this. It seems janky.
The other ideas we played with were using a query param on the nuxt-link, and then using that in a middlewear to delay the page transition. That seemed worse to me, because now my URL's have a query param in them that is used for an animation, seems like that is abusing query params. This also triggers the page loading progress bar, which isn't really the intent, it's to have a sequenced animation happen, then page load.
It seems to me that perhaps nuxt-link should have a delay prop, or perhaps the page transition config should allow for a delay (like it does with duration)?
I wanted to do this as well and came up with the following solution. Using the new slots api you can more elegantly customise the nuxt-link behaviour:
<nuxt-link v-slot="{ route, href }" :to="path" custom>
<a :href="href" #click.prevent="$emit('navigate', route)">
<slot></slot>
</a>
</nuxt-link>
This will make the link emit a navigate event with the route as a param. You then listen for this event wherever you include your menu component, like this:
<template>
<transition
name="fade"
#after-leave="maybeNavigate"
>
<MainMenu
v-if="menuIsVisible"
#navigate="navigate"
/>
</transition>
</template>
<script>
export default {
data: () => ({
menuIsVisible: false,
navigateToOnMainMenuClose: null,
}),
methods: {
navigate(route) {
this.navigateToOnMainMenuClose = route
this.menuIsVisible = false
},
maybeNavigate() {
if (this.navigateToOnMainMenuClose) {
this.$router.push(this.navigateToOnMainMenuClose)
this.navigateToOnMainMenuClose = null
}
},
},
}
</script>
Whenever you click a nav link in the menu, the route will be stored and the menu will close. After the menu out animation has finished, maybeNavigate() will push the stored route, if there is one. This removes the need for a setTimeout and if you manage to click multiple links in quick succession only the last one will be stored and navigated to.
Since nuxt-link is essentially a wrapped version of vue's router-link, if you look at the documentation for that there is an event property that accepts string or string[], looking at it's source code here: https://github.com/vuejs/vue-router/blob/dev/src/components/link.js#L86
you can see it will register a listener for disabled in this instance. It may make more sense to pass an empty array so that no event listeners are registered, but that's at the cost of readability.
Otherwise, #click.native is the suggested way to handle custom click handlers for router-link (see: https://github.com/vuejs/vue-router/issues/800#issuecomment-254623582).
The only other concerns I can think of are what happens if you click 2 different links in rapid succession and what happens if you click more than once. May just want to add a variable to track if a link has been clicked to prevent firing setTimeout multiple times, which could navigate you from page A to B and then to C as all timeouts will fire if not canceled. Or maybe you want to only navigate to the 'last' link clicked, so if another link is clicked, you would cancel the earlier setTimeout. This is realistically an edge case that probably won't be an issue, but worth exploring.
Otherwise, IMO, looks good to me. This seems like the simplest way to implement this without having to create a custom component / plugin. I'm no expert, but is likely how I would implement this functionality as well. It would be nice to see a delay option though since I can see myself using that functionality as well with vuetify.
Another potential method would be to do your store commit in beforeTransition: https://nuxtjs.org/api/configuration-transition/
Though I'm not sure that there is access to the store there, so you might have to write a custom plugin for that as well. Again, seems more complicated than it's worth for a simple delayed animation. Simple, working code is sometimes the best solution, even if it's not the most extensible option.
See also: How can I transition between two nuxt pages, while first waiting on a child component transition/animation to finish?
for another way of handling this.
i want be able to enable or disable this action:
This works perfect in react-native without redux, but when i add redux this action not works and come back again like the gif
I'm following this links but in this cases, this works with Navigator but i'm not using this prop. i'm using NavigationExperimental.
Thanks for help.
To disable gestures in NavigationExperimental CardStack, use it like this:
render () {
<CardStack
navigationState={navigationState}
... other properties
enableGestures={false}
/>
}
For more info (for RN 0.40) see sources NavigationCardStack.js
When I use Scrollspy it seems to show the scrollbar on the whole webpage. I looked at the source code and it seems to be hardcoded to the body element of the page, so I am guessing this means that it is impossible to put two scrollspys on a webpage?
Have you tried it? I am pretty sure this is supported, let me quote the source:
$('[data-spy="scroll"]').each(function () {
var $spy = $(this)
$spy.scrollspy($spy.data())
})
I've been playing around with Dojo over the last couple of days.
The script below changes the background position of the list item when the mouse is over the link.
dojo.query('a[class=main-menu-link]').forEach(function(linkTwo) {
dojo.connect(linkTwo, "onmouseover", function(evt) {
dojo.query('#main-menu ul li').forEach(function(linkThree) {
dojo.style(linkThree, {
"backgroundPosition": "right center",
});
});
You can see it in action in the right hand side menu: http://www.mechanic-one.suburban-glory.com/
I'm trying to work out the best of way of giving it a smooth transition between the two states... I've been looking on the Dojo documentation page but I'm not sure what is the best way of approaching it.
Check out the Animation quickstart. You can animate css properties and select from a set of existing animation effects and easings. Chaining is possible by requiring the NodeList-fx module.