Edit in JSFiddle

const Home = { template: '<main-layout><p>home page</p></main-layout>' }
const About = { template: '<main-layout><p>about page</p></main-layout>' }
const NotFound = { template: '<main-layout><p>Page not found</p></main-layout>' }

const routes = {
  '/': Home,
  '/about': About
}

Vue.component('v-link', {
  template: `
    <a
      v-bind:href="href"
      v-bind:class="{ active: isActive }"
      v-on:click="go">
      <slot></slot>
    </a>
  `,
  props: {
    href: {
      type:String,
      required: true 
    }
  },
  computed: {
    isActive () {
      return this.href === this.$root.currentRoute
    }
  },
  methods: {
    go (event) {
      event.preventDefault()
      this.$root.currentRoute = this.href
      window.history.pushState(
        null,
        routes[this.href],
        this.href
      )
    }
  }
})

Vue.component('main-layout', {
  template: `
    <div>
      <v-link href="/">Home</v-link>
      <v-link href="/about">About</v-link>
      <slot></slot>
    </div>
  `
})

new Vue({
  el: '#app',
  data: {
    currentRoute: window.location.pathname
  },
  computed: {
    ViewComponent () {
      return routes[this.currentRoute] || NotFound
    }
  },
  render (h) { return h(this.ViewComponent) }
})

window.addEventListener('popstate', () => {
  app.currentRoute = window.location.pathname
})
<div id="app"></div>
.active {
  color: cornflowerblue;
}

External resources loaded into this fiddle: