Warrio
Warrio

Reputation: 1913

How to use multiple references to the same vueJs component?

I have a php page person.php that includes 2 vueJs components: person-details.vue and phones.vue. Each of these components include the same third component notify-delete. This notify-delete component includes a bootstrap modal dialog to confirm a deletion action of the parent component (person or phone). I use props to set a message in the modal confirmation dialog and $refs to show it.

Problem: When this props is set the msg props from the component person and the dialog is shown, the message is correctly set. However when I set from the phones component, the dialog shows the message set by person. as if person is constantly overriding the value of the msg props.

here is a sample of the code:

person.php:

<person-details details="<?= json_encode($person) ?>"></person-details>
<phones details="<?= json_encode($phones) ?>"></phones>

Person-details.vue:

<template>
    <notify-delete ref="modalDeletePerson" :entity="'person'" :msg="deleteMsg" @confirmed="deleteMe"></notify-delete>
    <button type="button" @click="confirmDelete">Delete this person</button>
</template>

<script>
    export default {
        data () {
            return {
                deleteMsg: ''
            }
        },
        methods: {
            confirmDelete() {
                this.deleteMsg = 'Are you sure you want to delete this person?'
                this.$refs.modalDeletePerson.show()
            },
            deleteMe() {
                // delete person
            }
        }
    }
</script>
</template>

Phones.vue:

<template>
    <notify-delete ref="modalDeletePhone" :entity="'phone'" :msg="deleteMsg" @confirmed="deleteMe($event)"></notify-delete>

    <button type="button" @click="confirmDelete">Delete this phone</button>
</template>

<script>
    export default {
        data () {
            return {
                deleteMsg: ''
            }
        },
        methods: {
            confirmDelete() {
                this.deleteMsg = 'Are you sure you want to delete this phone?'
                this.$refs.modalDeletePhone.show()
            },
            deleteMe() {
                // delete phone
            }
        }
    }
</script>

Notify-delete.vue:

<template>
    <div id="modalDelete" class="modal fade" tabindex="-1" role="dialog">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <div class="modal-body">
                    {{msg}}
                </div>
                <div class="modal-footer">
                    <button type="submit" data-dismiss="modal" @click="confirm">Delete</button>
                    <button type="button" data-dismiss="modal">Cancel</button>
                </div>
            </div>
        </div>
    </div>
</template>
<script>
    export default {
        props: ['entity', 'msg'],

        methods: {
            show() {
                $('#modalDelete').modal('show')
            },

            confirm() {
                this.$emit('confirmed')
            }
        }
    }
</script>

Any idea how I can have two distinguish instances of the same component?

Upvotes: 1

Views: 8829

Answers (1)

Bert
Bert

Reputation: 82499

The problem is here

show() {
    $('#modalDelete').modal('show')
}

You are rendering two modals with the same id, then using jQuery to show them. Specifically, $('#modalDelete') will contain two elements. I expect the modal method just picks the first one and shows it.

Try

<div ref="modal" class="modal fade" tabindex="-1" role="dialog">

and

show() {
    $(this.$refs.modal).modal('show')
}

This should give each instance of the Notify-delete.vue component it's own reference.

Upvotes: 3

Related Questions