title: Vue JS dynamic modal with components
body: <blockquote>
  <p>in news.twig</p>
  </blockquote>
  <pre><code>{% extends 'layouts.twig' %}
  
  {% block content %}
  
  
  &lt;section class=&quot;ls section_padding_bottom_110&quot;&gt;
  
    &lt;div id=&quot;cart&quot; class=&quot;container&quot;&gt;
  
      &lt;cart
      v-bind:materials=&quot;news&quot;
      type=&quot;news&quot;
      test=&quot;materials&quot;
      &gt;&lt;/cart&gt;
      &lt;modal&gt;&lt;/modal&gt;
    &lt;/div&gt;
  
    &lt;script type=&quot;text/x-template&quot; id=&quot;modal-template&quot;&gt;
        &lt;transition name=&quot;modal&quot;&gt;
            &lt;div class=&quot;modal-mask&quot; v-if=&quot;active&quot; @click=&quot;close()&quot;&gt;
                &lt;div class=&quot;modal-wrapper&quot;&gt;
                    &lt;div class=&quot;modal-container&quot;&gt;
  
                        &lt;div class=&quot;modal-header&quot;&gt;
                            &lt;h3&gt;${ item.name }&lt;/h3&gt;
                        &lt;/div&gt;
  
                        &lt;div class=&quot;modal-body&quot;&gt;
                            ${ item.body }
                            &lt;br&gt;
                            modal #${ item.id }
                        &lt;/div&gt;
  
                        &lt;div class=&quot;modal-footer&quot;&gt;
                            &amp;nbsp;
                            &lt;button class=&quot;modal-default-button&quot; @click=&quot;close()&quot;&gt;
                                close
                            &lt;/button&gt;
                        &lt;/div&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
            &lt;/div&gt;
        &lt;/transition&gt;
    &lt;/script&gt;
  
  &lt;/section&gt;
  
  {% endblock %}
  </code></pre>
  <blockquote>
  <p>I have 2 components and 1 Vue in my js.</p>
  </blockquote>
  <pre><code>    var Hub = new Vue();
      
      Vue.component(
          'modal', {
              template: '#modal-template',
              delimiters: ['${', '}'],
              data: function() {
                  return {
                      active: false,
                      item: {
                          id: '',
                          name: '',
                          body: ''
                      }
                  }
              },
              methods: {
                  open: function (item) {
                      this.active = true;
                      this.item = item;
                  },
                  close: function () {
                      this.active = false;
                  }
              },
              mounted: function() {
                  this.$nextTick(function () {
                      Hub.$on('open-modal', this.open);
                      Hub.$on('close-modal', this.close);
                  }.bind(this));
              }
          });
  Vue.component('cart', {
    props: {
      materials: { type: Array, required: true},
      type: { type: String, required: true}
    },
    computed: {
      isPoints() {
        return this.type == 'paymentPoints';
      },
      isNews() {
        return this.type == 'news';
      }
    },
    template : `
    &lt;div class=&quot;row masonry-layout isotope_container&quot;&gt;
      &lt;div class=&quot;col-md-4 col-sm-6 isotope-item&quot; v-for=&quot;item in materials&quot;&gt;
        &lt;div class=&quot;vertical-item content-padding topmargin_80&quot;&gt;
          &lt;div class=&quot;item-media&quot;&gt;
            &lt;img v-bind:src=&quot;item.image&quot; alt=&quot;&quot;&gt;
            &lt;div class=&quot;media-links p-link&quot;&gt;
              &lt;div class=&quot;links-wrap&quot;&gt;
                &lt;i class=&quot;flaticon-arrows-2&quot;&gt;&lt;/i&gt;
              &lt;/div&gt;
              &lt;a v-if=&quot;!isNews&quot; v-bind:href=&quot;item.image&quot; class=&quot;abs-link&quot;&gt;&lt;/a&gt;
            &lt;/div&gt;
          &lt;/div&gt;
          &lt;button @click=&quot;openModal(item)&quot; @keyup.esc=&quot;closeModal()&quot;&gt;more&lt;/button&gt;
  
          &lt;div class=&quot;item-content with_shadow with_bottom_border&quot;&gt;
            &lt;span v-if=&quot;isNews&quot; class=&quot;categories-links&quot; style=&quot;font-size:20px;&quot;&gt;
              &lt;a rel=&quot;category&quot; href=&quot;#modal1&quot; data-toggle=&quot;modal&quot;&gt;
                {{item.name}}
              &lt;/a&gt;
            &lt;/span&gt;
            &lt;p&gt;{{item.body}}&lt;/p&gt;
            &lt;div v-if=&quot;isPoints&quot;&gt;
              &lt;hr class=&quot;light-divider full-content-divider bottommargin_10&quot;&gt;
              &lt;div class=&quot;media small-icon-media topmargin_5&quot;&gt;
                &lt;div class=&quot;media-left&quot;&gt;
                  &lt;i class=&quot;fa fa-map-marker grey fontsize_18&quot;&gt;&lt;/i&gt;
                &lt;/div&gt;
                &lt;div class=&quot;media-body&quot;&gt;
                  {{item.adress}}
                &lt;/div&gt;
              &lt;/div&gt;
              &lt;div class=&quot;media small-icon-media topmargin_5&quot;&gt;
                &lt;div class=&quot;media-left&quot;&gt;
                  &lt;i class=&quot;fa fa-phone grey fontsize_18&quot;&gt;&lt;/i&gt;
                &lt;/div&gt;
                &lt;div class=&quot;media-body&quot;&gt;
                  {{item.telephone}}
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div v-if=&quot;isNews&quot; class=&quot;text-center&quot;&gt;
            &lt;hr class=&quot;light-divider full-content-divider bottommargin_10&quot;&gt;
            &lt;span class=&quot;date&quot;&gt;
              &lt;i class=&quot;flaticon-clock-1 grey&quot;&gt;&lt;/i&gt;
              &lt;time class=&quot;entry-date&quot;&gt;
                {{item.date}}
              &lt;/time&gt;
            &lt;/span&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;
  
    &lt;/div&gt;
    `
  });
  
  var vm = new Vue({
    el: '#cart',
    name: 'cart',
    delimiters: ['${', '}'],
    data: {
      complated: [],
      continuing: [],
      planned: [],
      points: [],
      infoSlider: [],
      news: []
      },
      methods: {
        openModal: function (item) {
          Hub.$emit('open-modal', item);
        },
        closeModal: function () {
          Hub.$emit('close-modal');
        }
      },
      created() {
        axios.get(url).then(res =&gt; {
          var proje = res.data.projects[0];
          this.complated = proje.complated;
          this.continuing = proje.continuing;
          this.planned = proje.planned;
          this.points = res.data.paymentPoints;
          this.infoSlider = res.data.sliderİnfos;
          this.news = res.data.news;
        })
        .catch(e =&gt; {
          console.log(e);
        })
      }
    });
  </code></pre>
  <p>When I click <code>openModal(item)</code> button give me error ;</p>
  <blockquote>
  <p>Property or method &quot;openModal&quot; is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: <a href="https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties" rel="nofollow noreferrer">https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties</a>.</p>
  </blockquote>
  <p>I can not use the openModal function in component.
  I can use the function in news.twig without any problems, but then I can not use the component. Can you help me?</p>