4

The Vue Router loaded before the main Vue instance, but to load that Router, I supposed to have some information ready to then pass them as Property to this Route. In this example it's the currentTime from main Vue Instance to pass to Home screen.

Maybe keeping everything on $Store would fix it, but at the moment to project doesnt have Vuex implemented. I can't do it now.

Any suggestion?

main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import './registerServiceWorker'

Vue.config.productionTip = false

new Vue({
  data() {
    return {
      currentTime: 0
    }
  },
  router,
  created(){
    console.log("Vue created")
  },
  mounted(){
    console.log("Vue mounted")
    this.currentTime = Date.now()
  },
  render: h => h(App)
}).$mount('#app')

/router/index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'home',
    component: Home,
    props: {time: "I_WANT_MY_TIME_HERE"},
    beforeEnter (to, from, next){
      console.log("beforeRouteEnter on Home")
      next()
    } 
  },
  {
    path: '/about',
    name: 'about',
    component: () => import('../views/About.vue')
  }
]

const router = new VueRouter({
  routes
})

export default router

/components/Home.vue

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png">
    <h1>{{displayTime}}</h1>
    <HelloWorld msg="Welcome to Your Vue.js App"/>
  </div>
</template>

<script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue'

export default {
  name: 'home',
  props: ['time'],
  data() {
    return {
      displayTime: 0
    }
  },
  mounted(){
    console.log("mounted Home")
    this.displayTime = this.time
  },
  components: {
    HelloWorld
  }
}
</script>

enter image description here

enter image description here

3rdSenna
  • 344
  • 2
  • 16
  • Why not just get the time in the component? – Josef Oct 22 '19 at 16:57
  • As I said, it's an example =D – 3rdSenna Oct 22 '19 at 17:05
  • 1
    You can access the root-instance with `this.$root` from any component. Not really best practice, but should be enough for an example. – Josef Oct 22 '19 at 17:11
  • You can try with the beforeRouteEnter guard in the Home component. – equi Oct 22 '19 at 17:46
  • @josef98, it worked. As you said, it doesn't look the best practice. I'll keep trying to to find a better way, but at least I've one alternative now. – 3rdSenna Oct 22 '19 at 19:18
  • @equi, I was really thinking about "beforeRouteEnter" wait the Vue instance be ready, but I couldn't find out a way if not chaining chaining promises, which would make the code even more 'spaghetti'. Do you have simple example? – 3rdSenna Oct 22 '19 at 19:18
  • @3rdSenna there is a simple example in this answer that could maybe give you a hint: https://stackoverflow.com/questions/44041751/how-to-properly-use-vue-router-beforerouteenter-or-watch-to-trigger-method-in-si – equi Oct 23 '19 at 09:06
  • `it doesn't look the best practice` - You threw best practice out of the window when you said you are not going to use vuex, Everything else is less than best practices obviously. – Mat J Dec 11 '19 at 12:25
  • @MatJ, I agree with you. The issue is there's plenty of no best practices in the current project, so the idea is to move step by step to make better app. Slowly introduce a better practice, then eventually the best practices. The plane is flying, I have to repair this plane while is up there =) – 3rdSenna Dec 16 '19 at 13:26

2 Answers2

1

The router is used to display content at certain URL locations (eg. mysite.com/#/home or mysite.com/#/cart). It isn't used to pass variables around. For that you want to use the Vuex $store.

From what I understand, you don't need to change the Vue router for displaying the time on the main page; you want to edit components/Home.vue to display the time. I think that is the only file you need to edit.

dsaves
  • 181
  • 8
0

If you want to take the current time in mounted then this won't work, because at this moment both your Vue instance and your router already have been created. However, you can work around this in a few ways:

  • Create the start time outside the component, as a file-level constant; then you can simply wrap your router in a factory function and pass the time value as parameter; note that this way the time value will be a few milliseconds off the actual mount time.
  • Create the time directly inside the router; this way you don't have to pass anything in, but again the time will be a bit off from the mount time.

In general it would be helpful to understand why you want to do this. It seems to be a pretty complicated way of achieving something pretty simple, so with more background we might come up with a better solution.

dr_barto
  • 5,723
  • 3
  • 26
  • 47