Search code examples
vue.jsrouterlink

vuejs table router-link tag a


I want to add a router link to my table, everything is ok until here, but there is a situation like this. I want it to be displayed as a href. Table gets corrupted when I do router tag="a" When I set the router tag="tr", there is no problem, but the user may want to open that page by right-clicking the mouse and open a new window. so I would be happy if you could explain as an example how I can proceed. Thank you from now.

const app = new Vue({
    el: '#app',
    data: {
        userList: [
            {
                id: 1,
                name: "Prem",
                age: 18,
                status: "close",
                gender: "male",
            },
            {
                id: 2,
                name: "Chandu",
                status: "close",
                age: 20,
                gender: "female",
            },
            {
                id: 3,
                name: "Shravya",
                status: "open",
                age: 35,
                gender: "female",
            },
            {
                id: 4,
                name: "Shravya",
                status: "blocked",
                age: 35,
                gender: "female",
            }
        ]
    }
});
table {
    font-family: arial, sans-serif;
    border-collapse: collapse;
    width: 100%;
}

td, th {
    border: 1px solid #dddddd;
    text-align: left;
    padding: 8px;
}

tr:nth-child(even) {
    background-color: #dddddd;
}

.dropdown-submenu {
    position: relative;
}

.dropdown-submenu .dropdown-menu {
    top: 0;
    left: 100%;
    margin-top: -1px;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.js"></script>
<script src="https://unpkg.com/vue-router@2.0.0/dist/vue-router.js"></script>

<div id="app">
<table>
    <thead>
    <tr>
        <th>Name</th>
        <th>Age</th>
        <th>Status</th>
        <th>Gender</th>
    </tr>
    </thead>
    <tbody>
    <router-link
        tag="tr"
        v-for="(user, i) in userList" :key="i"
        :to="{ name: 'UserDetail', params: { id:user.id }}"
        >
            <td>{{ user.name }}</td>
            <td>{{ user.age }}</td>
            <td>{{ user.status }}</td>
            <td>{{ user.gender }}</td>
    </router-link>
    </tbody>
</table>
</div>


Solution

  • What you're trying to do wont work, as a table has a set structure, which doesn't allow for an <a> tag to be a child of <tbody>.

    What you instead can do is use position: absolute to "stretch" your link to the entire row, basically placing it above all the other content. Just be aware that doing so will cancel out all other interactive content within your table. Like buttons and inputs.

    I've copied the class/css from Bootstrap, but it should work even if you aren't using it.

    Just remember to place position: relative; on your <tr> so the link will be properly contained within each row.

    new Vue({
      el: '#app',
      data() {
        return {
          userList: [{
              id: 1,
              name: "Prem",
              age: 18,
              status: "close",
              gender: "male",
            },
            {
              id: 2,
              name: "Chandu",
              status: "close",
              age: 20,
              gender: "female",
            },
            {
              id: 3,
              name: "Shravya",
              status: "open",
              age: 35,
              gender: "female",
            }
          ]
        }
      }
    });
    .stretched-link::after {
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      z-index: 1;
      pointer-events: auto;
      content: "";
      background-color: rgba(0, 0, 0, 0);
    }
    
    .position-relative {
      position: relative;
    }
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.14/vue.js"></script>
    
    <div id="app" style="padding: 1rem;">
      <table class="table table-hover table-striped table-bordered">
        <thead>
          <tr>
            <th>Name</th>
            <th>Age</th>
            <th>Status</th>
            <th>Gender</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="(user, i) in userList" class="position-relative">
            <td>{{ user.name }}</td>
            <td>{{ user.age }}</td>
            <td>{{ user.status }}</td>
            <td>
              {{ user.gender }}
              <!-- This can be placed in any of the <td>'s -->
              <a class="stretched-link" :href="`#${user.id}`"></a>
            </td>
          </tr>
        </tbody>
      </table>
    </div>