如何定義事件
在 Vue 中,可以使用 v-on 指令來綁定事件監聽器。
下面是一個示例,在點擊按鈕時觸發事件處理程序:
<template>
<div>
<button v-on:click="incrementCounter">{{ counter }}</button>
</div>
</template>
<script>
export default {
data() {
return {
counter: 0
}
},
methods: {
incrementCounter() {
this.counter++
}
}
}
</script>
在上面的例子中,點擊按鈕時會觸發 incrementCounter 方法,然后將計數器增加 1。
還可以使用縮寫語法來綁定事件監聽器,如下所示:
<button @click="incrementCounter">{{ counter }}</button>
其他常見的監聽事件
除了 click 事件之外,Vue.js 中還有許多其他可供監聽的事件,還包括:
- input:當用戶在輸入框中輸入時觸發。
- submit:當表單被提交時觸發。
- focus:當元素獲得焦點時觸發。
- blur:當元素失去焦點時觸發。
- change:當元素的值改變時觸發,通常用于 select 和 input[type="checkbox"]。
- keydown:當按下鍵盤上的任意按鍵時觸發。
- keyup:當松開鍵盤上的任意按鍵時觸發。
- mouseenter:當鼠標指針移動到元素上時觸發。
- mouseleave:當鼠標指針移出元素時觸發。
- mousemove:當鼠標指針在元素上移動時觸發。
- mousedown:當鼠標按鈕被按下時觸發。
- mouseup:當鼠標按鈕被松開時觸發。
下面針對這些事件,分別配上案例,方便大家進行理解
1、input事件
當用戶在輸入框中輸入時觸發。可以在 input 標簽上直接綁定 v-on:input 事件,并在事件處理程序中執行相應的操作
<template>
<div>
<input v-on:input="onInput" placeholder="Enter Something">
<p>{{ message }}</p>
</div>
</template>
<script>
export default {
data() {
return {
message: ''
}
},
methods: {
onInput(event) {
this.message = event.target.value
}
}
}
</script>
2、submit事件
當表單被提交時觸發。可以在 form 標簽上直接綁定 v-on:submit 事件,并在事件處理程序中執行相應的操作。
<template>
<div>
<form v-on:submit.prevent="onSubmit">
<input type="text" v-model="message">
<button type="submit">Submit</button>
</form>
<p>{{message}}</p>
</div>
</template>
<script>
export default {
data() {
return {
message: ''
}
},
methods: {
onSubmit() {
alert('Form submitted!')
}
}
}
</script>
3、focus事件
當元素獲得焦點時觸發。可以在元素標簽上直接綁定 v-on:focus 事件,并在事件處理程序中執行相應的操作
<template>
<div>
<input v-on:focus="onFocus" placeholder="Enter Something">
</div>
</template>
<script>
export default {
methods: {
onFocus() {
alert('Input focused!')
}
}
}
</script>
4、blur事件
當元素失去焦點時觸發。可以在元素標簽上直接綁定 v-on:blur 事件,并在事件處理程序中執行相應的操作
<template>
<div>
<input v-on:blur="onBlur" placeholder="Enter Something">
</div>
</template>
<script>
export default {
methods: {
onBlur() {
alert('Input blurred!')
}
}
}
</script>
5、change事件
當元素的值改變時觸發,通常用于 select 和 input[type="checkbox"]。可以在元素標簽上直接綁定 v-on:change 事件,并在事件處理程序中執行相應的操作
<template>
<div>
<select v-on:change="onChange">
<option value="option1">Option 1</option>
<option value="option2">Option 2</option>
<option value="option3">Option 3</option>
</select>
<p>Selected: {{ selectedOption }}</p>
</div>
</template>
<script>
export default {
data() {
return {
selectedOption: ''
}
},
methods: {
onChange(event) {
this.selectedOption = event.target.value
}
}
}
</script>
6、keydown事件
當按下鍵盤上的任意按鍵時觸發。可以在元素標簽上直接綁定 v-on:keydown 事件,并在事件處理程序中執行相應的操作
<template>
<div>
<input v-on:keydown="onKeydown" placeholder="Press a key">
</div>
</template>
<script>
export default {
methods: {
onKeydown(event) {
alert(`Key pressed: ${event.key}`)
}
}
}
</script>
7、mouseenter事件
@mouseenter 事件是在鼠標指針移動到元素上方時觸發。
<template>
<div>
<button @mouseenter="mouseEnter">Hover me</button>
</div>
</template>
<script>
export default {
methods: {
mouseEnter() {
console.log("Mouse entered button");
}
}
};
</script>
上面的示例中,當用戶將鼠標移動到按鈕上時,會在控制臺打印 "Mouse entered button" 。
由于 mouseleave,mousemove,mousedown,mouseup 這幾個事件都比較類似,這里我就不舉例子進行展開介紹了。
聊一聊 Vue 的響應式
Vue.js 是一個 JAVAScript 框架,它采用數據驅動和組件化的思想,通過數據響應式來更新視圖。
數據響應式是 Vue 的核心機制之一,它會在 Vue 實例創建時對數據進行觀察,當數據發生變化時自動更新視圖。
代碼示例:
<template>
<div>
<p>{{ message }}</p>
<button @click="changeMessage">change message</button>
</div>
</template>
<script>
export default {
data() {
return {
message: 'Hello Vue'
}
},
methods: {
changeMessage() {
this.message = 'Hello World'
}
}
}
</script>
在這個例子中,我們在模板中使用了雙括號語法來渲染 message 屬性的值。當我們點擊按鈕時,會調用 changeMessage 方法,改變 message 的值,由于 Vue 采用了數據響應式,所以會自動更新視圖,使得 p 標簽中的文本也變成 “Hello World”。
那么如何理解Vue背后的響應式邏輯呢?
當我們在 Vue 實例中定義了 data 屬性時,Vue 會對這些數據進行觀察。當我們給 data 中的屬性賦值時,Vue 會自動觸發 setter,并在 setter 中進行依賴收集和派發更新。
依賴收集是 Vue 實現數據響應式的關鍵。當我們在模板中使用了某個數據,Vue 會在渲染過程中自動為這個數據建立一個依賴,并將其加入到相應的依賴收集器中。當數據發生變化時,Vue 會根據依賴收集器中的依賴關系,自動更新相應的視圖。
在上面的代碼中,我們在模板中使用了 {{ message }} 來渲染 message 屬性的值,Vue 會在渲染過程中自動將 {{ message }} 與 message 屬性建立依賴關系。當我們點擊按鈕時,會調用 changeMessage 方法,改變 message 的值,Vue 會根據依賴關系,自動更新 {{ message }} 所在的視圖。
數據響應式系統是 Vue.js 數據驅動視圖的基礎,它能使得 Vue.js 具有高度的可維護性和可擴展性。
延伸閱讀:Vue2 底層響應式實現邏輯
也許你會好奇,Vue 是如何實現響應式的,那么我們先簡單的聊聊 Vue2 底層的代碼是如何實現響應式的,感興趣的可以了解下。
Vue 的響應式系統的實現主要基于 Object.defineProperty() 這個 JavaScript 內置函數。在創建 Vue 實例時,Vue 會遍歷 data 選項中的所有屬性,使用 Object.defineProperty() 為它們定義 getter 和 setter。
在這里介紹一下Object.defineProperty的用法:
var obj = {};
Object.defineProperty(obj, 'name', {
value: 'Jack',
writable: true,
configurable: true,
enumerable: true
});
console.log(obj.name) //'Jack'
Object.defineProperty() 函數接受三個參數:對象、屬性名、屬性描述符。屬性描述符是一個對象,可以設置屬性的一些特性,如 value、writable、configurable、enumerable 等。
Vue 會在每個響應式屬性上定義一個 getter 和一個 setter,來攔截對該屬性的讀寫操作。當獲取屬性值時,調用的是 getter;當修改屬性值時,調用的是 setter。
Vue 的 setter 中會對新值進行檢測,如果發現新值和舊值不一樣,就會觸發相應的更新操作。
Vue 使用了一個叫做 Dep 的依賴管理器,來維護響應式數據與視圖更新之間的關系。Dep 類負責維護一個依賴列表,其中包含了所有讀取該屬性的 Watcher。當 setter 被調用時,會觸發 Dep 的 notify() 方法,通知所有 Watcher 更新。
Watcher 的作用是監聽響應式數據的變化,并觸發視圖更新。它是 Vue 中重要的組成部分之一。
在 Vue 中,視圖和響應式數據是一一對應的,每個響應式數據都對應著一個或多個 Watcher。當響應式數據發生變化時,Watcher 會被觸發,從而更新視圖。
Watcher 的實現細節較為復雜,但大致流程如下:
- 在 Vue 實例創建時,為每個視圖綁定的響應式數據創建一個 Watcher。
- Watcher 會在它所監聽的響應式數據上注冊一個 Dep。
- 當響應式數據發生變化時,會觸發 Dep 的 notify() 方法,從而通知所有 Watcher 更新。
- Watcher 會調用自己的 update() 方法更新視圖。
Watcher 的實現細節較為復雜,下面是一個簡化版的 Watcher 類的示例代碼,幫助理解其實現原理:
class Watcher {
constructor(vm, key, cb) {
this.vm = vm
this.key = key
this.cb = cb
// 將當前 Watcher 實例指向 Dep.target
// 這樣 Dep 就能夠收集到這個 Watcher
Dep.target = this
this.vm[this.key] // 觸發 getter,收集依賴
Dep.target = null
}
update() {
this.cb.call(this.vm, this.vm[this.key])
}
}
這個例子中,Watcher 類包含了三個屬性:vm、key、cb。vm 是 Vue 實例,key 是響應式數據的名稱,cb 是更新視圖的回調函數。
在構造函數中,Watcher 會將自己設置為 Dep.target,并讀取 vm[key]。這樣,在 vm[key] 的 getter 中就能夠收集到這個 Watcher。
update() 方法會在響應式數據發生變化時被調用,更新視圖。
Watcher 類還包含其他一些方法,如 addDep()、depend()等,用于維護與 Dep 之間的關系,可以參考 Vue 源碼來了解這些方法的具體實現。
希望這些資料能夠幫助您更好的理解 Vue 的響應式系統的實現。
延伸閱讀:Vue3 響應式的實現邏輯
Vue 3 的響應式系統與 Vue 2 的響應式系統有一些不同之處。
Vue 3 引入了一種新的響應式實現方式,叫做 "Proxy based observation"。它使用了 JavaScript 內置的 Proxy 對象來實現響應式,而不再使用 Object.defineProperty()。
使用 Proxy 對象可以更簡單地實現響應式,并且性能更優,代碼實現更簡潔。
舉個例子,在 Vue 2 中,我們可以這樣創建一個響應式對象:
let data = { count: 0 }
Object.defineProperty(data, 'count', {
get() {
console.log('count get')
return count
},
set(newValue) {
console.log('count set')
count = newValue
}
})
而在 Vue 3 中,我們可以這樣創建響應式對象:
let data = reactive({ count: 0 })
function reactive(obj) {
return new Proxy(obj, {
get(target, key, receiver) {
console.log(`get ${key}`)
return Reflect.get(target, key, receiver)
},
set(target, key, value, receiver) {
console.log(`set ${key}`)
return Reflect.set(target, key, value, receiver)
}
})
}
在Vue3中,還引入了一個叫做"reactivity"的新概念,用于描述一組可響應數據,而不再依賴于組件實例。這樣可以讓響應式系統更加靈活,更易于實現自定義組件。
總的來說, Vue 3 的響應式系統使用了 JavaScript 內置的 Proxy 對象,并引入了新的 reactivity 概念,提高了響應式系統的靈活性和性能。在 Vue 3 中,每個組件實例都有自己的響應式系統,而不再像 Vue 2 中那樣共用一個全局的響應式系統。這樣可以更好地支持復雜的組件結構和高性能的響應式系統。
另外,Vue 3 中的響應式系統還支持對 Map 和 Set 等新的數據類型的響應式,這在 Vue 2 中是不支持的。
在 Vue 3 中,響應式系統與虛擬 DOM 結合更緊密,更易于實現高性能的組件。Vue 3 中還引入了新的 Composition API,可以更靈活地編寫組件,更好地復用和組合組件邏輯。
總之,Vue 3 的響應式系統是基于 JavaScript 內置的 Proxy 對象實現,更加靈活高效,并支持新的數據類型和更好的組件編寫方式。
結束
今天的分享就到這里,本篇文章我們一起學習了如何在 Vue 中定義事件 ,并且介紹了常用的事件。以及什么是響應式,以及 Vue 底層是如何實現響應式的,并對 Vue2 和 Vue3 的實現方式和差異進行了介紹。下一篇文章,我將繼續介紹 Vue 其他方面的相關內容,比如計算屬性 Computed 和 Watch 屬性,敬請期待。