Can I render rows and cells in a table using v-for twice in Vue?

I am eager to utilize Vue in order to display a table with rows, while having the cells as a component.

I have created a functional example showcasing the desired end result along with some code outlining my approach:

HTML

<div id="app">
  <table>
    <thead>
      <tr>
        <th>Row</th>
        <th>ID</th>
        <th>Name</th>
        <th>Age</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="(row, rindex) in people">
        <td>{{ rindex }}</td>
        <cell v-for="(value, vindex, rindex) in row" :value="value" :vindex="vindex" :rindex="rindex"></cell>
      </tr>
    </tbody>
  </table>
  <template id="template-cell">
    <td>{{ value }}</td>
  </template>
</div>

JS

// Register the component
Vue.component('cell', {
  template: '#template-cell',
  name: 'row-value',
  props: ['value', 'vindex', 'rindex']
  // Here I intend to access value, vindex, and rindex
});
// Initialize the application
new Vue({
  el: '#app',
  data: {
    people: [
      {id: 3, name: 'Bob', age: 27},
      {id: 4, name: 'Frank', age: 32},
      {id: 5, name: 'Joe', age: 38}
    ]
  }
});

My rationale for this approach is based on the Vue documentation on v-for which illustrates the following example:

And another for the index:

<div v-for="(value, key, index) in object">
  {{ index }}. {{ key }} : {{ value }}
</div>

Therefore, I anticipate being able to retrieve the row's index in the cell component effortlessly. However, this has not been the case as it results in numerous errors indicating that the values are undefined.

If anyone could offer guidance on this matter, it would be greatly appreciated as I am at a loss on how to tackle this issue. I am keen to understand how to implement this correctly.

