Edit in JSFiddle

Vue.component('Modal', {
  template: '#modal-template',
  props: ['show', 'onClose'],
  methods: {
    close: function () {
        this.onClose();
    }
  },
  ready: function () {
    document.addEventListener("keydown", (e) => {
      if (this.show && e.keyCode == 27) {
        this.onClose();
      }
    });
  }
});

Vue.component('NewPostModal', {
  template: '#new-post-modal-template',
  props: ['show'],
  data: function () {
  	return {
    	title: '',
      body: ''
    };
  },
  methods: {
    close: function () {
      this.show = false;
      this.title = '';
      this.body = '';
    },
    savePost: function () {
      // Insert AJAX call here...
      this.close();
    }
  }
});

Vue.component('NewCommentModal', {
  template: '#new-comment-modal-template',
  props: ['show'],
  data: function () {
  	return {
      comment: ''
    };
  },
  methods: {
    close: function () {
      this.show = false;
      this.comment = '';
    },
    postComment: function () {
      // Insert AJAX call here...
      this.close();
    }
  }
});

new Vue({
  el: '#app',
  data: {
    showNewPostModal: false,
    showNewCommentModal: false
  }
});
<!-- template for the Modal component -->
<script type="x/template" id="modal-template">
    <div class="modal-mask" @click="close" v-show="show" transition="modal">
        <div class="modal-container" @click.stop>
            <slot></slot>
        </div>
    </div>
</script>

<!-- template for the NewPostModal component -->
<script type="x/template" id="new-post-modal-template">
    <modal :show.sync="show" :on-close="close">
        <div class="modal-header">
            <h3>New Post</h3>
        </div>

        <div class="modal-body">
            <label class="form-label">
                Title
                <input v-model="title" class="form-control">
            </label>
            <label class="form-label">
                Body
                <textarea v-model="body" rows="5" class="form-control"></textarea>
            </label>
        </div>

        <div class="modal-footer text-right">
            <button class="modal-default-button" @click="savePost()">
                Save
            </button>
        </div>
    </modal>
</script>


<!-- template for the NewCommentModal component -->
<script type="x/template" id="new-comment-modal-template">
    <modal :show.sync="show" :on-close="close">
        <div class="modal-header">
            <h3>New Comment</h3>
        </div>

        <div class="modal-body">
            <label class="form-label">
                Comment
                <textarea v-model="comment" rows="5" class="form-control"></textarea>
            </label>
        </div>

        <div class="modal-footer text-right">
            <button class="modal-default-button" @click="postComment()">
                Post
            </button>
        </div>
    </modal>
</script>


<!-- app -->
<div id="app">
    <new-post-modal :show.sync="showNewPostModal"></new-post-modal>
    <new-comment-modal :show.sync="showNewCommentModal"></new-comment-modal>
    <button @click="showNewPostModal = true">New Post</button>
    <button @click="showNewCommentModal = true">New Comment</button>
</div>
* {
    box-sizing: border-box;
}

.modal-mask {
    position: fixed;
    z-index: 9998;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, .5);
    transition: opacity .3s ease;
}

.modal-container {
    width: 300px;
    margin: 40px auto 0;
    padding: 20px 30px;
    background-color: #fff;
    border-radius: 2px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, .33);
    transition: all .3s ease;
    font-family: Helvetica, Arial, sans-serif;
}

.modal-header h3 {
    margin-top: 0;
    color: #42b983;
}

.modal-body {
    margin: 20px 0;
}

.text-right {
    text-align: right;
}

.form-label {
    display: block;
    margin-bottom: 1em;
}

.form-label > .form-control {
    margin-top: 0.5em;
}

.form-control {
    display: block;
    width: 100%;
    padding: 0.5em 1em;
    line-height: 1.5;
    border: 1px solid #ddd;
}

.modal-enter, .modal-leave {
    opacity: 0;
}

.modal-enter .modal-container,
.modal-leave .modal-container {
    -webkit-transform: scale(1.1);
    transform: scale(1.1);
}

External resources loaded into this fiddle: