[Vuejs]-How do I target the second instance of a nuxt component within a v-for loop?

2๐Ÿ‘

โœ…

How do I target the second instance of a nuxt component within a v-for
loop?

i will tell you exactly how to do this

index.vue

<div 
    v-for="(block,index) in page.fields.blocks" 
    :key="block.id">

    <Block 
        v-if="block.fields.style === 'Block'" 
        :index="index"/>
</div>

i will assume this is the information present in page.field.blocks

page :  {
    fields : {
        blocks : [
            {id:"a1", name:"mars",    fields : {style : "Block"}}, //index 0
            {id:"a2", name:"jupiter", fields : {style : "Block"}}, //index 1
            {id:"a3", name:"saturn",  fields : {style : "Block"}}, //index 2
            {id:"a4", name:"uranus",  fields : {style : "Block"}}, //index 3
            {id:"a5", name:"neptune", fields : {style : "Block"}}  //index 4
        ]
   }
}

the index object in v-for="(block,index) will contain the order of elements in the array page.field.blocks

  • For your usecase, we need to make use of this index object
  • index object needs to be passed to child component i.e Block.vue :index="index"
  • This index object is received in Block.vue using props

Block.vue

<template>
  <div>
      <div>block.vue</div> 
      <div :class="index == 1 ? 'left' : 'right'">{{index}}</div>
  </div>
</template>

<script>
export default {
  props:["index"]
}
</script>

Your goal is to check specifically for second element. check if index == 1 and assign the appropriate class :class="index == 1 ? 'left' : 'right'"

Update:

i seemed to have missed a simple logic as Highlighted by @Morty Choi .
all below code changes should be done in index.vue

create a computed property to filter the objects with style === 'Block' before hand

computed:{
      filterBlocks(){
        return this.page.fields.blocks.filter((data) => data.fields.style === 'Block');
      }
}

and then use the computed property v-for in index.vue

<div 
    v-for="(block,index) in filterBlocks" 
    :key="block.id">
๐Ÿ‘คdivine

2๐Ÿ‘

I think this can be solved by using css.

div > .Block:nth-child(2) {
    // style definition
}

Another way would be bind the class in the outer loop instead.

filteredPageFieldsBlocks = page.fields.blocks.filter(b => block.fields.style === 'Block')

<template>
  <div>
    <div v-for="(block, index) in filteredPageFieldsBlocks">
      <Block :class="index === 1 ? 'left' : 'right'"/>
    </div>
  </div>
</template>
๐Ÿ‘คMorty Choi

Leave a comment