2017-08-01 45 views
3
Vue.directive('login-to-click', { 
    bind (el) { 
    const clickHandler = (event) => { 
     event.preventDefault() 
     event.stopImmediatePropagation() 
     alert('click') 
    } 
    el.addEventListener('click', clickHandler, true) 
    } 
}) 

使用如何防止/停止指令(VUE 2.X)違約事件(點擊)的傳播

<button @click="handleClick" v-login-to-click>CLICK</button> 

​​總是被觸發。我怎樣才能防止來自指令?嘗試了/沒有addEventListener「捕獲」標誌沒有任何運氣。


現在我結束了以下解決方案:

Vue.prototype.$checkAuth = function (handler, ...args) { 
    const isLoggedIn = store.getters['session/isLoggedIn'] 
    if (isLoggedIn) { 
    return handler.apply(this, args) 
    } else { 
    router.push('/login') 
    } 
} 

然後在組件

<button @click="$checkAuth(handleClick)">CLICK</button> 

回答

0

您可以使用:

event.target.preventDefault(); 

我不知道爲什麼想要這樣做,因爲你正在添加點擊監聽器的原因。

也許你可以澄清你的問題多一點。

+0

event.target.preventDefault未定義。 – user606521

+0

那麼當你登錄時你的'event'實際上會顯示什麼? –

1

根據我的理解,這些是兩個不同的事件處理程序,您只能阻止指令中綁定的默認事件,但這對@click沒有影響,因爲您不覆蓋點擊偵聽器,而是添加第二個。 如果您希望阻止默認的@click綁定,則可以使用@click.prevent="handleClick"

我不認爲有任何方法可以從指令中完成它,因爲您通過將@click綁定到按鈕來顯式添加另一個偵聽器。

+0

我的用例非常簡單:在我的應用程序中,我有許多按鈕(按照/ like/add to watchlist/block等),需要用戶登錄才能點擊它們。我想添加v-login-to-click指令,如果用戶沒有登錄,將阻止給定元素/組件的點擊(相反,我會將用戶重定向到登錄頁面或顯示登錄模式)。 – user606521

+0

就像我說過的,你不能用指令覆蓋@cllick所綁定的clicklistener。你可以做的唯一的事情就是在你使用指令和'@ click'或(注意:hacky)的地方使用click.prevent,在指令中使用el引用並刪除所有其他的點擊監聽器。我真的不認爲2)是一種選擇,因爲它會逐字刪除你的情況下的handleClick。 –

3
在我的應用程序

我有很多按鈕(遵循/像/加入收藏夾/塊 等)需要用戶先登錄點擊它們

與在Vue公司2很多東西這對指令來說是一個糟糕的用例,但是對於一個組件來說卻是非常好的用例。

這裏有一個按鈕,當用戶被授權,這只是點擊。

console.clear() 
 

 
const AuthenticatedButton = { 
 
    props:["onAuth", "onNonAuth", "disable", "auth"], 
 
    template: ` 
 
    <button @click="onClick" 
 
      :disabled="disableWhenNotAuthorized"> 
 
     <slot>{{this.auth}}</slot> 
 
    </button>`, 
 
    computed:{ 
 
    disableWhenNotAuthorized(){ 
 
     return this.disable && !this.auth 
 
    } 
 
    }, 
 
    methods:{ 
 
    onClick(){ 
 
     if (this.auth && this.onAuth) this.onAuth() 
 
     if (!this.auth && this.onNonAuth) this.onNonAuth()  
 
    } 
 
    } 
 
} 
 

 
new Vue({ 
 
    el:"#app", 
 
    data:{ 
 
    loggedIn: false 
 
    }, 
 
    methods:{ 
 
    onClick(){ 
 
     alert("User is authenticated") 
 
    }, 
 
    notAuthorized(){ 
 
     alert("You are not authorized.") 
 
    } 
 
    }, 
 
    components:{ 
 
    "auth-btn": AuthenticatedButton 
 
    } 
 
})
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script> 
 
<div id="app"> 
 
    <h3>User is {{!loggedIn ? 'Not Authorized' : 'Authorized'}}</h3> 
 
    <auth-btn :auth="loggedIn" 
 
      :on-auth="onClick" 
 
      :on-non-auth="notAuthorized"> 
 
    Executes non auth handler when not authorized 
 
    </auth-btn> <br> 
 
    <auth-btn :auth="loggedIn" 
 
      :on-auth="onClick" 
 
      :disable="true"> 
 
    Disabled when not authorized 
 
    </auth-btn> <br><br> 
 
    <button @click="loggedIn = true">Authenicate User</button> 
 
</div>

使用此按鈕可以設置授權的處理器和非授權的處理程序。另外,如果用戶未被授權,您可以禁用該按鈕。

在此組件的授權狀態通過屬性傳遞的,但如果你正在使用某種形式的國家管理(如Vuex)的,你可以很容易地使用來代替。

+0

這是一個很好的例子,但假設其中一個組件不是按鈕,而是鏈接或圖像。然後,我將不得不爲他們每個人準備sich包裝。 – user606521

+0

@ user606521這實際上花了我大約10分鐘的時間來寫。如果需要,除模板外的所有內容都可以是混合模式。您的擔憂是有效的,但感覺像是不成熟的優化。 – Bert

+0

現在我結束了另一種解決方案(請參閱我的編輯問題)。我只想保持代碼清潔和儘可能小 - 我正在處理一個包含100多個不同頁面的項目。我不確定我的解決方案是不是一點點「哈克」,但它運作良好。 – user606521

0

以我爲例,我需要有條件地阻止右側的默認行爲和左箭頭鍵。當光標在我的輸入字段的中間時,我希望事件的正常行爲移動光標。但是,當我到達輸入的開始或結束時,我希望焦點切換到下一個輸入,並將光標定位到下一個字段的開始處,以便向右箭頭和下一個字段的末尾處向左箭頭。當我將光標放在下一個字段的開頭或結尾時,默認的左或右事件行爲會給我一個「一次性」的效果。發生這種情況是因爲在更改焦點並設置光標位置後,左側或右側箭頭鍵事件可以完成其默認行爲。

在我的情況「event.target.preventDefault()」沒有停止默認行爲。我使用「event.preventDefault()」來防止事件的默認行爲:

<template> 
    <div> 
    <input 
     @keydown.right.stop="right($event)" 
    > 
    <!-- 
     other inputs are defined here 
    --> 
    </div> 
</template> 

<script type="text/javascript"> 
export default { 
    methods: { 
    right (event) { 
     /* 
     code to conditionally change input element focus goes here 
     */ 
     // prevent default behavior 
     event.preventDefault() 
    } 
    } 
} 
</script>