2
votes

I am researching whether a vue router is the best approach for the following scenario:

I have a page containing 'n' number of divs. Each of the divs have different content inside them. When a user clicks on a button in the div, I would like the div to open in a separate browser window (including its contents).

  • Can a route name/component be created on the fly to route to? Since I have 'n' number of divs, that are created dynamically, I cannot hard-code name/components for each one

    <router-link :to="{ name: 'fooRoute'}" target="_blank"> Link Text </router-link>

  • I want to avoid the same component instance being used (via route with params) since I may want multiple divs to be open at the same time (each one in their own browser window)

2

2 Answers

2
votes

If the link is opening in a separate window, it makes no sense to use a <router-link> component as the application will load from scratch in any case. You can use an anchor element instead and generate the href property dynamically for each div.

To answer your questions:

  1. A route name cannot be created dynamically since all routes must be defined at the beginning, when the app (along with router) is being initialized. That said, you can have a dynamic route and then dynamically generate different paths that will be matched by that route.

  2. There is no way for the same component instance to be reused if it's running in a separate browser window/tab.

0
votes

It is possible to create dynamic router name.

profileList.vue

<template>
  <main>
    <b-container>
      <b-card
        v-for="username in ['a', 'b']"
        :key="username"
      >
        <b-link :to="{ name: profileType + 'Profile', params: { [profileType + 'name']: username }}">Details</b-link>
    </b-container>
  </main>
</template>

<script>
export default {
  name: 'profileList',

  data () {
    return {
      profileType: ''
    }
  },

  watch: {
    // Call again the method if the route changes.
    '$route': function () {
      this.whatPageLoaded()
    }
  },

  created () {
    this.whatPageLoaded()
  },

  methods: {
    whatPageLoaded () {
      this.profileType = this.$route.path // /user or /place
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style>
</style>

b-container, b-card, b-link are taken from bootstrap-vue, so you can freely change it.

router.js

const router = new Router({
  mode: 'hash',
  base: process.env.BASE_URL,
  linkExactActiveClass: 'active',
  routes: [
    // USERS
    {
      path: '/user/:username',
      name: userProfile,
      component: userProfile
    },
    {
      path: '/user',
      name: 'userList',
      component: profileList
    },

    // PLACES
    {
      path: '/place/:placename',
      name: placeProfile,
      component: placeProfile
    },
    {
      path: '/place',
      name: 'placeList',
      component: ProfileList
    }
  ]
})