Displaying V-for Lists in Vue Components

Posted by admin at January 7, 2021

I was building a number of templates for a huge application form, and had to break it down into smaller VueJS components. The process required a list of objects to be sent to a component as prop and listed in the template using v-for. This article covers how to properly list items from an object into a Vue Component.

The setup for the component look like this:


        Vue.component(

            // the name of the vue component
            'pel-list',

            function() {

                // the DOM element ID
                el: "",

                // the props: licences is an array of licence types
                props: [personnel],

                // the vue compnent data store
                data: function() {
                    return 0;
                },

                // the template media box displaying image and bio data of the PEL staff
                template: `
                    <div v-for="(officer, index) in personnel">
                        <div class="media">
                            <div class="media-left">
                                <img class="circle-image" v-bind:src="officer.photo" />
                            </div>
                            <div class="media-center">
                                <div v-html="officer.name" class="bold" />
                                <div v-html="officer.id" />
                                <div v-html="officer.licence_type" />
                            </div>
                        </div>
                    </div>
                `
            }
        );

And data items to be listed in the Vue Component is located in the data store of the main Vue function that is connected to the DOM. This is the parent component that is called when the page is loaded, and in turn provides data elements to be used for the Vue component we just defined above. This is parent Vue component, the Vue app. The data store looks like the following:


        let app = new Vue({

            // the ID of the DOM
            el: "app", 

            data: {
                // the PEL records to be listed in the DOM
                records: [
                    {
                        "id": "98-459-034",
                        "name": "John Doe",
                        "licence_type": "Applicant",
                        "photo": "img/john.doe.jpeg",
                    },
                    {
                        "id": "74-859-8960",
                        "name": "Jane Dane",
                        "licence_type": "Student Pilot",
                        "photo": "img/hane.dane.jpeg",
                    },
                    {
                        "id": "77-654-4934",
                        "name": "Lenny Xavier",
                        "licence_type": "Private Pilot",
                        "photo": "img/lenny.xavier.jpeg",
                    },
                    {
                        "id": "78-654-1434",
                        "name": "Dawn Lane",
                        "licence_type": "Commercial Pilot",
                        "photo": "img/dawn.lane.jpeg",
                    },
                ],
            },
        })

Then we load the Vue component into the DOM by entering the code below somewhere inside the Vue app:


      <div id="app">
            <!--...-->

            <!--load the vue component into the DOM-->
            <!-- and pass the records node from the data store-->
            <lic-list
                v-prop:personnel="records"
            /></lic-list>

            <!--...-->
      </div>

Here, a problem presents itself. Only one item in my list of personnel records was displayed when the Vue Component was loaded up.

Solution:

In order to resolve this, and show every record on the props node, I encased the entire html in the template node inside a single container (‘div’ or ‘span’ etc.)

So instead of the following:


            // whatever is displayed in HTML_RESOURCE node will not be shown
            template: "{{HTML_RESOURCE}}";

            // only the first item in the array 'items' will be shown
            template:`
                <div v-for="(item, index) in items">
                    <!-- the rest of the component-->
                </div>
            `

… we ensure the resource in the template node is displayed by replacing the lines with the following:


            // encase in a DIV tag
            template: "<div>{{HTML_RESOURCE}}</div>";

            // encase in a DIV tag in order to display all the items in the list
            template: `
            <div>
                <div v-for="(item, index) in items">
                    <!-- the rest of the component -->
                </div>
            </div>
            `

In conclusion, to ensure that all the items in a list presented in a Vue component are displayed, simply put everything in a DIV or SPAN.

   0 likes

Suggested Read