Динамический, многоразовый модал в VUE - PullRequest
0 голосов
/ 20 сентября 2018

У меня есть родительское приложение с двумя дочерними компонентами.

  • Дочерний компонент A (manager-tab) переключает свойство данных в родительском приложении, отправляя событие.
  • Свойство data связано с реквизитом в дочернем компоненте B (manager-modal).
  • Когда это свойство данных переключается, открывается manager-modal.
  • Нажатие «Отправить» на manager-modal затем предполагает закрытие модального окна.

Проблема в том, что единственный способ, которым я смог иметь такое поведение, - это напрямую мутировать опору, которая переключается из-за испущенного события manager-tab.Это вызывает предупреждение консоли, и это то, что я хотел бы решить.Предупреждение:

view.app.php

<div id="app">
  <div class="app">
    <div class="app__container">
      <div class="app__row">
        <?php foreach ($member->rms as $rm): ?>
          <manager-tab
            :name="'<?= $rm->name; ?>'"
            :position="'RM'"
            :thumbnail="'<?= $rm->headshot ?>'"
            v-on:activate-rm-modal="activateRmModal"
          ></manager-tab>
        <?php endforeach; ?>
        <?php foreach ($member->ams as $am): ?>
          <manager-tab
            :name="'<?= $am->name; ?>'"
            :position="'AM'"
            :thumbnail="'<?= $am->headshot ?>'"
            v-on:activate-am-modal="activateAmModal"
          ></manager-tab>
        <?php endforeach; ?>
      </div>
    </div>
  </div>

  <manager-modal 
    :is-active="showRmModal"
    :phone="'<?= $rm->phone ?>'"
    :full-name="'<?= $rm->fullName; ?>'"
    :email="'<?= $rm->email; ?>'"
    :position="'RM'"
    :thumbnail="'<?= $rm->headshot ?>'"
  ></manager-modal>
  <manager-modal 
    :is-active="showAmModal"
    :phone="'<?= $am->phone ?>'"
    :full-name="'<?= $am->fullName; ?>'"
    :email="'<?= $am->email; ?>'"
    :position="'AM'"
    :thumbnail="'<?= $am->headshot ?>'"
  ></manager-modal>
</div>

view.app.js:

import Vue from 'vue';
import ManagerTab from '../vue-components/app/Manager_Tab.vue';
import ManagerModal from '../vue-components/app/Manager_Modal.vue';

window.App = new Vue({
  el: '#app',
  components: {
    ManagerTab,
    ManagerModal
  },
  data: {
    showRmModal: false,
    showAmModal: false,
  },
  methods: {
    activateRmModal: function() {
      this.showRmModal = true;
      this.showAmModal = false;
    },
    activateAmModal: function() {
      this.showAmModal = true;
      this.showRmModal = false;
    },
  },
});

Manager_Tab.vue:

<template>
  <div class="manager-tab" @click="emit">
    <img :src="this.thumbnail" class="manager-tab__thumbnail" />
    <div class="manager-tab__identity">
      <h5 class="identity__position">
        {{ this.position }}
      </h5>
      <h5 class="identity__name">
        {{ this.name }}
      </h5>
    </div>
    <div class="manager-tab__icon">
      <i class="fa fa-chevron-right"></i>
    </div>
  </div>
</template>

<script>
  export default {
    name: 'manager-tab',
    data() {
      return {
      }
    },
    props: {
      name      : '',
      phone     : '',
      fullName  : '',
      email     : '',
      position  : '',
      thumbnail : ''
    },
    methods: {
      emit: function() {
        if (this.position == "RM") {
          this.$emit('activate-rm-modal');
        } else {
          this.$emit('activate-am-modal');
        }
      }
    },
  }
</script>

Manager_Modal.vue:

<template>
    <div :class="{ 'modal-open' : isActive }" class="modal in" v-show="isActive">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal__header">
                    <img class="modal__profile-pic" :src="this.thumbnail" />
                    <div class="modal__contact-name">{{ this.name }}</div>
                    <div class="modal__contact-position">{{ this.position }}</div>

                    <div class="modal__contact-row">
                        <div class="modal__contact-phone">{{ this.phone }}</div>
                        <div class="modal__contact-separator">|</div>
                        <div class="modal__contact-email">{{ this.email }}</div>
                    </div>
                </div>
                <div class="modal-body">
                    <textarea class="modal__comment-block" placeholder="Send a message..." v-model="text"></textarea>
                </div>
                <div class="modal__footer">
                    <div class="modal__send-btn" @click="sendMessage()">Send</div>
                </div>
            </div>
        </div>
    </div>
</template>



<script>  
  import Axios from 'axios';

  export default {
    name: 'manager-modal',
    data() {
      return {
        isModalOpen: this.isActive,
        msg: '',
        personName: '',
        personPhone: '',
        personMessage: '',
      }
    },
    props: {
        phone       : '',
        fullName    : '',
        email       : '',
        position    : '',
        thumbnail   : '',
        isActive    : false
    },
    methods: {
        sendMessage: function() {
            if (this.text) {
                this.personMessage = this.text;
                this.close();
            } else {
                console.error('No message text');
            }
        },
        close: function() {
          this.isActive = !this.isActive;
        },
    },
  }
</script>


<style lang="scss" scoped>
    @import '../../../../scss/utilities/_index.scss';
    .modal-open {
        display: block;
    }
</style>

Я пытался присвоить значение isActive в Manager_Modal.vue свойству данных и использовать его для моих мутаций.

Это не сработало, и я думаю, что причина не сработала в том, что isActive изначально передается из родительского приложения.

Я пытался сделать то же самое с вычисляемым свойством, но это также не работает.Я сделал это, имея такой фрагмент кода в Manager_Modal.vue, как показано ниже:

computed: {
    isModalActive: function() {
        this.isActive = !this.isActive;
    }
}

Мое окончательное решение до того, как прийти сюда в SO, было попытка отправить еще одно событие родителю для переключения соответствующего флага (showRmModal или showAmModal), но родитель по какой-то причине не поймает событие.В vue devtools событие сработало, но родитель никогда его не поймает.

Я знаю, что решение этого вопроса прямо передо мной, но я просто не вижу его.Любая помощь будет принята с благодарностью.

JSFiddle: http://jsfiddle.net/eywraw8t/380816/

Вот несколько ссылок, по которым я прошел, прежде чем написать новый вопрос:

Какдинамическое добавление функций vue js в jquery

Шаблон проектирования веб-компонентов

Vue 2 - Мутирующие реквизиты vue-warn

Повторное использование модального режима с VueJS 2 <- это годичный вопрос, идентичный моему, но на него нет ответа, и мне не нравится копать старые темы, особенно когда для них нет решения. </p>

https://vuejs.org/v2/guide/components.html

https://laracasts.com/discuss/channels/vue/avoid-mutating-a-prop-directly-since-the-value-will-be-overwritten-whenever-the-parent-component-re-renders

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