user11606914
user11606914

Reputation:

Rendering lists using v-for in Vuejs?

I am trying to render a list of names using v-for. I have an array of names and I am able to create the template and render the names in the div. What I want to do is if I add any new object in my data, how can I render that part onwards of the data in a new template. So for example, everything until name 'michael' is rendered in one div, but if I add a new name to the data, from that point onwards the names should be rendered inside another template. Here is a CodePen showing my problem

new Vue({
  el: '#app',
  data() {
    return {
      myArray: [{
          name: 'Sam',
          value: 'sam'
        },
        {
          name: 'Gary',
          value: 'gary'
        },
        {
          name: 'Smith',
          value: 'smith'
        },
        {
          name: 'Sunny',
          value: 'sunny'
        },
        {
          name: 'Michael',
          value: 'michael'
        }
      ]
    }
  }
})
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <v-app id="inspire" class="ml-4">
    <template>
      <div v-for="person in myArray" key="person.name">
        {{person.name}}
      </div>
    </template>
    <template>
      //New names should be rendered here from the new values added to the data?
    </template>
  </v-app>
</div>

Any help will be appreciated. I hope I have explained my need. If not let me know.

Upvotes: 0

Views: 280

Answers (2)

Mamadou Hady Barry
Mamadou Hady Barry

Reputation: 629

You can do somethings like this

<template>
  ...
  <v-app id="inspire" class="ml-4">
    <template>
       <!-- Names -->
      <div v-for="person in myArray1" key="person.name">
        {{person.name}}
      </div>
    </template>
    <template>
      <!-- New names -->
      <div v-for="person in myArray2" key="person.name">
        {{person.name}}
      </div>
    </template>
    <v-btn @click="addNewPerson">
      Add
    </v-btn>
  </v-app>
  ...
</template>
<script>
export default {
  ...
  data() {
    return {
      myArray: [{
          name: 'Sam',
          value: 'sam'
        },
        {
          name: 'Gary',
          value: 'gary'
        },
        {
          name: 'Smith',
          value: 'smith'
        },
        {
          name: 'Sunny',
          value: 'sunny'
        },
        {
          name: 'Michael',
          value: 'michael'
        }
      ]
    }
  },
  computed: {
    myArray1() {
      return this.myArray.filter(it => it.recent !== true)
    },
     myArray2() {
      return this.myArray.filter(it => it.recent === true)
    },
  },
  methods: {
    addNewPerson() {
      this.myArray.push({
        name: 'Michael 1',
        value: 'michael 2',
        recent: true // add this
      })
    }
  }
  ...
}
</script>

Upvotes: 0

Arc
Arc

Reputation: 1078

To accomplish what you want, you will either need to use a computed value that returns newly added values by checking if they are in a position that exceeds the original link (or any other method really), so if you first load the component and store that the existing array has 5 elements, you can have a computed that returns the first 5 elements and put that into the first div, then another computed that returns elements 6+ into the second div. Otherwise, you will need to use two separate arrays.

Keep in mind I'm using this.$data here in the example, but the data and the values should be in the store, so it'd be this.$store.state.myArray instead.

<template>
    <div>
        <div v-for="(element, index) of getExisting" :key="index">{{element.name}}</div>
        <div v-for="(element, index) of getNew" :key="index">{{element.name}}</div>
    </div>
</template>

<script>
export default {
    data: () => ({
        created () {
            this.existing = this.myArray.length
        },
        myArray: [
            { name: 'John' },
            { name: 'James' }
        ],
        existing: null
    }),
    computed: {
        getExisting () {
            return this.$data.myArray.slice(0, this.existing)
        },
        getNew () {
            return this.$data.myArray.slice(this.existing, myArray.length)
        }
    }
}
</script>

Upvotes: 0

Related Questions