我正在寻找一种方法来关闭组件,使其在元素的单击位置超出范围。
我尝试了addEventListener
。
这将关闭组件,但在关闭后将不会再次打开。
window.addEventListener('click', function(e){
if (document.getElementById('shopcartpreview').contains(e.target)){
console.log("Clicked in Box");
} else{
console.log("Clicked outside Box");
$('#shopcartpreview').hide();
}
})
有没有办法做到这一点?
<template>
<div id="shopcartpreview" v-if="carthover">
<div class="cartitem" v-for="item in cartitems">
<div class="cartitempic"><img class="productImg" width="80px" height="80px" v-bind:src="'assets/products/' + item.image"></div>
<div class="cartitemdetails">
<div class="cartitemname">{{item.name}}</div>
<div class="cartitemqty">1 X </div>
<div class="cartitemprice">€{{item.unit_price}}</div>
</div>
<div class="cartitemdelete">
<img src="assets/images/icon-bin.png" width="15px" height="15px">
</div>
</div>
<div class="carttotal">
<div class="carttotaltext">TOTAL:</div>
<div class="carttotalprice">€2,860.00</div>
</div>
<div class="cartcheckouttbn">PROCEED TO CHECKOUT</div>
<div class="viewcart">VIEW CART</div>
</div>
</template>
<script>
module.exports = {
data: function () {
return{
cartitems: 0,
carthover: false,
}
},
created(){
EventBus.$on('addToCart', (payload) =>{
this.cartitems = payload
}),
EventBus.$on('mouseover', (carthover) =>{
this.carthover = carthover
})
}
}
</script>
答案 0 :(得分:1)
Demo Fiddle:https://jsfiddle.net/bq8m4fhe/
创建clickoutside指令... Detect click outside element
module.exports = {
data: function() {
return {
cartitems: 0,
carthover: false
};
},
directives: {
clickoutside: {
bind: function(el, binding, vnode) {
el.clickOutsideEvent = function(event) {
// here I check that click was outside the el and his childrens
if (!(el == event.target || el.contains(event.target))) {
// and if it did, call method provided in attribute value
vnode.context[binding.expression](event);
}
};
document.body.addEventListener("click", el.clickOutsideEvent);
document.body.addEventListener("touchstart", el.clickOutsideEvent);
},
unbind: function(el) {
document.body.removeEventListener("click", el.clickOutsideEvent);
document.body.removeEventListener("touchstart", el.clickOutsideEvent);
},
stopProp(event) {
event.stopPropagation();
}
}
},
created() {
EventBus.$on("addToCart", payload => {
this.cartitems = payload;
}),
EventBus.$on("mouseover", carthover => {
this.carthover = carthover;
});
}
};
像这样使用该指令。
<div id="shopcartpreview" v-if="carthover" v-clickoutside="SHOPPING_CART_HIDE_FUNCTION">
答案 1 :(得分:0)
我在组件的末尾创建了一个div
元素,就像这样:
<div v-if="isPopup" class="outside" v-on:click="away()"></div>
在CSS中指定.outside
类的位置如下:
.outside {
width: 100vw;
height: 100vh;
position: fixed;
top: 0px;
left: 0px;
}
away()
是Vue实例中的一种方法,如下所示:
away() {
this.isPopup = false;
}
容易,效果很好。
答案 2 :(得分:0)
首先,当您打开一个组件(例如,下拉菜单)时,应将窗口对象绑定到一个click
事件,该事件用于关闭下拉菜单。在此,停止此事件的传播非常重要。
关于事件传播,bubbling and capturing。
然后,当您关闭下拉菜单时,应使用removeEventListener删除事件监听器。
如下所示的下拉菜单
<li class="user-profile nav-item">
<div class="dropdown" @click="toggleDropdown">
<img src="@/assets/user.jpg" alt="user-alias">
<ul class="dropdown-menu" v-if="showDropdown">
<li class="dropdown-menu-item"><a>Dashbord</a></li>
<li class="dropdown-menu-item"><a>Profile</a></li>
<li class="dropdown-menu-item"><a>Settings</a></li>
<li class="dropdown-menu-item"><a>Logout</a></li>
</ul>
</div>
</li>
Vue组件:
export default {
data () {
return {
showDropdown: false,
}
},
methods: {
toggleDropdown (e) {
e.stopPropagation() // this will stop propagation of this event to upper level
this.showDropdown = !this.showDropdown
if (this.showDropdown) {
window.addEventListener('click', () => {
this.showDropdown = false
})
} else {
window.removeEventListener('click', () => {
this.showDropdown = false
})
}
}
}
}