beforeDestroy hook for nuxt page component - vue.js

I need to emit some events before leaving a particular page. So I'm thinking of using the beforeDestroy hook to do this. But it seems not triggering the method.
// pages/view.vue
beforeDestroy() {
this.$alertEvent('finished')
}
I'm also using the keep-alive directive on the <nuxt>
How can I trigger this method effectively?

for Nuxt 3 you can use onBeforeUnmount
onBeforeUnmount(() => {
alert('the component is destroyed')
})
https://vuejs.org/api/composition-api-lifecycle.html#onbeforeunmount

i think this should work .
maybe you have problem with this.$alertEvent('finished') so you cannot see the result
beforeDestroy() {
alert('the component is destroy')
},

If your component wrapped inside - this is what Nuxt keep-alive directive does, then your component will not be destroyed.
You should use deactivated hook.
https://v2.vuejs.org/v2/api/#deactivated

Related

Nuxt.js | watching route changes on component

I am pushing route parameter/query changes from a component, and I want to watch changes from another component. I was handling the issue by using below syntax on vue
watch: {
"$route.params.index": function (val) {
console.log(val)
}
}
What is the corresponding syntax in nuxt ?
Thanks in advance.

Detect exiting route changes in Vue

I'm working on a component which enables the user to undo the deletion of an item. However, the item should be deleted when the user navigates to another route. To achieve this I'm watching the route like so:
`watch: {
$route(to, from) {
if (this.showUndo === true) {
console.log('item will be deleted');
this.confirmDelete();
}
},
},
`
Unfortunately, this gets only triggered when I enter this specific route and not on exiting it. An explanation why that is or an alternative to my watch: - method would be much appreciated!
Basically I'm looking for an alternative to beforeRouteLeave since this is a sub-component and therefore I can't use Navigation Guards. Thanks!
Vue lifecycle hook- BeforeDestroy is fired right before teardown. Your component will still be fully present and functional. If you need to cleanup events or reactive subscriptions,
beforeDestroy would probably be the time to do it.
<script>
export default {
beforeDestroy() {
//Try like this
this.confirmDelete();
console.log('item will be deleted');
}
}
</script>
Ref - https://v2.vuejs.org/v2/api/#beforeDestroy

Vue.js lifecycle hooks

