Vue.js - 从孙插槽组件发射没有将 $emit 事件冒泡到父级

Posted

技术标签:

【中文标题】Vue.js - 从孙插槽组件发射没有将 $emit 事件冒泡到父级【英文标题】:Vue.js - Emit from grandchild slot component didn't bubble $emit event to parent 【发布时间】:2020-08-07 19:18:34 【问题描述】:

我计划并制作了一个模态窗口,然后创建了一个按钮来关闭模态窗口。 我想使用 $emit 作为按钮的事件来更改 isHomeDialog 的值。 但是,$emit 的事件没有传递到“Home.vue”

主页.vue

<template>
  <div>
    <ReviewDialog
      :is-open="isHomeDialog"
      @close="closeEvent()/>
  </div>
</template>

<script>
import ReviewDialog from '@/components/popup/dialog/ReviewDialog';
</script>

export default 
  name: 'Home',
  components: 
    ReviewDialog
  ,
  data () 
    return 
      isHomeDialog: true
    ;
  ,
  methods: 
    closeEvent () 
      console.log('close');
      isHomeDialog = false;
    
  
;

BaseDialog.vue

<template>
  <div v-show="isOpen">
    <div class="mask">&nbsp;</div>
    <div class="content">
      <button
        class="close"
        @click="$emit('close')">&nbsp;</button>

      <slot/>

    </div>
  </div>
</template>
<script>
export default 
  props: 
    isOpen: 
      type: Boolean,
      required: true
    
  
;

reviewdialog.vue

<template>
  <BaseDialog
    url="@/components/popup/dialog/BaseDialog"
    id="review-dialog"
    :is-open="isOpen"
    :header-text="'REVIEW'">

    <div class="warp">
      <p>
        test
      </p>
    </div>
  </BaseDialog>
</template>

<script>
import BaseDialog from '@/components/popup/dialog/BaseDialog';

export default 
  components: 
    BaseDialog
  ,
  props: 
    isOpen: 
      type: Boolean,
      default: false
    
  
</script>

首页 └ 基础对话框 └评论对话框

在上述结构中,我尝试使用 $emit 向 BaseDialog 和 ReviewDialog 发送请求,但没有传递到 Home。 除了使用 $root.$emit 请求它之外,还有什么方法可以将 $emit 发送到其父组件?

【问题讨论】:

【参考方案1】:

BaseDialog 向其父级ReviewDialog 发出close 事件,后者并未监听它。所以你需要在ReviewDialog监听,并将事件重新发送到Home

<BaseDialog
    url="@/components/popup/dialog/BaseDialog"
    id="review-dialog"
    :is-open="isOpen"
    :header-text="'REVIEW'"
    @close="$emit('close')"> <-- This line is new -->

另一种方法是让ReviewDialog 传递其所有侦听器:

<BaseDialog
    url="@/components/popup/dialog/BaseDialog"
    id="review-dialog"
    :is-open="isOpen"
    :header-text="'REVIEW'"
    v-on="$listeners"> <-- This line is new -->

【讨论】:

非常感谢您的帮助。 $listeners 是一个事件处理程序,但它似乎接收并传递子组件的 $emit 事件。对吗? 不客气。 $listeners 包含所有监听组件的东西,它是一种特殊的语法,将它们全部传递给子组件【参考方案2】:

由于在 Vue2 中不推荐使用双向绑定 + 子不能直接改变 props

可能是另一种方法custom component with v-model

我把参考放在下面: vuejs update parent data from child component

【讨论】:

以上是关于Vue.js - 从孙插槽组件发射没有将 $emit 事件冒泡到父级的主要内容,如果未能解决你的问题,请参考以下文章

Vue.js 将数据从插槽传递到组件实例

Vue.js 将插槽传递给包装好的 Bootstrap-Vue 表组件

将父母道具传递给Vue,js中的插槽

将插槽传递到 Vue.js 中的插槽

Vue.js slot插槽

Vue.js(17)之 插槽