'input type radio with vue 3

This code is almost working. I have 3 input fields when clicked they toggle another div below them and it works. My problem is that i want to show only one div atm, so when one is clicked another two are supposed to hide. Please take a look at code.

<template>
<div class="payment">
    <div class="option">
        <div class="pouzecem" @click="changePouzecem">
            <input type="radio" :checked="showPouzecem">
            <p>Pouzecem(provizija + 13kn)</p>
        </div>
        <div class="desc" v-show="showPouzecem">
            <p>Izborom opcije plaćanje pouzećem</p>
        </div>
    </div>
    <div class="option">
        <div class="card" @click="changeCard">
            <div>
                <input type="radio" :checked="showCard">
                <p>Kreditna kartica</p>
            </div>
            <img src="../assets/icons/cards.png">
        </div>
        <div class="desc" v-show="showCard">
            <p>Kreditna kartica</p>
            <div class="card-info">
                <input type="text">
            </div>
        </div>
    </div>
    <div class="option">
        <div class="paypal" @click="changePayPal">
            <div>
                <input type="radio" :checked="showPayPal">
                <p>PayPal</p>
            </div>
            <img src="../assets/icons/paypal.png" >
        </div>
        <div class="desc" v-show="showPayPal">
            <button class="paypal-btn"><icon name="paypal"></icon></button>
            <p>The safer, easier way to pay</p>
        </div>
    </div>
</div>
</template>

<script>
import Icon from './icons/Icon.vue'

export default {
    components: { Icon },
    data() {
        return {
            showPouzecem: true,
            showCard: false,
            showPayPal: false
        }
    },
    methods: {
        changePouzecem() {
            this.showPouzecem = !this.showPouzecem
            if(this.showPouzecem === true) {
                this.showCard === false
                this.showPayPal === false
            }
        },
        changeCard() {
            this.showCard = !this.showCard
            if(this.showPouzecem === true) {
                this.showPouzecem === false
                this.showPayPal === false
            }
        },
        changePayPal() {
            this.showPayPal = !this.showPayPal
            if(this.showPayPal === true) {
                this.showPouzecem === false
                this.showCard === false
            }
        }
    }
}
</script>

Looks like v-show is not updating after function is called. What is the way to solve this?



Solution 1:[1]

Natively, input[type="radio"] work by sharing the same name attribute and they automatically switch to unchecked when another input pointing at the same name is selected/checked.

In Vue, you do that by using the same v-model.

You don't need any of the change methods. You can rely on the current value of the v-model (shared between the radios) (selectedOption in the following example):

const {
  createApp
} = Vue;
createApp({
  data: () => ({
    selectedOption: 'pouzecem'
  })
}).mount('#app')
label {
  cursor: pointer;
}
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<div id="app">
  <div class="payment">
    <div class="option">
      <div class="pouzecem">
        <p>
          <label>
            <input type="radio" v-model="selectedOption" value="pouzecem">
            <span>Pouzecem(provizija + 13kn)</span>
          </label>
      </p>
      <div class="desc" v-show="selectedOption === 'pouzecem'">
        <p>Izborom opcije pla?anje pouze?em</p>
      </div>
    </div>
    <div class="option">
      <div class="card">
        <p>
          <label>
            <input type="radio" v-model="selectedOption" value="card">
            <span>Kreditna kartica</span>
            <!--img src="../assets/icons/cards.png" -->
          </label>
        </p>
      </div>
      <div class="desc" v-show="selectedOption === 'card'">
        <p>Kreditna kartica</p>
        <div class="card-info">
          <input type="text">
        </div>
      </div>
    </div>
    <div class="option">
      <div class="paypal">
        <p>
          <label>
            <input type="radio" v-model="selectedOption" value="paypal">
            <span>PayPal</span>
            <!-- img src="../assets/icons/paypal.png" -->
          </label>
        </p>
      </div>
      <div class="desc" v-show="selectedOption === 'paypal'">
        <button class="paypal-btn"><icon name="paypal">Icon...</icon></button>
        <p>The safer, easier way to pay</p>
      </div>
    </div>
  </div>
</div>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1