Vue.js 显示从另一个组件调用一个组件

Vue.js Display call one component from another component

我有 2 个组成部分:

Vue.component('repo-button', {
  props:["check_in_id", "repo_id"],
  template: '#repo-button',
  methods: {
    fetchRepo: function() {
        url = window.location.href.split("#")[0] + "/check_ins/" + this.check_in_id + "/repositionings/" + this.repo_id + ".json"
        cl(url)
        cl(this)
        var that;
        that = this;

        $.ajax({
            url: url,
            success: function(data) {
                cl(data)
                that.showRepo();
            }
        })

    },
    showRepo: function() {
        // what do I put here to display the modal 
    }
  },
  data: function() {
  var that = this;
  return {

  }
}
});

Vue.component('repo-modal', {
    template: "#repo-modal",
    data: function() {
        return {
            status: 'none'
        }
    }
});

var repositionings = new Vue({
    el: "#repo-vue"
});

...我的视图由一个按钮和一个模式组成。我想要按钮在 repo-button 组件上调用 fetchRepo 并显示模态(将其 status 属性 从 none 更改为 block.

<script type="text/x-template" id="repo-button">
    <div class='socialCircle-item success'>
    <i class='fa fa-comment' 
         @click="fetchRepo"
      :data-check_in='check_in_id' 
      :data-repo='repo_id'> 
    </i>
  </div>
</script>

<script type="text/x-template" id="repo-modal">
    <div  v-bind:style="{ display: status }" class="modal" id="vue-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" data-client_id="<%= @client.id %>">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h4 class="modal-title"></h4>
                </div>
                <div class="modal-body"></div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-danger btn-simple" data-dismiss="modal">Close</button>
                </div>
            </div>
        </div>
    </div>
</script>

<div id="repo-vue">
    <div is="repo-modal"></div>
    <div is="repo-button" repo_id="<%= ci.repositioning.id %>" check_in_id="<%= ci.id %>"></div>
</div>

Props down, events up

In Vue.js, the parent-child component relationship can be summarized as props down, events up. The parent passes data down to the child via props, and the child sends messages to the parent via events.

特别是,如果组件的状态需要在外部(由父级或兄弟级)控制,则该状态应作为 prop 从父级传入。事件向父级指示应该更改状态。

模态框的状态由其自身和同级组件中的事件控制。所以状态存在于父级中,并作为道具传递给模态。单击模态关闭按钮会发出(自定义)hidemodal 事件;单击同级组件的评论图标会发出 showmodal 事件。父级通过相应地设置其 showRepoModal 数据项来处理这些事件。

Vue.component('repo-button', {
  template: '#repo-button',
  methods: {
    showRepo: function() {
      this.$emit('showmodal');
    }
  }
});

Vue.component('repo-modal', {
  template: "#repo-modal",
  props: ["show"],
  computed: {
    status() {
      return this.show ? 'block' : 'none'
    }
  },
  methods: {
    hideRepo() {
      this.$emit('hidemodal');
    }
  }
});

var repositionings = new Vue({
  el: "#repo-vue",
  data: {
    showRepoModal: false
  }
});
.socialCircle-item i {
  cursor: pointer;
}
<link href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.2.6/vue.min.js"></script>
<template id="repo-button">
    <div class='socialCircle-item success'>
    <i class='fa fa-comment' 
         @click="showRepo"
         >
    </i>
  </div>
</template>

<template id="repo-modal">
    <div  v-bind:style="{ display: status }" class="modal" id="vue-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" >
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h4 class="modal-title"></h4>
                </div>
                <div class="modal-body"></div>
                <div class="modal-footer">
                    <button type="button" @click="hideRepo" class="btn btn-danger btn-simple" data-dismiss="modal">Close</button>
                </div>
            </div>
        </div>
    </div>
</template>

<div id="repo-vue">
  <div is="repo-modal" :show="showRepoModal" @hidemodal="showRepoModal = false"></div>
  <div is="repo-button" @showmodal="showRepoModal = true"></div>
</div>