VueJS: Incorporating a Computed Property within a v-for Loop

Is there a way to utilize computed properties in lists while working with VueJS v2.0.2?

Check out the HTML snippet below:

<div id="el">
    <p v-for="item in items">
        <span>{{fullName}}</span>
    </p>
</div>

And here's the corresponding Vue code:

var items = [
    { id:1, firstname:'John', lastname: 'Doe' },
    { id:2, firstname:'Martin', lastname: 'Bust' }
];

var vm = new Vue({
    el: '#el',
    data: { items: items },
    computed: {
        fullName: function(item) {
            return item.firstname + ' ' + item.lastname;
        },
    },
});

Answer №1

Instead of creating a computed property for each iteration, consider turning each items into its own component with its own fullName computed property.

If you prefer not to create a separate user component, you can utilize a method instead. Move the logic from the computed property to methods, allowing you to call it like this:

{{ fullName(user) }}

Additionally, if you need to pass arguments to a computed property, it may be more appropriate to use a method.

Answer №2

One important point to note is that the items variable is an array containing all items, while the computed property holds a single fullName, which cannot represent all the fullNames in the items array. To address this issue, you can try the following approach:

var vm = new Vue({
    el: '#el',
    data: { items: items },
    computed: {
        // corrections start
        fullNames: function() {
            return this.items.map(function(item) {
                return item.firstname + ' ' + item.lastname;
            });
        }
        // corrections end
    }
});

Then in the view:

<div id="el">
    <p v-for="(item, index) in items">
        <span>{{fullNames[index]}}</span>
    </p>
</div>

While Bill's method does work, using computed properties provides a more elegant solution than using methods within iterations - especially as the application grows in complexity. Additionally, utilizing computed properties can result in better performance compared to using method in certain situations: http://vuejs.org/guide/computed.html#Computed-Caching-vs-Methods

Answer №3

I found PanJunjie潘俊杰's approach to be quite effective. By looping through this.items only once during component creation and then caching the result, it really tackles the core of the issue. This is one of the major advantages of using a computed property over a method.

computed: {
    // corrections start
    fullNames: function() {
        return this.items.map(function(item) {
            return item.firstname + ' ' + item.lastname;
        });
    }
    // corrections end
}

.

<p v-for="(item, index) in items">
    <span>{{fullNames[index]}}</span>
</p>

The only drawback I see is that, in the HTML markup, fullNames is accessed by the list index. This could be improved by utilizing .reduce() instead of .map() in the computed property to create an Object with a key for each item.id in this.items.

Take this scenario for example:

computed: {
    fullNames() {
        return this.items.reduce((acc, item) => {
            acc[item.id] = `${item.firstname} ${item.lastname}`;
            return acc;
        }, {});
    },
},

.

<p v-for="item in items" :key="`person-${item.id}`">
    <span>{{ fullNames[item.id] }}</span>
</p>

Please note: the above illustration assumes that item.id is unique, as typically seen in database outputs.

Answer №4

Perhaps consider incorporating another v-for loop that iterates through a list with only one item:

<div id="el">
    <p v-for="item in items">
        <template v-for="fullName in [item.firstName + ' ' + item.lastName]">
            <span>{{fullName}}</span>
        </template>
    </p>
</div>

It may not be the most elegant solution, but it achieves your desired outcome: an object encapsulating that span with a fullName property containing the specified value.

This feature serves a purpose beyond aesthetics, as we might need to reference that value in multiple instances, for example:

<span v-if="...">I am {{fullName}}</span>
<span v-else-if="...">You are {{fullName}}</span>
<span v-else>Who is {{fullName}}?</span>

In my scenario, I was generating dates within v-for loops (yes, yet another calendar), like so:

<v-row v-for="r in 5">
    <v-col v-for="c in 7">
        <template v-for="day in [new Date(start.getTime() + 24*60*60*1000*((c-1) + 7*(r-1)))]">
            <span>
                Rendering of a day such as {{day.getYear()}} and
                {{day.getMonth()}} etc.
            </span>
        </template>
    </v-col>
</v-row>

(I omitted the :key="whatever" settings for brevity)

The ideal approach would be to create a separate component for this logic, but introducing a new component for every small task like this risks cluttering the namespace unnecessarily.

Perhaps a

v-let="day as new Date(...)"
directive could prove useful in such cases.

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

What are the different scenarios in AngularJS where $scope is utilized versus when var is utilized?

Which is more efficient in AngularJS: using var or $scope. for variables inside functions? I am asking this question because I recently came across information about $watch, $digest, and $apply in AngularJS. While I may not have fully grasped the concept ...

Pug Template Not Displaying Emojis or Special Characters in Sendgrid Email Subject Line

There seems to be an issue with rendering emojis or special characters in the subject header of the pug file, although they work perfectly in the body. I have compiled both the body and subject header separately using pug. const compileHtmlFunction = pug.c ...

Utilizing AngularJS with Restheart API to streamline MongoDB integration and efficiently parse JSON data outputs

Utilizing RestHeart to expose CRUD functionality from MongoBD. Attempting to call the Rest API from AngularJS and retrieve the JSON output like the one displayed below. My focus is specifically on extracting the name, age, & city fields that are stored in ...

Having trouble accessing Kotlin JS from JavaScript

I'm currently experiencing an issue where I am unable to call any Kotlin JS function and receiving an error stating that 'something' is not defined. Initially, I attempted compiling the project with Gradle but found success after following ...

The React.js component search test encounters errors in locating components

I have been working on a React app that utilizes Redux and React-router. I am currently writing tests using React TestUtils, and I encountered an issue with the following test results: The first expect statement is successful: expect(nav).to.have.length(1) ...

Serve as a proxy for several hosts with identical URL structures

I've been utilizing the http-proxy-middleware to handle my API calls. Is there a way to proxy multiple target hosts? I've searched for solutions in the issues but still haven't found a clear answer. https://github.com/chimurai/http-proxy-m ...

Having trouble accessing a DOM element within a Vue component while using vanilla JavaScript

I am attempting to dynamically update data from a Vue component using jQuery in a Webpack project. Below is the code snippet: <template> <div id="container"> <slot>show string!!</slot> <div id="s_container"&g ...

Updating nested objects: A guide on how to effectively modify complex

I am trying to utilize the $push method in order to insert an object into a nested array, but I am struggling to dynamically access the correct object inside the array. Allow me to provide a clearer explanation by showcasing the code. Here is my Schema: ...

Utilizing db.system.js Function within the $where Clause

Here is an illustration of a basic function that I have saved: db.system.js.save({_id: "sum", value: function (x, y) { return x + y; }}); However, when attempting to call it within the $where clause, a Reference not exist error occurs. <?php $collec ...

I could really use some assistance with this project for my friend

Whenever I click on the image, it only displays two out of the three possible alerts. How can I make it show all three? Here's my code: <!DOCTYPE html> <html> <head> </head> <body> <img src="http://www.build ...

Obtain an assortment of Vuetify lists

Is there a way to get the selected item or index from a vuetify list? I've tried applying v-model to the <v-list> tag, but it doesn't seem to work and I can't find any working examples. My idea is to have a list of images or file nam ...

What is the best way to connect an HTML file to a controller in Angular.js?

When developing an app module using the MEAN stack with MVC, I created a folder named AppModules. Inside AppModules, there is a folder called search, which contains three subfolders: models, views, and controllers. I've written an HTML file in the vie ...

The error message "Jest Nuxt Cannot read property 'child' of undefined" indicates a problem where a property

Having trouble running Jest tests for Nuxt/Vue components. I've connected everything needed for testing, fixed issues with jsdom and babel, but can't figure out the Vue component problem. The error message is: TypeError: Cannot read property ...

Discover the process of accessing and setting values in Angular 8 to easily retrieve and manipulate data from any page!

Greetings! I am currently utilizing Angular 8 and I have a query regarding how to access the set value in any given page. Here is a snippet of my code: class.ts export class testClass { get test():string{ return this.sexe; } ...

Bidirectional updates in AngularJS with CSS styling

On the backend, certain HTML elements store their position and size persistently and retrieve them when the page loads. These elements can be dragged and resized by users, with any updates needing to be saved on the backend for consistency across sessions. ...

Ways to substitute the v-model pattern with react hooks

Transitioning my application from Vue to React. In Vue 2, using v-model on a component was similar to passing a value prop and emitting an input event. To change the prop or event names to something different in Vue, a model option needed to be added to t ...

Evaluate One Input Value to Determine Another Input Value

Hey there, I've made an update to the fiddle but let me clarify what I'm trying to achieve. My goal is not to implement form validation as I already have that covered with the HTML5 "required" attribute. What I'm aiming for is to customize t ...

Is it possible for jQuery UI Tabs to load entire new HTML pages?

In my index.html file, I have set up 3 different tabs. Using the jQuery UI function tabs(), I am attempting to load an HTML page via Ajax. Each HTML page includes the jQuery library and contains the following code: <link type="text/css" href="css/redmo ...

Submitting a form using jquery

I am working on a project that involves using a jquery fancyzoom box. Within this box, there is a contact form that should send an email upon submission. However, I am encountering issues with calling the form submit function due to the fancyzoom feature. ...

Kurento's WebRTC feature is currently experiencing difficulties with recording functionality

Currently, I am attempting to capture video using the Kurento Media Server with nodejs. Following the hello-world example provided here, I connected a recorderEndpoint to the webrtcEndpoint and successfully got everything up and running. However, on the se ...