如何拦截引导"data-target"事件?



对问题的阐述:

我正在使用引导模式对话框,我只希望在用户登录时它起作用。

虽然 vue.js 可以使这个元素完全消失,如果用户没有登录,或者处理任何类型的链接,"数据目标"给我带来了麻烦。

目标:在激活模式之前检查用户是否已登录。 如果用户未登录,我会在代码中的其他地方处理它(细节与IMO的这个问题无关,但涉及激活一个完全独立的模态(。

如果用户已登录,则允许通过"数据目标"激活模式

问题:目前,当用户未登录时,"reportModalIdWithHash"在 'checkForLogin(('

法典:

<span
class="float-right text-muted smaller-font make-clickable"
data-toggle="modal"
:data-target="reportModalIdWithHash"
v-on:click="checkForLogin()"
>
Report
</span>

有关首选解决方案的说明:

我希望在模态由"数据目标"触发之前发生"checkForLogin(("。

虽然我总是可以用 Vue.js 让元素消失,但我希望用户看到该选项,然后在他们单击它时,如果他们没有登录,则显示登录名而不是报告模式。

是否有可能拦截并重新触发"数据目标"?

为什么不使用动态data-target

:data-target="`#${isLoggedIn ? 'fancy' : 'login'}-modal`"

new Vue({
el: '#app',
data: () => ({
isLoggedIn: false
}),
methods: {
handleLogin() {
// replace this with an async API call...
this.isLoggedIn = true;
// and switch modals...
['fancy', 'login'].forEach(name => $(`#${name}-modal`).modal('toggle'));
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" ></script>
<div id="app" class="container">
<div class="form-check p-3">
<input class="form-check-input" type="checkbox" v-model="isLoggedIn" id="check">
<label class="form-check-label" for="check">
<code>isLoggedIn</code> (click to change)
</label>
</div>
<div class="btn btn-primary"  data-toggle="modal"
v-text="`Open Report`"
:data-target="`#${isLoggedIn ? 'fancy' : 'login'}-modal`"></div>
<div class="modal fade" tabindex="-1" role="dialog" id="login-modal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Login modal</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<p>Login modal content goes here.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" @click="handleLogin" data-dismiss="modal" >Login</button>
</div>
</div>
</div>
</div>
<div class="modal fade" tabindex="-1" role="dialog" id="fancy-modal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Fancy report</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<p>Fancy report goes here.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Meh...</button>
<button type="button" class="btn btn-primary">OK</button>
</div>
</div>
</div>
</div>
</div>


注意:这是一个简单的概念证明,而不是生产就绪的代码:

  • 不要像我的例子那样使用 Vue + Bootstrap + jQuery(这很野蛮(。你最好使用BootstrapVue(并摆脱jQuery(。
  • 您可能希望使用单个动态模式,并通过插槽注入正文、标题和页脚内容。这并不总是更好,但一般来说,以牺牲可读性为代价会导致 DRY-er 代码。

使用 BootstrapVue,您的按钮看起来更像这样:

<b-btn v-b-modal[`${isLoggedIn ? 'fancy' : 'login'}-modal`]> Open Modal</b-btn>

。或者,如果要在方法中处理它:

<b-btn @click="handleOpenModal">Open modal</b-btn>

和:

methods: {
handleOpenModal() {
this.$bvModal.open(this.isLoggedIn ? 'fancy-modal' : 'login-modal');
}
}

最新更新