Vue:在<slot>中从父级获取数据

时间:2020-06-05 14:27:50

标签: vue.js vue-js-modal

我不知道我想要的方式是否可行。我正在将此Vue插件用于模态:https://www.npmjs.com/package/vue-js-modal

我有一个名为ModalButton的组件,负责触发模式:

<modal-button :modal-data="{{  collect(['account' => $account])  }}" modal-name="leave-account">Leave Account</modal-button>

如您所见,我正在发送:modal-data作为道具。

ModalButton组件如下:

<template>
  <button @click.prevent="show" type="button" class="px-3 py-2 bg-gray-200 font-bold text-gray-700 ">
    <slot></slot>
  </button>
</template>

<script>
// @ is an alias to /src

export default {

  name: 'ModalButton',
  data() {
      return {

      }
  },

  props: {
    modalName: String,
    modalData: Object
  },

  methods: {
    show () {
      this.$modal.show(this.modalName, this.modalData);
    },
    hide () {
      this.$modal.hide(this.modalName);
    }
  }
}
</script>

您可以在show方法上看到,该方法来自于将数据发送到模态的插件

this.$modal.show(this.modalName, this.modalData);

在我的刀片服务器模板(我使用laravel)中,我有<modal>

<modal name="leave-account" class="text-center">
    <div class="flex items-center justify-center h-full p-6">
        <div>
            <div>
                <div class="text-3xl font-bold mb-2">Are you sure?</div>
                <p>If you leave this account, you won't be able to join back unless invited again. </p>
            </div>
            <footer class="flex items-center justify-end mb-24 mt-auto">
                <button class="px-3 py-2 bg-gray-200 font-bold text-gray-700 mr-3">Cancel</button>
                <ajax-button 
                class-list="px-3 py-2 bg-primary text-white font-bold"
                :route=@{{SOMEHOW ACCESS MODAL DATA}}
                method="delete">
                Yes, leave account
                </ajax-button>
            </footer>
        </div>
    </div>
</modal>

在我的模式中,我还有另一个名为AjaxButton的组件,它使我可以使用一个可重用的按钮来处理ajax请求。

我需要一种方法来访问传递给模态的模态数据。我不想不必创建其他特定的模态组件来处理此问题。

这可能吗?

:route道具需要发送的具体内容是Account,因为我的路线需要模型绑定。即看起来像/accounts/leave/53

编辑:

所以我可以这样做:

<button @click="$modal.hide('leave-account')" class="px-3 py-2 bg-gray-200 font-bold text-gray-700 mr-3">Cancel</button>

(就在我的<ajax-button>上方)

很显然,我能够访问$modal属性/方法。所以必须有一种方法来实现我想要的

1 个答案:

答案 0 :(得分:0)

您可以使用更简单的模式:

<modal-button v-model="showModal">
Leave Account
</modal-button>
<modal v-model="showModal" caption="Leave Account">
{{  collect(['account' => $account])  }}
</modal>

然后modal-button将如下所示:

<template>
  <button @click.stop="$emit('input',true)" type="button" class="px-3 py-2 bg-gray-200 font-bold text-gray-700 ">
    <slot/>
  </button>
</template>

<script>
export default
{
  name: 'ModalButton',
  props:
  {
    value:
    {
      type: Boolean,
      default: false
    }
  }
}
</script>

modal组件将是:

<template>
  <transition name="modal">
    <div class="modal_overlay" @click="close" v-if="value">
      <div class="modal_content" style="overflow: auto;" @click.stop>
        <div class="modal_title">{{ caption }} <div class="modal_close" @click="close">&#10006;</div></div>
        <slot/>
      </div>
    </div>
  </transition>
</template>

<script>

export default
{
  props: 
  {
    value:
    {
      type: Boolean,
      default: false
    },
    caption:
    {
      type: String,
      default: ''
    },

  created()
  {
    document.addEventListener('keydown', this.modal_escape, false);
  },
  beforeDestroy()
  {
    document.removeEventListener('keydown', this.modal_escape, false);
  },
  methods:
    {
      close()
      {
        this.$emit('input', false);
      },
      modal_escape(event)
      {
        var e = event || window.event;
        if(this.value && e.keyCode == 27)
        {
          this.close();
          // All good browsers…
          if (e.preventDefault) e.preventDefault();
          // …and IE
          if (e.returnValue) e.returnValue = false;
          return false;
        }
      }
    }
}
</script>

<style>
  .modal_overlay
  {
    position: fixed;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    z-index: 25;
    text-align: initial;
    background-color: rgba(0,0,0,0.75);
  }

  .modal_content
  {
    position: relative;
    display: inline-block;
    left: 50%;
    top: 50%;
    transform: translate(-50%,-50%);
    background-color: white;
    border: 2px solid #000;
    border-radius: 5px;
    max-width: 90vw;
    max-height: 90vh;
  }

  .modal_title
  {
    text-align: center;
    background-color: #F27935;
    color: white;
    line-height: 1.65;
    padding-left: 6px;
  }

  .modal_close
  {
    float: right;
    display: inline-block;
    cursor: pointer;
    padding: 0 5px 0 4px;
  }

  .modal_close:hover
  {
    color: white;
    background-color: #00B4FF;
  }

  .modal-enter-active
  {
    transition: all .4s ease;
  }

  .modal-leave-active
  {
    transition: all .2s cubic-bezier(1.0, 0.5, 0.8, 1.0);
  }

  .modal-enter, .modal-leave-to
  {
    transform: translateX(10px);
    opacity: 0;
  }
</style>