在Vue中使用模态时,为什么我的v-if如果不触发?

时间:2019-05-20 18:36:58

标签: vue.js

我正在使用v-if来控制Vue应用程序中页面的显示。 “页面”数据属性会跟踪当前页面,并通过单击按钮进行更新。直到我介绍模态,这种方法才能很好地发挥作用,因为现在当我打开模态并使用应用程序的导航按钮向后浏览两个页面时,即使属性已正确更新,该页面仍无法显示。

这是一个简化的示例-导航到页面B,然后C,然后显示模式2。取消模式2,然后导航到页面B,并且不显示任何内容(尽管标题指示页面属性为B)。

https://jsfiddle.net/fLmq0dxn/1/

我已经尝试了引导模式和本机js模式的这种方法,但是发生了相同的问题。控制台中未报告任何错误。我以为它可能是嵌套错误的div,但是我已经检查了这些并通过验证程序。

我意识到我的导航方法是原始的,模态可能应该是组件,但是我是Vue的新手,据我所知,我的方法“应该”起作用。谁能解释为什么不满意?

HTML:

<div id="app">

  <p>(app.page = {{page}})</p>
  <br/>

  <div class="page" id="A" v-if="page=='A'">
  Page A
  <br/>
  <button v-on:click="pager('B')">To B</button>
  </div>

  <div class="page" id="B" v-if="page=='B'">
  Page B
  <br/>
  <button v-on:click="pager('C')">To C</button>
  <button v-on:click="modalOpen('mod1')">Modal</button>
  </div>

  <!-- ************ Modal 1 ************************************ -->
  <div id="mod1" class="mod">
    <div class="mod-content">
      <span class="mod-close" v-on:click="modalClose">&times;</span>
      <h1>Modal 1</h1>

      <button v-on:click="modalClose" class="btn btn-secondary">Cancel</button>
    </div>
  </div>


  <div class="page" id="C" v-if="page=='C'">
  Page C
  <br/>
  <button v-on:click="pager('B')">To B</button>
  <button v-on:click="modalOpen('mod2')">Modal</button>
  </div>


     <!-- ************ Modal 2 ************************************ -->
  <div id="mod2" class="mod">
    <div class="mod-content">
      <span class="mod-close" v-on:click="modalClose">&times;</span>
      <h1>Modal 2</h1>

      <button v-on:click="modalClose" class="btn btn-secondary">Cancel</button>
    </div>
  </div>

</div>

CSS:

/* The Modal (background) */
.mod {
    display: none; /* Hidden by default */
    position: fixed; /* Stay in place */
    z-index: 1; /* Sit on top */
    left: 0;
    top: 0;
    width: 100%; /* Full width */
    height: 100%; /* Full height */
    overflow: auto; /* Enable scroll if needed */
    background-color: rgb(0,0,0); /* Fallback color */
    background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
  }

  /* Modal Content/Box */
  .mod-content {
    background-color: #fefefe;
    margin: 20% auto;
    padding: 20px;
    border: 1px solid #888;
    border-radius:8px;
    width: 90%;
    max-width:800px;
  }

  /* The Close Button */
  .mod-close {
    color: #aaa;
    float: right;
    font-size: 28px;
    font-weight: bold;
  }

  .mod-close:hover,
  .mod-close:focus {
    color: black;
    text-decoration: none;
    cursor: pointer;
  }

Javascript:

new Vue({
  el: "#app",
  data: {
        page: "A"
  },
  methods: {
    pager: function(target){
        this.page=target;
    },
    modalOpen: function(modID) {
        $('#'+ modID).css('display','block');
      },
    modalClose: function(){     
            $('.mod').css('display','none');
    }
  }
})

1 个答案:

答案 0 :(得分:1)

不幸的是,将Vue与jQuery结合会带来风险。

在您的特定情况下,似乎当您尝试关闭模式时,jQuery会使用“ mod”类查找所有元素,但是当隐藏它们时,Vue会篡改选择,最后您会隐藏不正确的元素(在您的情况下,页面B的内容)。 Vue的目的不是让另一个库摆弄DOM。

仅使用Vue即可“轻松”实现目标。由于您可以通过更改样式来管理模态,因此可以使用Vue class and/or style binding做类似的事情。

例如您可能有一个覆盖display: none的类,并且有条件地根据数据应用该类,这与处理页面非常相似。甚至可以像使用页面一样使用v-if管理模式。

条件类为https://jsfiddle.net/jfx8mbya/

的示例

由v-if管理的模态示例:

new Vue({
  el: "#app",
  data: {
    page: "A",
    modal: null
  },
  methods: {
    pager: function(target) {
      this.page = target;
    },
    modalOpen: function(modID) {
      this.modal = modID;
    },
    modalClose: function() {
      this.modal = null;
    }
  }
})
/* The Modal (background) */

.mod {
  /*display: none;*/
  /* Hidden by default */
  position: fixed;
  /* Stay in place */
  z-index: 1;
  /* Sit on top */
  left: 0;
  top: 0;
  width: 100%;
  /* Full width */
  height: 100%;
  /* Full height */
  overflow: auto;
  /* Enable scroll if needed */
  background-color: rgb(0, 0, 0);
  /* Fallback color */
  background-color: rgba(0, 0, 0, 0.4);
  /* Black w/ opacity */
}


/* Modal Content/Box */

.mod-content {
  background-color: #fefefe;
  margin: 20% auto;
  padding: 20px;
  border: 1px solid #888;
  border-radius: 8px;
  width: 90%;
  max-width: 800px;
}


/* The Close Button */

.mod-close {
  color: #aaa;
  float: right;
  font-size: 28px;
  font-weight: bold;
}

.mod-close:hover,
.mod-close:focus {
  color: black;
  text-decoration: none;
  cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">

  <p>(app.page = {{page}})</p>
  <br/>

  <div class="page" id="A" v-if="page=='A'">
    Page A
    <br/>
    <button v-on:click="pager('B')">To B</button>
  </div>

  <div class="page" id="B" v-if="page=='B'">
    Page B
    <br/>
    <button v-on:click="pager('C')">To C</button>
    <button v-on:click="modalOpen('mod1')">Modal</button>
  </div>

  <!-- ************ Modal 1 ************************************ -->
  <div id="mod1" class="mod" v-if="modal === 'mod1'">
    <div class="mod-content">
      <span class="mod-close" v-on:click="modalClose">&times;</span>
      <h1>Modal 1</h1>

      <button v-on:click="modalClose" class="btn btn-secondary">Cancel</button>
    </div>
  </div>


  <div class="page" id="C" v-if="page=='C'">
    Page C
    <br/>
    <button v-on:click="pager('B')">To B</button>
    <button v-on:click="modalOpen('mod2')">Modal</button>
  </div>


  <!-- ************ Modal 2 ************************************ -->
  <div id="mod2" class="mod" v-if="modal === 'mod2'">
    <div class="mod-content">
      <span class="mod-close" v-on:click="modalClose">&times;</span>
      <h1>Modal 2</h1>

      <button v-on:click="modalClose" class="btn btn-secondary">Cancel</button>
    </div>
  </div>

</div>