I was sure that the lifecycle hooks in Vue were 8 (beforeCreate, created, beforeMount, mounted, beforeUpdate, updated, beforeDestroy, destroyed) but today I found out(https://v2.vuejs.org/v2/api/#activated) that there are 3 more:
• activated
• deactivated
• error captured
Somebody can explain how these 3 work? Is possible to test them with a console.log? (Just to understand when they are called)
First, a little context:
In Vue 2.0+, there is a built-in component called <keep-alive> that takes the child element inside it and keeps it alive in memory as a cached component. Normally, Vue would reuse a component if its props change, but maybe the component is very complex and is slow to update. You could wrap it with <keep-alive> and the component would be cached for the props provided to it.
When a component inside a <keep-alive> is updated, the activated life-cycle hook is called. When that component is cached and set aside, the deactivated life-cycle hook is called.
The errorCaptured life-cycle hook was added in Vue 2.5.0 and is called whenever an error is captured by a descendent component. So, if you have a component called A that has a child component called B, and that has a child component called C, then if C captures and error, the errorCaptured life-cycle hook will be called on both A and B.
These hooks all work the same as any other hook, so use them the same way.
export default {
data() {
return {}
},
mounted() {
console.log('mounted hook called')
},
errorCaptured(err, vm, info) {
console.log('error captured in component', vm)
console.error(err)
console.log('error info:', info)
},
activated() {
console.log('cached component is being used again')
},
deactivated() {
console.log('component is being kept alive in cache for now')
}
}
https://v2.vuejs.org/v2/api/#activated
https://v2.vuejs.org/v2/api/#deactivated
https://v2.vuejs.org/v2/api/#errorCaptured
I know it's already late for this answer but someone might also looking answer for
the problem. Vue.js disable's console.log function by default, so we have to enable it.
Just put "rules": { "no-console": "off",} on package.json
Cheers

Vue.js: how to use the afterEnter hook with an async component

I would like to use JS Hook as described here. Specially, I want to use the afterEnter hook with an async component.
This is my async component:
Vue.component('example', function(resolve, reject){
let data = {
text: 'test data',
};
$.post('http://example.com', data, function(r){
r = JSON.parse(r);
if( r.success ) {
resolve({
template: r.data,
afterEnter: function(el, done){
console.log('test');
}
});
}
});
});
This is what the ajax call gets from the server, and it's what is passed to the template in r.data.
<transition v-on:after-enter="afterEnter"></transition>
These are the two errors that I get.
[Vue warn]: Property or method "afterEnter" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option.
[Vue warn]: Invalid handler for event "after-enter": got undefined
Is it possible to use JS hooks with async components? And if not, how should I approach this? My objective is to run custom JS after Vue (and/or vue-router) inject the component template onto the page, so that I can initiliaze image sliders and whatnot. It is important that my custom JS fires every time the component is navigated to, and not only on the first load.
Thank you.
That warning means that Vue is looking for (but unable to find) a property or method named "afterEnter", which you reference in your template. You have defined afterEnter in your resolve function as if it is a lifecycle hook, but it needs to be one of your Vue instance's methods.
So, your resolve function should look like this:
resolve({
template: r.data,
methods: {
afterEnter: function(el, done) {
console.log('test');
}
}
});

vue 2 lifecycle - how to stop beforeDestroy?

Can I add something to beforeDestroy to prevent destroying the component? ?
Or is there any way to prevent destroying the component ?
my case is that when I change spa page by vue-route, I use watch route first, but I found that doesn't trigger because the component just destroy..
As belmin bedak commented you can use keep-alive
when you use keep-alive two more lifecycle hooks come into action, they are activated and deactivated hooks instead of destroyed
The purpose of keep-alive is to cache and to not destroy the component
you can use include and exclude atteibutes of the keep-alive element and mention the names of the components that shoulb be included to be cached and be excluded from caching. Here is documentation
in case you want to forecefully destroy the component even if its cached you can use vm.$destroy() here
Further you can console.log in all the lifecycle hooks and check which lifecycle hook is being called
You can use vue-route navigation-guards, so if you call next(false) inside the hook, navigation will be aborted.
router.afterEach((to, from) => {
if(your condition){
next(false) //this will abort route navigation
}
})
According to this source: https://router.vuejs.org/guide/advanced/navigation-guards.html
I suggest you to do something like this with your Vue router:
const router = new VueRouter({ }); // declare your router with params
router.beforeEach((to, from, next) => {
if(yourCondition){
next(false); // prevent user from navigating somewhere
} else {
return next(); // navigate to next "page" as usual
}
});
This will prevent destroying your Vue instance on your declared condition, and it will also prevent user from navigating to another page.
Although I would consider #Vamsi Krishna "keep-alive" answer to be the proper "VueJS way" to solve this issue, I was not willing to refactor part of my code for it.
I also couldn't use the Vue router navigation guard "as-is" because in the case of beforeRouterLeave, even though using next(false) prevented the route from continuing, the component in Vue was ALREADY destroyed. Any state I had that wasn't saved would be lost, which defeats the purpose of cancelling the route change.
This wasn't what I wanted, as I needed the state of the form/settings in the component to remain (the component reloaded itself and kept the same route).
So I came up with a strategy that still used a navigation guard, but also cached any form changes/settings I had in the component in-memory, eg. I add a beforeRouteLeave hook in the component:
beforeRouteLeave (to, from, next) {
if (!this.isFormDirty() || confirm('Discard changes made?')) {
_cachedComponentData = null // delete the cached data
next()
} else {
_cachedComponentData = this.componentData // store the cached data based on component data you are setting during use of the component
next(false)
}
}
Outside the Vue component, I initialize _cachedComponentData
<script>
let _cachedComponentData = null
module.exports = {
...component code here
}
<script>
Then in the created or mounted life cycle hooks, I can set the _cachedComponentData to "continue where the user left off" in the component:
...
if (_cachedComponentData) {
this.componentData = _cachedComponentData
}
...