Lance Pollard
Lance Pollard

Reputation: 79258

How to pass an item from v-for to a function in Vue.js?

I would like to do something like this:

<div v-for="section in sections">
  <h1 v-if="section.level === 1">
    ...
  </h1>
  <h2 v-else-if="section.level === 2">
    ...
  </h2>
  <h3 v-else-if="section.level === 3">
    ...
  </h3>
  <h4 v-else-if="section.level === 4">
    ...
  </h4>
  <h5 v-else-if="section.level === 5">
    ...
  </h5>
  <h6 v-else-if="section.level === 6">
    ...
  </h6>
</div>

But more cleanly in my case (this is just a made up example, the real-world example is too hard to directly copy for this post), I want to abstract those calls into functions so there's no real logic in the template:

<div v-for="section in sections">
  <h1 v-if="isLevel(section, 1)">
    ...
  </h1>
  <h2 v-else-if="isLevel(section, 2)">
    ...
  </h2>
  <h3 v-else-if="isLevel(section, 3)">
    ...
  </h3>
  <h4 v-else-if="isLevel(section, 4)">
    ...
  </h4>
  <h5 v-else-if="isLevel(section, 5)">
    ...
  </h5>
  <h6 v-else-if="isLevel(section, 6)">
    ...
  </h6>
</div>

How can I do this in Vue.js? What is the desired way?

I can think of one way, which would be to create custom components for each hx (pseudocode):

<div v-for="section in sections">
  <MyHeader section="{{ section }}" />
</div>

new Vue({
  template: the MyHeader one,
  props: {
    section: true
  },
  methods: {
    isLevel1: function() {
      return this.$data.section.level === 1
    },
    isLevel2: function() {
      return this.$data.section.level === 2
    },
    ...
  }
})

<template name="MyHeader">
  <h1 v-if="isLevel1">
    ...
  </h1>
  <h2 v-else-if="isLevel2">
    ...
  </h2>
  <h3 v-else-if="isLevel3">
    ...
  </h3>
  <h4 v-else-if="isLevel4">
    ...
  </h4>
  <h5 v-else-if="isLevel5">
    ...
  </h5>
  <h6 v-else-if="isLevel6">
    ...
  </h6>
</template>

But requiring to make them into custom classes is kind of a burden. I also don't want to use the render function directly. I'm trying to see the idiomatic way of doing this in Vue.js, and what Vue is capable of. I am new to Vue so sorry if I am messing things up.

Upvotes: 0

Views: 755

Answers (1)

Boussadjra Brahim
Boussadjra Brahim

Reputation: 1

I think you could do it using component with is prop :

<div v-for="section in sections">
  <component :is="'h'+section.level" ></component>
</div>

Upvotes: 1

Related Questions