Vue - несколько родителей используют одного и того же ребенка - PullRequest
0 голосов
/ 27 апреля 2018

Есть ли способ в Vue.js для нескольких родителей использовать одного и того же ребенка?

Я хотел бы, чтобы несколько кнопок удаления запускали один мод с различным содержанием.

Пример

myfile.html:

<table id="app" class="table table-striped table-sm table-responsive-md">
    <thead>
        <tr>
            <th>Title</th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        <tr class="post">
            <td>Test2</td>
            <td>
                <delete-confirm popup-title="Are you sure ?" popup-message="Message 1">
                    Delete
                </delete-confirm>
            </td>
        </tr>
        <tr class="post">
            <td>Test article</td>
            <td>
                <delete-confirm popup-title="Are you sure ?" popup-message="Message 2">
                    Delete
                </delete-confirm>
            </td>
        </tr>
    </tbody>
</table>

app.js:

require('./bootstrap');

window.Vue = require('vue');

Vue.component('delete-confirm', require('./components/DeleteConfirm.vue'));
Vue.component('magnific-popup', require('./components/MagnificPopup.vue'));

const app = new Vue({
    el: '#app'
});

компоненты / DeleteConfirm.vue:

<template>
    <span>
        <button ref="button" @click="showConfirmation($event.target)" class="btn btn-danger">
            <i class="fa fa-trash"></i> <slot></slot>
        </button>

        <magnific-popup v-on:click="click" ref="popup">
            <h2 slot="title">{{ popupTitle }}</h2>
            <p slot="content">{{ popupMessage }}</p>
        </magnific-popup>
    </span>
</template>

<script>
    import $ from 'jquery';

    export default {
        props: ['popupTitle', 'popupMessage'],
        methods: {
            showConfirmation(target) {
                this.$refs.popup.open(target);
            },
            click(type) {
                this.$refs.popup.close();

                if (type === 'confirm') {
                    $.ajax({
                        url: '404me',
                        type: 'DELETE',
                    }).then(() => { /* TODO */ }).catch(() => { /* TODO */ });
                }
            }
        },
    };
</script>

компоненты / MagnificPopup.vue:

<template>
    <div class="white-popup zoom-anim-dialog mfp-hide">
        <div class="container bg-light col-8 mx-auto p-3 rounded">
            <slot name="title"></slot>
            <div class="popup-content">
                <slot name="content"></slot>
            </div>
            <div class="popup-actions">
                <button type="button" @click="sendYes" class="btn btn-primary">
                    Yes
                </button>
                <button type="button" @click="sendNo" class="btn btn-secondary">
                    No
                </button>
            </div>
        </div>
    </div>
</template>

<script>
    import $ from 'jquery';
    require('magnific-popup');

    export default {
        methods: {
            sendYes() {
                this.$emit('click', 'confirm');
            },
            sendNo() {
                this.$emit('click', 'cancel');
            },
            close: function() {
                $.magnificPopup.close();
            },
            open: function(trigger) {
                $.magnificPopup.open({
                    items: {
                        src: this.$el,
                    },
                    midClick: true,
                    mainClass: 'my-mfp-zoom-in',
                    fixedContentPos: false,
                    fixedBgPos: true,
                    overflowY: 'auto',
                    closeBtnInside: true,
                    preloader: false,
                    removalDelay: 300,
                });
            },
        }
    };
</script>

<style lang="scss">
    @import '~magnific-popup/src/css/main';
    @import '../../css/magnific-popup.css';
</style>

Работает хорошо, но недостатком является то, что он создает один всплывающий элемент dom на компонент кнопки.

Сгенерированный HTML-код (лучше описывает проблему) - Мне не разрешено вставлять картинки.


Я бы предпочел не объявлять <magnific-popup> в каждом файле, который использует компонент <button-delete> (например, в myfile.html ).

Есть ли способ добавить этот всплывающий компонент в качестве зависимости, которая добавляется только один раз в DOM и используется позже?


То, чего я хочу достичь, будет что-то вроде

Только <delete-confirm> элементы объявлены в myfile.html , нет <magnific-popup>.

Объявите MagnificPopup как зависимость DeleteConfirm, чтобы при использовании одного или нескольких элементов <delete-confirm> в DOM myfile.html добавлялся отдельный элемент <magnific-popup>. 1055 *

Ответы [ 2 ]

0 голосов
/ 27 апреля 2018

Зарегистрируйте свой <magnific-popup> глобально в своем main.js (или там, где вы создаете свой корневой экземпляр Vue). Таким образом, компонент регистрируется только один раз, но он будет доступен для всех дочерних компонентов.

Вы не предоставили рабочий образец в своем вопросе, но в моих локальных тестах это генерирует только один модал / всплывающее окно - не несколько поверх друг друга.

// main.js

// Register your popup...
import MagnificPopup from '@/components/MagnificPopup'
Vue.component('magnific-popup', MagnificPopup)

// ...just before you create your Vue instance
new Vue({
  el: '#app',
  router,
  store,
  //...
})
0 голосов
/ 27 апреля 2018

Поместите всплывающее окно в родительском (на том же уровне используются button-delete с). При нажатии каждая кнопка должна $emit событие , которое родительский элемент обрабатывает, выполняя все, что вы хотите, для всплывающего окна.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...