简体   繁体   中英

Vue: change component prop from parent component on click, radio buttons

I have two components: Toggle.vue which is basically a button and a TestToggle.vue which has two Toggle components inside. I want to be able for the toggle elements to serve as a radio button of sorts: only one can be selected at a time.

It is supposed to look like this (only one button is active at a time):

在此处输入图像描述

However I can select two buttons:

在此处输入图像描述

which isn't right.

Toggle.vue :

<template>
    <div class="rounded-full m-5 w-40 
                flex justify-center 
                p-2 cursor-pointer"
         :class = "status ? 'bg-green-700 
                             hover:bg-green-600' :
                            'bg-red-700 
                             hover:bg-red-600'"
         v-on:click="status = true">
        <p>{{text}} : {{status}}</p>
    </div>
</template>

<script>
    export default {
        props:  {
            text:  {
                type: String,
                default: ''
            },
            status: {
                type: Boolean,
                default: false
            }
        }
    }
</script>

TestToggle.vue :

<template>
    <div>
        <p>Active: {{activeTab}}</p>
        <Toggle v-on:click = "activeTab = 1"
                text="Toggle 1 "/>
        <Toggle v-on:click = "activeTab = 2"
                text = "Toggle 2"/>
    </div>
</template>

<script>
     import Toggle from '../test/Toggle.vue';

    export default {
        components: {Toggle},

         data: function () {
             return {
                activeTab: 1
            }
        },
        methods: {

        }
    }
</script>

I think I need to set status = false from TestToggle to Toggle when another Toggle is clicked? How do I do that? Or should I do it completely differently?

Another problem is that I can't update activeTab data property inside TestToggle component: it always shows 1 ...

EDIT :

I tried this code (as suggested in the answer), but it just doesn't work: the buttons don't react to clicks:

Toggle.vue :

<template>
    <div class="rounded-full m-5 w-40
                flex justify-center
                p-2 cursor-pointer"
         :class = "status ? 'bg-green-700 hover:bg-green-600' :
                            'bg-red-700 hover:bg-red-600'">
    <p>{{text}} : {{status}}</p>
    </div>
</template>


<script>
    export default {
        props:  {
            text:  {
                type: String,
                default: ''
            },
            status: {
                type: Boolean,
                default: false
            }
        }
    }
</script>

TestToggle.vue :

<template>
    <div>
        <p>Active: {{activeTab}}</p>
        <Toggle v-on:click = "activeTab = 1"
                text="Toggle 1 "
                v-bind:status="activeTab === 1"/>
        <Toggle v-on:click = "activeTab = 2"
                text = "Toggle 2"
                v-bind:status="activeTab === 2"/>
    </div>
</template>


<script>
     import Toggle from '.././toggle-so/Toggle.vue';

    export default {
        components: {Toggle},

        data: function () {
            return {
                activeTab: 1
            }
        },
        methods: {

        }
    }
</script>

In Toggle.vue , status is declared as a prop, so you should not modify it:

<template>
    <div class="rounded-full m-5 w-40 
                flex justify-center 
                p-2 cursor-pointer"
         :class = "status ? 'bg-green-700 
                             hover:bg-green-600' :
                            'bg-red-700 
                             hover:bg-red-600'"
        <p>{{text}} : {{status}}</p>
    </div>
</template>

but pass it to Toggle.vue from TestToggle.vue :

<template>
    <div>
        <p>Active: {{activeTab}}</p>
        <Toggle v-on:click.native = "activeTab = 1"
                text="Toggle 1 "
                v-bind:status="activeTab === 1"/>
        <Toggle v-on:click.native = "activeTab = 2"
                text = "Toggle 2"
                v-bind:status="activeTab === 2"/>
    </div>
</template>

If you change the status in Toggle.vue , you make it independent of every other Toggle, but if you want a radio button behavior, each status is dependent of other statuses. That's why you need to manage if from the parent component.

You also need to use the native event modifier to listen to the div click of the children.

I made a simple JSFiddle to show a working example .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM