原文地址javascript
你說你是搞前端的,那麼你確定就知道事件,知道事件,你就確定知道 event 對象吧?各類的庫、框架多少都有針對 event 對象的處理。好比 jquery,經過它內部進行必定的封裝,咱們開發的時候,就無需關注 event 對象的部分兼容性問題。最典型的,若是咱們要阻止默認事件,在 chrome 等瀏覽器中,咱們可能要寫一個:php
event.preventDefault();
而在 IE 中,咱們則須要寫:css
event.returnValue = false;
多虧了 jquery ,跨瀏覽器的實現,咱們統一隻須要寫:html
event.preventDefault();
兼容?jquery 內部幫咱們搞定了。相似的還有好比阻止事件冒泡以以及事件綁定(addEventListener / attachEvent)等,簡單到不少的後端都會使用 $('xxx').bind(...),這不是咱們今天的重點,咱們往下看。前端
咱們知道,相比於 jquery,vue 的事件綁定能夠顯得更加直觀和便捷,咱們只須要在模板上添加一個 v-on 指令(還能夠簡寫爲 @),便可完成相似於 $('xxx').bind 的效果,少了一個利用選擇器查詢元素的操做。咱們知道,jquery 中,event 對象會被默認當作實參傳入處處理函數中,以下:vue
$('body').bind('click', function (event) { console.log(typeof event); // object });
這裏直接就獲取到了 event 對象,那麼問題來了,vue 中呢?java
<div id="app"> <button v-on:click="click">click me</button> </div> ... var app = new Vue({ el: '#app', methods: { click(event) { console.log(typeof event); // object } } });
這裏的實現方式看起來和 jquery 是一致的啊,可是實際上,vue 比 jquery 要要複雜得多,jquery 官方也明確的說,v-on
不簡單是 addEventListener
的語法糖。在 jquery 中,咱們傳入到 bind 方法中的回調,只能是一個函數表類型的變量或者一個匿名函數,傳遞的時候,還不能執行它(在後面加上一堆圓括號),不然就變成了取這一個函數的返回值做爲事件回調。而咱們知道,vue 的 v-on
指令接受的值能夠是函數執行的形式,好比 v-on:click="click(233)"
。這裏咱們能夠傳遞任何須要傳遞的參數,甚至能夠不傳遞參數:jquery
<div id="app"> <button v-on:click="click()">click me</button> </div> ... var app = new Vue({ el: '#app', methods: { click(event) { console.log(typeof event); // undefined } } });
咦?個人 event 對象呢?怎麼不見了?打印看看 arguments.length 也是 0,說明這時候確實沒有實參被傳入進來。T_T,那咱們若是既須要傳遞參數,又須要用到 event 對象,這個該怎麼辦呢?git
翻看 vue 文檔,不難發現,其實咱們能夠經過將一個特殊變量 $event 傳入到回調中解決這個問題:chrome
<div id="app"> <button v-on:click="click($event, 233)">click me</button> </div> ... var app = new Vue({ el: '#app', methods: { click(event, val) { console.log(typeof event); // object } } });
好吧,這樣看起來就正常了。
簡單總結來講:
2、烏龍
前面都算是鋪墊吧,如今真正的烏龍來了。
翻看小夥伴兒的代碼,偶然看到了相似下面的代碼:
<div id="app"> <button v-on:click="click(233)">click me</button> </div> ... var app = new Vue({ el: '#app', methods: { click(val) { console.log(typeof event); // object } } });
看到這一段代碼,個人心裏是崩潰的,丟進 chrome 裏面一跑,尼瑪還真能夠,打印 arguments.length,也是正常的 1。尼瑪!這是什麼鬼?毀三觀啊?
既沒有傳入實參,也沒有接收的形參,這個 event 對象的來源,要麼是上級做用鏈,要麼。。。是全局做用域。。。全局的,不由想到了 window.event
。再次上 MDN 確認了一下,果真,window.event,ie 和 chrome 都在 window 對象上有這樣一個屬性: