Vue Router and relative child links

https://stackoverflow.com/questions/63930194/vuetify-tabs-as-nested-dynamic-routes-erroring-on-parent-prop

by MichalLevy

HTML

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<head>
  <link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
  <link href="https://cdn.jsdelivr.net/npm/@mdi/[email protected]/css/materialdesignicons.min.css" rel="stylesheet">
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" rel="stylesheet">
</head>
<div id="app">
  <v-app>
    <v-main>
      <v-container>
        <router-link to="/parent/123/">Go To Parent</router-link>
        <router-view></router-view>
      </v-container>
    </v-main>
  </v-app>
</div>

JavaScript

var mockObj = {
  name: "Steve"
}

const Parent = {
  template: '<div><h1>Hello from parent <em>"{{obj}}"</em> (id: {{ $route.params.id }}) (someInternalValue: {{ someInternalValue }})</h1>' +
    '<div>Relative</div>' +
    '<v-tabs>' +
    '<v-tab to="child1">child1</v-tab>' +
    '<v-tab to="child2">child2</v-tab>' +
    '<v-tab to="child3">child3</v-tab>' +
    '</v-tabs>' +
    '<div>Full path</div>' +
    '<v-tabs>' +
    '<v-tab :to="{ path: `/parent/${$route.params.id}/child1` }">child1</v-tab>' +
    '<v-tab :to="{ path: `/parent/${$route.params.id}/child2` }">child2</v-tab>' +
    '<v-tab :to="{ path: `/parent/${$route.params.id}/child3` }">child3</v-tab>' +
    '</v-tabs>' +
    '<div>With name</div>' +
    '<v-tabs>' +
    '<v-tab :to="{ name:`child1` }">child1</v-tab>' +
    '<v-tab :to="{ name:`child2` }">child2</v-tab>' +
    '<v-tab :to="{ name:`child3` }">child3</v-tab>' +
    '</v-tabs>' +
    '<router-view></router-view>' +
    '</div>',
  props: {
    obj: {
      type: Object,
      required: true
    }
  },
  data() {
    return {
      someInternalValue: 0
    }    
  },
  created() {
    this.someInternalValue = Math.floor(Math.random() * Math.floor(100))
  },
  beforeRouteUpdate(to, from, next) {
    console.log("beforeRouteUpdate parent component")
    console.log(`From: ${JSON.stringify(from.params)}`)
    console.log(`To: ${JSON.stringify(to.params)}`)
    
    // HackyHack
    if(from.params.obj)
      to.params.obj = from.params.obj
      
    next()
  }
};

const Child1 = {
  template: '<h3>Child1</h3>'
};
const Child2 = {
  template: '<h3>Child2</h3>'
};
const Child3 = {
  template: '<h3>Child3</h3>'
};

const routes = [{
  path: '/parent/:id',
  component: Parent,
  props: true,
  beforeEnter: function(routeTo, routeFrom, next) {
    routeTo.params.obj = mockObj;
    console.log("beforeEnter parent route")
    next();
  },
  children: [{
      path: 'child1',
      name: 'child1',
      component: Child1
    },
    {
      path:...