Extending Vue Lifecycle Hooks

I have a special application where I would like to run a method on every component when it is mounted. So I could have the method as a global mixin or something and then simply do..

mounted(){
   this.mySpecialMethod();
}

However, I was wondering if it is possible to simply extend Vues mounted hook so the method is always run on every component when it is mounted. I have not been able to find in info on this.

If you really want to have everything call your mounted hook, you can use a global mixin.

Below, we have the mixin myMixin that will log to console every time something is mounted or destroyed. When you run the example, you can see that every time the plus button is clicked, it runs both the component's mounted hook as well as the mixin's hook.

If you want to extend this so that it can be reusable as a library, you can create a plugin out of it.

const foo = {
  template: "<div @click='onClick'>hello</div>",
  mounted() {
    console.log("Foo's mounted");
  },
  methods: {
    onClick() {
      console.log("click");
    }
  }
}

const myMixin = {
  mounted() {
    console.log("I've been mounted");
  },
  destroyed() {
    console.log("I've been destroyed");
  }
};

Vue.mixin(myMixin);

const app = new Vue({
  el: "#app",
  data() {
    return {
      foos: []
    };
  },
  components: {
    foo
  },
  methods: {
    add() {
      this.foos.push("fizz");
    },
    remove() {
      this.foos.pop();
    }
  }
});
<script src="https://cdn.jsdelivr.net/npm/vue"></script>

<div id="app">
  <button @click="add()">+</button><button @click="remove()">-</button>
  <ul>
    <li v-for="f in foos">
      <foo></foo>
  </ul>
</div>

as stated in this jsfiddle: http://jsfiddle.net/posva/wtpuevc6/ , you have no obligation to use webpack or .vue files.

the code below is not from me and all credit goes to this jsfiddle creator:

create an index.html file:

<script src="https://npmcdn.com/vue/dist/vue.js"></script>
<script src="https://npmcdn.com/vue-router/dist/vue-router.js"></script>
<script src="/topic/js/home.js"></script>
<script src="/topic/js/foo.js"></script>
<script src="/topic/js/router.js"></script>
<script src="/topic/js/index.js"></script>

<div id="app">
  <router-link to="/topic/">/home</router-link>
  <router-link to="/topic/foo">/foo</router-link>
  <router-view></router-view>
</div>

home.js

const home = { template: '<div>home</div>' }

foo.js

const foo = { template: '<div>foo</div>' }

router.js

const router = new vuerouter({
  mode: 'history',
  routes: [
    { path: '/', component: home },
    { path: '/foo', component: foo }
  ]
})

index.js

new vue({
    router,
  el: '#app',
  data: {
    msg: 'hello world'
  }
})

appreciate the framework...

just a sidenote: .vue files are really awesome, you should definitely try them if not using them is not a requirement

finally, i found the solution myself, very simple:

the component imported itself is not a constructor, but we can easily make a constructor:

import mycomponent from './components/mycompnent.vue';
const mycomponentconstructor = vue.extend(mycomponent);

so the final solution is:

import mycomponent from './components/mycompnent.vue';
export default {
    mounted() {
        const mycomponentconstructor = vue.extend(mycomponent);
        const vm = new mycomponentconstructor();
        vm.$mount('#some-place');
    }
}

the constructor of the lazy loaded module should do that

@ngmodule({...})
export class mylazymodule {
  constructor(/* service injection here if required */) {
    console.log('lazy module loaded');
  }
}

upgrade your vue version to 2.2.0 or greater. the fiddle has 2.3.2, the latest one. and your local version is 2.1.0.

in 2.2.0 and above, activated and deactivated will fire for all nested components inside a tree.

read here: https://vuejs.org/v2/api/#keep-alive

update using: npm update --save vue


Tags: Vue.Js Vuejs2