1.理解Vue事件的綁定方式
1.1 原生行內(nèi)事件綁定
說明:
- vue采用行內(nèi)事件綁定的方式.
- 因此在學(xué)習(xí)vue事件綁定方式之前,先回顧一下JS的行內(nèi)事件綁定
- 學(xué)習(xí)中對比vue的行內(nèi)事件綁定和JS原生行內(nèi)事件綁定的不同
示例代碼如下:
<style> .box{ color:red; } .wrap{ color:skyblue; }</style><div id="app"> <h2 id="box" class="box">Hello World</h2> <button onclick="changeColor()">點(diǎn)擊切換顏色</button></div><script> let className = "box" function changeColor(){ if(className =='box'){ box.className = className = "wrap" }else{ box.className = className = "box" } }</script>
注意:
- 這種原生綁定事件方式不常用,因?yàn)轳詈闲蕴?/li>
- onclick屬性值是函數(shù)執(zhí)行字符串,在點(diǎn)擊觸發(fā)后會把這個(gè)字符串強(qiáng)制轉(zhuǎn)為js語句執(zhí)行
vue采用這種方式綁定事件,
原因在于這種綁定方式比較直觀的處理事件的綁定, 省去了大量獲取DOM的操作.
不用擔(dān)心Vue的問題, Vue在采用行內(nèi)事件綁定,內(nèi)部肯定做了大量的優(yōu)化處理
2.v-on(@) 事件的綁定與基本使用
為了讓用戶和你的應(yīng)用進(jìn)行交互,我們可以用 v-on 指令添加一個(gè)事件監(jiān)聽器,通過事件監(jiān)聽器觸發(fā)事件執(zhí)行程序
2.1 v-on指令的認(rèn)識和使用
v-on指令說明
- v-on指令和其他指令一樣,通過v-on綁定事件后,事件屬性值將不再是字符串,而是表達(dá)式
- 因此接班是表達(dá)式就可以在引號中做一些基本的操作
<div id="app"> <h2 class="box">點(diǎn)擊次數(shù): {{ count }}</h2> <!-- 既然click 的值是表達(dá)式,那么我們就可以動態(tài)的拿到vue ,data屬性中的數(shù)據(jù),然后操作--> <button v-on:click="count ">暴擊</button></div><script> const vm = new Vue({ el: "#app", data: { count: 0 } })</script>
示例說明:
- 通過v-on指令綁定click單機(jī)事件
- v-on指定綁定事件的屬性值是表達(dá)式,表達(dá)式中可以直接獲取vue中的數(shù)據(jù)
- 因此可以是表達(dá)式中直接對數(shù)據(jù)進(jìn)行修改
通過上面的說明就能理解,每次點(diǎn)擊都會修改數(shù)據(jù),數(shù)據(jù)的修改觸發(fā)vue響應(yīng)系統(tǒng),進(jìn)而改變頁面顯示
之中直接修改數(shù)據(jù)一般情況下用的比較少,原因在于:
- 通過v-on綁定的事件屬性值雖然是表達(dá)式,但是只能處理單個(gè)表達(dá)式邏輯
- 如果處理復(fù)雜的程序就會有局限性
- 同時(shí)沒發(fā)在引號中使用事件對象,來處理事件的細(xì)節(jié)
因此,通常會選擇在表達(dá)式中綁定vue的方法,將方法作為事件函數(shù)處理
2.2 v-on指定綁定methods方法
調(diào)用在 Vue 實(shí)例中定義的方法
說明:
- 在選項(xiàng)對象屬性methods中定義vue示例的方法
- 通過方法名將vue辦法綁定給事件,作為事件處理函數(shù)使用
示例1:修改上一個(gè)示例,限制點(diǎn)擊次數(shù)
<!-- 限定點(diǎn)擊次數(shù) --><div id="app"> <h2 class="box">點(diǎn)擊次數(shù): {{ count }}</h2> <button v-on:click="handleClick">點(diǎn)擊</button></div><script> const vm = new Vue({ el: "#app", data: { count: 0 }, methods: { handleClick(){ let count = this.count; // 限定顯示最大點(diǎn)擊次數(shù) this.count = Math.min( count,5) } } })</script>
示例2: 翻轉(zhuǎn)消息
<!-- HTML ---><div id="app-5"> <p>{{ message }}</p> <button v-on:click="reverseMessage">逆轉(zhuǎn)消息</button></div><!-- JS ---><script> new Vue({ el: "#app-5", data: { message: 'Hello Vue.js' }, methods: { reverseMessage: function(){ this.message = this.message.split('').reverse().join('') } } })</script>
示例說明:
- 通過示例,當(dāng)按鈕綁定button被點(diǎn)擊時(shí),就會觸發(fā)methods屬性中的的方法,
- 在方法中修改數(shù)據(jù), 當(dāng)數(shù)據(jù)被修改時(shí)觸發(fā)響應(yīng)系統(tǒng), 響應(yīng)系統(tǒng)觸發(fā)視圖的重新渲染,
注意.
methods中方法,不能和data的數(shù)據(jù)重名,因?yàn)閐ata中的數(shù)據(jù)和methods中的方法都會在Vue初始化時(shí)成為Vue示例的屬性或方法
2.3 事件綁定的簡寫方式
<!-- 完整語法 --><button v-on:click="reverseMessage">逆轉(zhuǎn)消息</button><!-- 縮寫 --><button @click="reverseMessage">逆轉(zhuǎn)消息</button>
3. 關(guān)于函數(shù)內(nèi)的this指向問題
3.1 普通函數(shù)this
方法內(nèi)this默認(rèn)指向?qū)嵗龑ο?就可以通過實(shí)例對象處理很多操作
<div id="app"> <!-- 綁定事件觸發(fā)Vue方法 --> <button @click="reversed">按鈕</button></div><script> let vm = new Vue({ el: "#app", data: { msg: "Hello Vue" }, methods: { reversed() { console.log(this) // 實(shí)例對象 } } })</script>
點(diǎn)擊結(jié)果
3.2 箭頭函數(shù)中this
如果改為箭頭函數(shù)為如下寫法:
{ reversed:() => { console.log(this) // 實(shí)例對象 }}
那么我們就將實(shí)例中的方法換成箭頭函數(shù)
<div id="app"> <!-- 綁定事件觸發(fā)Vue方法 --> <button @click="reversed">按鈕</button></div><script> let vm = new Vue({ el: "#app", data: { msg: "Hello Vue" }, methods: { reversed:()=> { console.log(this) // 實(shí)例對象 } } })</script>
點(diǎn)擊結(jié)果:
4. methods方法中不推薦使用箭頭函數(shù)
其實(shí)在上一小節(jié)中了解方法的不同寫法會導(dǎo)致this的不同, 那么就來羅列一下不推薦使用箭頭函數(shù)的原因
4.1 methods不推薦使用箭頭函數(shù)
不推薦使用功能箭頭函數(shù)說明:
1.vue是以數(shù)據(jù)作為驅(qū)動的,數(shù)據(jù)的變化將會觸發(fā)vue響應(yīng)系統(tǒng),同時(shí)更改頁面的渲染結(jié)果,
- vue以數(shù)據(jù)為驅(qū)動,也就是說我們在未來的操作中將大量操作數(shù)據(jù),
- 數(shù)據(jù)被處理為Vue 實(shí)例vm上的屬性,那么我們就需要大量的通過vm對象來調(diào)用數(shù)據(jù)
- 甚至methods的中的方法也會掛在在vm對象上的,
- 因此箭頭函數(shù)會影響我們對于數(shù)據(jù)和方法的獲取,因?yàn)榧^函數(shù)this是window
也正式因?yàn)檫@些原因,我們不推薦方法使用箭頭函數(shù),因?yàn)檫@樣會丟失this指向, 那么我們就不能利用this 來獲取數(shù)據(jù)和其他方法了.
看下面的例子
<div id="app"> <button @click="handleClick">非箭頭函數(shù)中this</button> <button @click="handleClickTwo">箭頭函數(shù)中的this</button></div><script> const vm = new Vue({ el: "#app", data: { msg: "hello" }, methods: { handleClick(){ console.log(this) // vue實(shí)例化對象 }, handleClickTwo: () => { console.log(this) // window 對象 }, } })</script>
這樣我們就會發(fā)現(xiàn)如果我們使用普通函數(shù), 那么要獲取數(shù)據(jù)就很簡單
handleClick(){ console.log(this) // vue實(shí)例化對象 // 利用this 獲取數(shù)據(jù) console.log(this.msg) // 獲取數(shù)據(jù)},
總結(jié):
methods屬性中方法函數(shù)中如果不需要操作Vue實(shí)例上的屬性和方法, 可以使用箭頭函數(shù),
但是一般不推薦使用箭頭函數(shù), 原因
- 一是因?yàn)槲覀冸S時(shí)可能需要在方法中獲取Vue實(shí)例的其他數(shù)據(jù)或其他方法,
- 二是統(tǒng)一的編碼風(fēng)格,總不至于有的用箭頭函數(shù),有的不用吧,
4.2 關(guān)于Vue方法里使用箭頭函數(shù)誤區(qū)
但是我們需要避免一個(gè)誤區(qū):
我們推薦不使用箭頭函數(shù)是methods的方法, 不是說真?zhèn)€Vue項(xiàng)目里都不能使用箭頭函數(shù),
比如我們?nèi)绻诜椒ɡ镞€有函數(shù),在函數(shù)中需要使用vue實(shí)例化對象我們這個(gè)時(shí)候用箭頭函數(shù)會比非箭頭函數(shù)要
例如
<div id="app"> <button @click="handleClick">查看this</button></div><script> const vm = new Vue({ el: "#app", data: { msg: "hello" }, methods: { handleClick(){ console.log(this) // vue實(shí)例化對象 // 延遲修改數(shù)據(jù) // 1.方法內(nèi)使用普通函數(shù),查看普通函數(shù)中this setTimeout(function(){ console.log(this) // window 對象 // 這個(gè)是有要修改數(shù)據(jù),還的使用vm vm.msg = "wrod" }, 1000) // 2.方法內(nèi)使用箭頭函數(shù), 查看函數(shù)內(nèi)this setTimeout(() => { console.log(this) // vue實(shí)例對象 // 這個(gè)是有修改數(shù)據(jù),依然可以使用this this.msg = "wuwei" }, 2000) }, } })</script>
通過示例就能看出,用不用箭頭函數(shù),完全看自己的需求, 而不是說不推薦使用箭頭函數(shù),就整個(gè)Vue項(xiàng)目中一個(gè)箭頭函數(shù)都不用了,
要關(guān)注一下是哪里不推薦使用箭頭函數(shù).
因此:
Vue中是不是用箭頭函數(shù),完全看你自身的情況,千萬不要聽人說Vue不推薦使用箭頭函數(shù),就整個(gè)Vue項(xiàng)目中一個(gè)箭頭函數(shù)都不用, 用不用,看this
5. 關(guān)于方法的事件對象
在調(diào)用方法的時(shí)候有兩種情況,一種是不加括號,一種加括號
<!--不加括號 --><button @click="reversed">點(diǎn)擊</button><!--加括號 --><button @click="reversed()">點(diǎn)擊</button><button @click="reversed(12345)">點(diǎn)擊</button>
那么很明顯使用加括號的方式是為了傳遞參數(shù)給事件函數(shù),
那么我們就來看看不同的事件綁定方式對于事件對象的影響
5.1 不加括號
不加括號的情況下,默認(rèn)第一個(gè)形參就是事件對象
<div id="app"> <!-- 不加括號綁定事件 --> <button @click="reversed">點(diǎn)擊</button></div><script> let vm = new Vue({ el: "#app", data: { msg: "Hello Vue" }, methods: { reversed:(ev)=> { console.log(ev) // 事件對象 } } })</script>
頁面點(diǎn)擊結(jié)果:
5.2 加括號
如果加括號無論你傳不傳實(shí)參,形參默認(rèn)就是要接受你傳遞的實(shí)參
<div id="app"> <!-- 加括號未傳參 --> <button @click="reversed()">點(diǎn)擊</button> <!-- 加括號傳參 --> <button @click="reversed(123)">點(diǎn)擊2</button></div><script> let vm = new Vue({ el: "#app", data: { msg: "Hello Vue" }, methods: { reversed:(ev)=> { console.log(ev) // 事件對象 } } })</script>
點(diǎn)擊后的結(jié)果
事件綁定加括號說明
- 通過示例發(fā)現(xiàn),加括號沒有傳參是,事件函數(shù)的第一個(gè)形參是undefined因?yàn)闆]有接受到實(shí)參
- 如果加括號綁定事件, 事件執(zhí)行傳遞了實(shí)參,那么事件函數(shù)的第一個(gè)形參就是傳遞過來的實(shí)參
那么問題來了,如果我需要傳參時(shí)如何獲取事件對象呢
5.3 綁定事件手動傳遞事件對象
如果加括號就需要手動的傳遞事件對象
<div id="app"> <!-- 手動傳遞事件對象,此時(shí)$event就是事件對象 --> <button @click="reversed($event,123)">點(diǎn)擊</button></div><script> const vm = new Vue({ el:"#app", data:{ msg:"Hello Vue" }, methods: { reversed(ev,num){ console.log(ev) // 事件對象 console.log(num) // 123 } } })</script>
點(diǎn)擊結(jié)果
5.4 默認(rèn)事件對象的變量
同時(shí)還發(fā)現(xiàn): 無論加不加括號,傳不傳參數(shù),在函數(shù)里變量event默認(rèn)是事件對象, 所以不要定義同名變量將其覆蓋就可以了
<div id="app"> <!-- 手動傳遞事件對象,此時(shí)$event就是事件對象 --> <button @click="reversed($event,123)">點(diǎn)擊</button></div><script> const vm = new Vue({ el:"#app", data:{ msg:"Hello Vue" }, methods: { reversed(ev,num){ console.log(event); } } })</script>
點(diǎn)擊顯示結(jié)果
總結(jié):
- 方法寫在methods屬性中
- 事件函數(shù)不需要傳參不加括號, 需要傳參加括號
- 事件函數(shù)無括號,默認(rèn)第一個(gè)參數(shù)是事件對象
- 事件函數(shù)有括號,需要手動傳遞事件對象
- 無論事件函數(shù)有無括號,event變量都是事件對象,前提不能有同名變量覆蓋
版權(quán)聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻(xiàn),該文觀點(diǎn)僅代表作者本人。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如發(fā)現(xiàn)本站有涉嫌抄襲侵權(quán)/違法違規(guī)的內(nèi)容, 請發(fā)送郵件至 舉報(bào),一經(jīng)查實(shí),本站將立刻刪除。