1

I'm new to Vue.js and I guess I'm missing some point on the way it works. I'm trying to build the following:

  1. Fetch a list of plans from a REST API - done
  2. Display the plans as buttons with v-for - done
  3. Allow the user to click in one of those buttons / plans to mark it as chosen

My code to print the buttons inside bootstrap columns:

<b-col lg="4" class="plan" v-for="plan in plans" :key="plan.id">
<b-button block variant="secondary" v-on:click="pickPlan(plan.id)">
    <p class="price">€ {{plan.price}}</p>
    <p class="plan">{{plan.name}}</p>
</b-button>

My problem: how can I make it so if the user clicks on some button it changes the property variant="primary" in that button and sets all others to variant="secondary"?

Thank you.

2 Answers 2

2

You can bind the variant attribute to any data available on your Vue component or use it together with inline JavaScript, like this:

<b-col lg="4" class="plan" v-for="plan in plans" :key="plan.id">
    <b-button block :variant="plan.id === chosenPlan.id ? 'primary' : 'secondary'" v-on:click="pickPlan(plan.id)">
        <p class="price">€ {{plan.price}}</p>
        <p class="plan">{{plan.name}}</p>
    </b-button>
</b-col>

And then make sure to set chosenPlan in your pickPlan(planId) method.

Sign up to request clarification or add additional context in comments.

2 Comments

Many thanks you solution is easy to implement and doesn't envolve chafing the plans array. I ended up creating a method to hide the if logic from the template code as described in here stackoverflow.com/questions/40522634/…
So my final template code was <b-button class="plan" block :variant="planButtonVariant(plan)" v-on:click="pickPlan(plan)"> and the script methods: { planButtonVariant: function (plan) { return plan.id === this.chosenPlan.id ? "primary" : "outline-secondary" },
1

One way to solve it is to extend plan object and add to it extra called variant or picked and use this property to bind to variant attribute in template

<template>
  <div>
    <b-col lg="4" class="plan" v-for="plan in plans" :key="plan.id">
      <b-button block v-bind:variant="picked ? 'primary' : 'secondary'" v-on:click="pickPlan(id)">
          <p class="price">€ {{plan.price}}</p>
          <p class="plan">{{plan.name}}</p>
      </b-button>
    </b-col>
  </div>
</template>

<script>
export default {
  data() {
    return {
      plans: [
        { id: 1, name: 'Plan name 1', price: 12.00, picked: false },
        { id: 2, name: 'Plan name 2', price: 24.00, picked: true },
      ]
    }
  },
  methods: {
    pickPlan(id) {
      this.plans = this.plans.map(p => {
        if(p.id === id) {
          return { ...p, picked: true }
        }
        return { ...p, picked: false }
      })
    }
  }
}
</script>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.