sazr
sazr

Reputation: 25928

Component `mounted` fires twice on page load

I have a very weird error where on page load a components mounted and beforeMount fire/run twice? Each of my components represents a page, so when I load the page on mywebsite.com/contact the Contact.vue functions mounted and beforeMount fire/run twice but if I load the page on mywebsite.com/foo the Contact.vue functions mounted and beforeMount fire/run once (which is what I think? should happen).

Any idea why these functions would execute twice? I have a bit of finicky setup but it work nicely for dynamic templates.

router/index.js:

const router = new Router({
routes: [
  {
      path: (window.SETTINGS.ROOT || '') + '/:slug',
      name: 'Page',
      component: Page,
      props: true
  },
]
})

Page.vue:

<template>
  <component v-if="wp" :is="templateComponent" v-bind:wp="wp"></component>
  <p v-else>Loading...</p>
</template>

<script type="text/javascript">

import { mapGetters } from 'vuex'
import * as Templates from './templates'

// Map templates
let templateCmps = {}
_.each(Templates, cmp => {
  templateCmps[cmp.name] = cmp
})

export default {

props: ["slug"],

components: {
  ...templateCmps

  // Example:
  // 'default': Templates.Default,
  // 'contact': Templates.Contact,
  // 'home': Templates.Home,
},

computed: {
  ...mapGetters(['pageBySlug']),

  wp() {
    return this.pageBySlug(this.slug);
  },

  templateComponent() {
    let template = 'default' // assign default template

    if (!_.isNull(this.wp.template) && this.wp.template.length)
      template = this.wp.template.replace('.php','').toLowerCase()

    return template
  }
},

created() {
  this.$store.dispatch('getPageBySlug', { slug: this.slug })
}
}
</script>

Contact.vue:

<template>
    <main></main>
</template>

<script type="text/javascript">


export default {

    name: 'contact',

    mounted() {
      console.log('Contact::mounted') // this outputs twice
    },

    beforeMount() {
      console.log('Contact::beforeMount') // this outputs twice
    }
}

</script>

Upvotes: 13

Views: 9509

Answers (1)

morphatic
morphatic

Reputation: 7955

I had (have) a similar issue. I'm not 100% sure about this, but I think the issue may be caused by vuex. Vuex has it's own internal instance of Vue (created here in the resetStoreVM() function called in the constructor()). My suspicion is that this internal instance of Vue causes some components to be re-created, which in turn triggers the lifecycle events for those components to fire more than once.

If not in vuex, is it possible that you're creating more than one instance of Vue (i.e. new Vue({})) in your app? Alternatively, is there some code that is causing your primary Vue instance or the Contact component to be initialized more than once? That's all I can think of that might cause this.

Upvotes: 2

Related Questions