(Note: My reason for wanting to render the cells within the component is to observe value changes, refer to this answer to another question I posed here if you're interested)

Answer №1

In order for your cell component to be rendered correctly within a table in HTML, you should wrap it inside a template element. This is because a table expects only td elements inside tr elements. If it encounters cell, it will not display it properly (a similar issue can be seen with Angular here). The template element acts as a content fragment in this scenario, allowing Vue to replace cell with tr after compilation.

  <tr v-for="(row, rindex) in people">
    <td>{{ rindex }}</td>
    <template>
       <cell  v-for="(value, vindex) in row" :value="value" :vindex="vindex" :rindex="rindex" ></cell>
    </template>
  </tr>

Check out the working example here.

Answer №2

It is uncertain whether swapping out index with rindex in the v-for constructor is permissible. If the v-for implementation requires string labels for both key and index, using rindex and vindex may not function as intended.

Another concern emerges from the documentation: Vue List Rendering

When iterating through an object, the order is determined by the key enumeration order of Object.keys(), a sequence that is not guaranteed to be consistent across all JavaScript engines.

As a result, the sequencing of your data may vary unpredictably. It is advisable to avoid using object iterators for cell and explicitly specify the order of display like this:

<tr v-for="(person, index) in people">
    <td>{{ index }}</td>
    <cell :value="index" valueType="index" :rowIndex="index"></cell>
    <cell :value="person.id" valueType="id" :rowIndex="index"></cell>
    <cell :value="person.name" valueType="name" :rowIndex="index"></cell>
</tr>

Adjust your cell component definition as follows:

Vue.component("cell", {
    template: "#template-cell",
    name: "row-value",
    props: ["value", "valueType", "rowIndex"],
    // your component code here...
})

With these modifications, you can now utilize valueType and rowIndex within your cell component.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using jQuery to create clickable URLs within a rollover div

I am looking to have the div appear on a mouse over effect in the following code. Is there a way for me to input a url based on the data that is passed to it? Anchorage: ["Anchorage", "(555)555-5555"], (This represents the data being posted) AtlanticCit ...

Utilize JavaScript to enclose every piece of text within single quotes in a span element

I have a tiny snippet of text: "some sample text" just a little more "additional text" I am trying to figure out how to wrap all the content between quotation marks in a span container, similar to what hilight.js does. I've been struggling to make it ...

How can I ensure that only the relevant form values are submitted in Vue2?

I currently have a form page that serves the purpose of both creating and updating data. The form fields are structured as follows; view image details here content: (...) i18n: (...) image: (...) name: (...) orderIndex: (...) position: (...) I am able t ...

Difficulty encountered while transmitting JSON data from Express to React

Currently, I am diving into learning express and facing an issue with transmitting JSON data from my express server to my react application. When working on my express server, I initiate an API call to the openweathermap API and then send the obtained JSO ...

What is the proper way to mention JavaScript packages when including them as parameters in Angular elements within HTML?

I was looking to enhance the command to be more authoritative. <div (click)="lastCall(999)">click me</div> My attempt to utilize Number.MAX_SAFE_INTEGER resulted in an error from my computer stating that it wasn't recognized. As a result ...

How should we structure our JavaScript code: MVC or self-rendering components?

I'm in the process of developing a highly JS-centric web application. The bulk of the work is being carried out on the client side, with occasional syncing to the server using AJAX and XMPP. This is my first venture into creating something of this ma ...

Error in AngularJS when passing object to modal dialog

I'm facing a challenge with an AngularJS application I'm developing. It involves displaying a list of contacts, each accompanied by a button that triggers a modal containing a form for editing the contact information. The issue arises when attemp ...

Best practices for handling APIs in Vue

After spending hours reading documentation and searching online for the best way to manage API calls in larger projects, I have yet to find a solution that meets my needs. My goal is to create a service or facade for the backend that can be easily integra ...

Accessing the background page of a Chrome extension while it's in operation

I am in the process of developing my first chrome extension that allows youtube.com/tv to run in the background so it can be accessed easily on a phone or tablet. Everything is working fine, except for the fact that if I want to watch the video and not j ...

What is the proper way to access the current value of a computed property from within its own computation method?

Our goal is to activate a query when a string reaches a length of 3 characters or more, and keep it activated once triggered. Leveraging the Vue 2 Composition API, we have implemented a reactive object to manage the status of queries: import { computed, de ...

Retrieve the tweets from the next Twitter user in the Array using blogger.js

I am working on a project that involves a javascript array of Twitter usernames. Using blogger.js, I successfully load the first username along with their last 5 tweets. Now, I am looking to create HTML buttons or links for "previous" and "next" in order ...

The data displayed in the <span> element isn't reflecting the response from the loaded page, despite being visible in Firebug

I have encountered a problem while trying to load a signup.php page into a div on my main page. All the elements (forms, JavaScript, etc.) function correctly in the loaded page, except for one issue - I cannot get the response from the PHP script to displa ...

How to call a function within a component from another component without encountering the "Cannot read property" error

Having trouble calling a function from one component in another by passing the reference of one to the other. I keep getting a "Cannot read property" error. Below is the code snippet Alert Component import { Component, OnInit, Output } from '@angula ...

Ways to retrieve the mapState property within a method

Is there a way to access the count property within the method while working with vuex? Take a look at my code provided below: Screenshot of Code: https://i.stack.imgur.com/xNUHM.png Error Message [Vue warn]: Computed property "count" was assigned to bu ...

Is it possible for me to retrieve data in object using double v-for?

I am attempting to create a dynamic table using the following objects: <tr v-for="product in allPosts" :key="product.id"> <td v-for='(item, i) in checked' :key='`item${i}`'>{{product.item}}</td> </tr> In th ...

Ways to access the HTML content of a component in vue.js

I have a unique html template displayed below CustomTemplate.vue <template> <div class="content custom-page"> <md-card class="page-display"> <md-card-header class="page-header"> <md-card- ...

Does the downloading of images get affected when the CSS file has the disabled attribute?

Is it possible to delay the download of images on a website by setting the stylesheet to 'disabled'? For example: <link id="imagesCSS" rel="stylesheet" type="text/css" href="images.css" disabled> My idea is to enable the link later to tri ...

Saving Data in an Angular Material Table: A How-to Guide

I have a basic angular material table and I am looking for a way to save the data displayed in each row when a button is clicked. Is it possible to save each row of data as an object and push it to an array? If so, how can I achieve this? <div class=& ...

The appearance of an unforeseen * symbol caused a

Having issues with this particular line of code, import * as posenet from '@tensorflow-models/posenet' The error 'Uncaught SyntaxError: Unexpected token *' keeps popping up, I have the latest version of Chrome installed and I've ...

What is the best way to invoke a function with multiple parameters in TypeScript?

I have a function that manipulates a specified query string, along with another version that always uses window.location.search. Here is the code snippet: class MyClass { public changeQuery(query: string; exclude: boolean = true; ...values: string[]): st ...