v-on 綁定事件時,函數名加括弧和不加括弧有什麼區別?

本人開始學習vue.js,之前在博客上看到一個例子

&
&
&
&&
&
&

&
&
&


不要想的太複雜,只傳函數名相當於觸發事件時把那個函數當成是事件處理器

代括弧的話,@click="fn()"相當於把這個引號裡面的字元串當代碼執行(所以這裡甚至可以寫成@click="a = a + 1",反正就是執行引號里的代碼),另外用這種寫法時,引號內部可以訪問vue實例上所有的值,同時在事件觸發時也有一個$event對象可以用

就這點區別


從官方的文檔 事件處理器 — Vue.js 中可以看出通過 `v-on` 中既可以執行一段代碼、一個方法、內聯 JavaScript 語句,根據不同的情況 Vue 會做不同的處理,具體可以從源碼中可以看出(2.1.10版本),在編譯階段,會根據抽象HTML語法樹生成代碼,從 https://github.com/vuejs/vue/blob/v2.1.10/src/compiler/codegen/index.js#L194 可以看出如果此時包含了事件處理,則會調用 `genHandlers` 生成事件處理代碼,最終走到 https://github.com/vuejs/vue/blob/v2.1.10/src/compiler/codegen/events.js#L46 ,這裡有兩個正則判斷,判斷是函數正則以及屬性訪問正則,如果兩個正則匹配成功則直接返回當前的值,否則用 `function($event){${handler.value}}` 包裹一次。

針對於你的疑問來說,如果說你是直接給定的 `greet` 的話,則屬性訪問正則匹配成功,如果是`greet()` 或者 `x+=1` 來說,則兩個正則都匹配失敗,利用函數包裹一層;而額外的第一種判斷函數的正則則只有是你寫的是函數的時候才會匹配成功,也就是類似於 `function () {xxx}` 或者 `() =&> dsf` 也就是一個匿名函數或者箭頭函數。

最後,到底需不需要加括弧的話,一般就是要看參數的情況了:

1、不需要參數或者默認參數的情況下,用一個定義的方法名即可。此時有一個需要注意的就是默認參數的情況,對於原生的事件處理的話,參數就只有一個:事件對象event;而對於自定義事件的話,則是在 emit 的時候傳入的參數是什麼,這個定義的方法被調用的時候的參數也是一一對應的。

2、自定義參數,這個參數有可能是你在HTML上直接寫的`greet("xx")`,也有可能是在特殊上下文中得到的,例如說在 `v-for` 內部,可以傳入當前循環項;這種情況下則是當一段代碼片段來執行的,此時正是因為包裹的函數是有`$event`參數的,所以可以使用這個;你可能還會發現此時還可以這樣寫:`greet(arguments)`,傳入的就是`arguments`對象,把調用定義方法的參數在形式上是可以由多個變為一個的。


以 Vue.1.0.28 為例,雖然 Vue 內部對是否有括弧有不同的處理,但是對於使用者來說和 原生 JavaScript 中 addEventListener 是基本保持一致的;

function eventHandler(event) {}
el.addEventListener("click", eventHandler, false)
v-on:click="eventHandler"

不同點是 event 的樣子。

function eventHandler(event, value) {}
el.addEventListener("click", function (event) {
eventHandler(event, 123)
}, false)
v-on:click="eventHandler($event, 123)"


推薦閱讀:

閱讀vue.js源碼可以從哪幾方面入手?
vue開發的項目,前端寫的.vue文件中的生命周期方法,線上還存在嗎?
jQuery的ajaxSubmit如何實現批量圖片非同步上傳?
除了Bootstrap,有沒有更好的響應式框架用來開發外包項目?

TAG:前端框架 | React | Vuejs | Vuex | vue-router |