为啥在卸载相关组件时保持“模态背景淡化显示”存在,我应该如何“删除/禁用”这个 div

Posted

技术标签:

【中文标题】为啥在卸载相关组件时保持“模态背景淡化显示”存在,我应该如何“删除/禁用”这个 div【英文标题】:Why keeps the "modal-backdrop fade show" exist when the concerning component is un-mounted and how should i "remove/disable" this div为什么在卸载相关组件时保持“模态背景淡化显示”存在,我应该如何“删除/禁用”这个 div 【发布时间】:2020-07-02 15:25:47 【问题描述】:

情况

我有一个 vue 组件,其中包含一个应该显示模态的子组件。 当我切换isShowModal bool(通过按钮或Vue devtools)时,会显示模态。当我单击模式中的关闭按钮(或在 devtools 中切换isShowModal)时, 模态关闭。所以到目前为止,这就像预期的那样工作。

当我尝试通过单击打开模式的按钮再次打开模式时,它不起作用。我注意到modal-backdrop 仍然“存在”(作为不可见的覆盖)。 我不明白为什么在卸载modal-component 时会发生这种情况。

当我通过 devtools 控制台使用命令 $("#"+ idHere).modal("hide"); 关闭模式时,模式,包括背景被隐藏。

注意:我有一些原因要安装/卸载组件以显示/关闭模式。出于这个原因,调用$("#" + "idHere").modal("show/hide"); 不是触发事件的选项吗? 我对事件进行了同样的尝试,只是为了测试目的,而不是模态包括。背景被完美地隐藏了。

下面的代码不是真正的代码,因为它包含的逻辑多于该问题所需的逻辑。当涉及到父/模型切换功能时,示例代码非常适合我的代码。 模态组件的模板几乎完全是从我的代码中复制过来的。

问题

当我卸载模态组件时,如何关闭/删除/禁用(无论正确的术语是什么)背景。 我用来挂载/卸载组件的方法是否可行? 最好的做法是像我在 Vue 中那样切换模式?

示例代码

父组件示例:

<template>
    <div>
      <modal-component
        title = "Zone"
        v-if = "isShowModal"
                :closeCallback = "() =>  isShowModal = false " />

        // Some button that toggles the isShowModal bool 
    </div>
</template>

<script>
  export default 
    mounted() 

    ,
    data() 
      return 
        isShowModal: false,
      
    ,
      showZoneNewModal: function(zone) 
            this.isShowModal = true;
        ,
    
</script>

模态组件示例:

<template>
  <div class="modal fade in" :id="this._uid" style="display: none; padding-right: 17px;" data-backdrop="static">
    <div class="modal-dialog">
      <div class="modal-content">
        <div class="modal-header">
                  <button type="button" class="close" v-on:click="closeCallback()" aria-label="Close">
            <span aria-hidden="true">×</span>
                  </button>
          <h4 class="modal-title"> title </h4>
        </div>
        <div class="modal-body">
          <div class="form-horizontal">
            // some header content
          </div>
        </div>
        <div class="modal-footer">
          // some body content
        </div>
      </div>
    </div>
  </div>
</template>

<script>
  export default 
    props: 
      closeCallback:  type: Function, required: true ,
        
    mounted() 
      $("#" + this._uid).modal('show');
    ,
        beforeDestroy() 
      $("#" + this._uid).modal("hide");
    ,
    
</script>

更新

这一行“生成”了背景 div。当我从模态组件的模板中删除所有其他代码时,问题仍然存在。

<template>
  <div class="modal fade in" :id="this._uid" style="display: none; padding-right: 17px;" data-backdrop="static">
  </div>
</template>

更新 2

我注意到,由于某种原因,在安装 modal-component 时会生成 2 个 div。在开发工具中没有 1 看起来像这样:

<div id="9" data-backdrop="static" class="modal fade in box-info show" style="display: block; padding-right: 17px;" aria-modal="true"></div>

没有 2 在开发工具中看起来像这样。这也是保持“活跃/活跃”的那个。我在我的 2 个组件之一中找不到带有 modal-backdrop 类的 div。 (也无法使用 grep 找到任何东西)。

<div class="modal-backdrop fade show"></div>

【问题讨论】:

由于某种原因,:id="this._uid" 是导致此问题的原因......即使我不明白到底发生了什么(我猜对 Vue 缺乏了解)。 - 删除:id="this._uid" 解决了我的问题。 modal的id默认还是_uid 【参考方案1】:

正如我在 previous question 中回复的那样 - 将 v-if 放在 div 包装器上,你会没事的(可能)。

&lt;template&gt; 中的任何其他html 标记一样,此背景div 是组件的一部分,并且会在组件被移除时被移除。

另外,不要使用#id,Vue不需要这个也没有理由这样做,如果你想定位特定元素,你可以使用$ref

最后一个 - 不喜欢在模板中使用匿名函数,因为 Vue 每次都会为它重新分配内存,该模板会被渲染。你总是可以使用方法来代替。

【讨论】:

我看到了你的答案,但我无法完成,因此这个新问题.. 我还尝试将 &lt;modal-component .../&gt; 包装在 div 中并将 v-if 应用于 div而不是modal-component 标签,但也不起作用。您的意思是我应该在子组件外部 div 上设置 if 吗? &lt;template&gt; &lt;div v-if="...".&gt;... ?由于模态在modal-component 内部并且该组件已卸载,我的逻辑说它还应该清理modal-backdrop div。 你应该把你的v-if 包含这个div,modal-backdrop 你在说。你在使用一些模态库吗? 如果这是组件的一部分,那么它在 v-if 为 false 之后绝对不应该存在...... 花了一些时间和试验,但终于我现在开始工作了(请参阅我的问题的评论) - 我不再使用 #id - 我不再使用事件 - 我知道我应该避免&lt;template&gt; 标记中的内联函数,但在 methods: 中创建函数看起来有点矫枉过正,只是切换一个布尔值。在这种情况下使用内联函数的缺点有那么大吗?卸载组件时Vue不会释放内存-我在模态关闭时“卸载”(v-if = false)它们 很高兴你解决了这个问题,这不是矫枉过正,而是正常的练习。虽然内存消耗不是很大,但如果你有更好的方法,为什么还要这样做:)

以上是关于为啥在卸载相关组件时保持“模态背景淡化显示”存在,我应该如何“删除/禁用”这个 div的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的组件一直在所有路由中呈现?

为啥我在c++里面的代码在vs2022里打不开?

在组件之间路由时如何保持 React 新的 Context API 状态?

为啥手机会闪屏,总是闪屏怎么办?

Nextjs如何在转到下一页时不卸载上一页(保持状态)

为啥mysql安装不了