简体   繁体   中英

Vue JS dynamic modal with components

in news.twig

{% extends 'layouts.twig' %}

{% block content %}


<section class="ls section_padding_bottom_110">

  <div id="cart" class="container">

    <cart
    v-bind:materials="news"
    type="news"
    test="materials"
    ></cart>
    <modal></modal>
  </div>

  <script type="text/x-template" id="modal-template">
      <transition name="modal">
          <div class="modal-mask" v-if="active" @click="close()">
              <div class="modal-wrapper">
                  <div class="modal-container">

                      <div class="modal-header">
                          <h3>${ item.name }</h3>
                      </div>

                      <div class="modal-body">
                          ${ item.body }
                          <br>
                          modal #${ item.id }
                      </div>

                      <div class="modal-footer">
                          &nbsp;
                          <button class="modal-default-button" @click="close()">
                              close
                          </button>
                      </div>
                  </div>
              </div>
          </div>
      </transition>
  </script>

</section>

{% endblock %}

I have 2 components and 1 Vue in my js.

    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 : `
  <div class="row masonry-layout isotope_container">
    <div class="col-md-4 col-sm-6 isotope-item" v-for="item in materials">
      <div class="vertical-item content-padding topmargin_80">
        <div class="item-media">
          <img v-bind:src="item.image" alt="">
          <div class="media-links p-link">
            <div class="links-wrap">
              <i class="flaticon-arrows-2"></i>
            </div>
            <a v-if="!isNews" v-bind:href="item.image" class="abs-link"></a>
          </div>
        </div>
        <button @click="openModal(item)" @keyup.esc="closeModal()">more</button>

        <div class="item-content with_shadow with_bottom_border">
          <span v-if="isNews" class="categories-links" style="font-size:20px;">
            <a rel="category" href="#modal1" data-toggle="modal">
              {{item.name}}
            </a>
          </span>
          <p>{{item.body}}</p>
          <div v-if="isPoints">
            <hr class="light-divider full-content-divider bottommargin_10">
            <div class="media small-icon-media topmargin_5">
              <div class="media-left">
                <i class="fa fa-map-marker grey fontsize_18"></i>
              </div>
              <div class="media-body">
                {{item.adress}}
              </div>
            </div>
            <div class="media small-icon-media topmargin_5">
              <div class="media-left">
                <i class="fa fa-phone grey fontsize_18"></i>
              </div>
              <div class="media-body">
                {{item.telephone}}
              </div>
            </div>
          </div>
          <div v-if="isNews" class="text-center">
          <hr class="light-divider full-content-divider bottommargin_10">
          <span class="date">
            <i class="flaticon-clock-1 grey"></i>
            <time class="entry-date">
              {{item.date}}
            </time>
          </span>
          </div>
        </div>
      </div>
    </div>

  </div>
  `
});

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 => {
        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 => {
        console.log(e);
      })
    }
  });

When I click openModal(item) button give me error ;

Property or method "openModal" 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: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties .

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?

You are using openModal in cart component, but that method is defined in root component. According to Vue's documentation :

Everything in the parent template is compiled in parent scope; everything in the child template is compiled in the child scope.

in my case need to define variable in vuejs

like this

<script>
    export default {
        name: "MegaMenu",
        props: {
          categories: Array,
        },
    }

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