[toc]
>[success] # v-on 知識點
1. 用`v-on`指令監聽 DOM 事件,`v-on`中要處理的邏輯比較復雜,因此不支持直接在`v-on`中直接寫js代碼,例如下面直接使用alert 方法,如果這么寫必須是在`vue`實例對象的`method`中有定義alter方法才行,否則不支js 自帶一些默認方法直接調用
~~~html
<button v-on:click="alert('a')">v-on按鈕</button>
~~~
2. 事件處理器的值可以有兩種表現形式,**內聯事件處理器** 和 **方法事件處理器**
* **內聯事件處理器**,事件被觸發時執行的內聯 JavaScript 語句(最通俗理解,調用方法時候有括號,直接使用以聲明屬性)實際上是將其執行的是一段 `js `代碼
~~~html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="app">
{{count}}
<button @click="count++">內聯</button>
<button @click="add()">內聯</button>
<button @click="addStep(2)">內聯</button>
<button @click="addStep(2);add()">內聯</button>
</div>
<!-- 通過cdn 引入 -->
<script src="https://unpkg.com/vue@next"></script>
<script>
const app = Vue.createApp({
data() {
return {
count: 1,
}
},
methods: {
add() {
this.count++
},
addStep(num) {
this.count += num
},
},
})
app.mount('#app')
</script>
</body>
</html>
~~~
* **方法事件處理器**,一個指向組件上定義的方法的屬性名或是路徑(簡單理解直接方法名字)
~~~html
<!-- `greet` 是上面定義過的方法名 -->
<button @click="greet">Greet</button>
~~~
~~~
data() {
return {
name: 'Vue.js'
}
},
methods: {
greet(event) {
// 方法中的 `this` 指向當前活躍的組件實例
alert(`Hello ${this.name}!`)
// `event` 是 DOM 原生事件
if (event) {
alert(event.target.tagName)
}
}
}
~~~
二者檢測形式:` v-on` 的值是否是合法的 `JavaScript `標識符或屬性訪問路徑來斷定是何種形式的事件處理器。舉例來說,**foo、foo.bar 和 foo['bar'] 會被視為方法事件處理器**,而 **foo() 和 count++ 會被視為內聯事件處理器** 。
>[info] ## 常見使用
~~~html
<!-- 動態事件 -->
<button v-on:[event]="doThis"></button>
<!-- 動態事件縮寫 -->
<button @[event]="doThis"></button>
<!-- 對象語法 -->
<button v-on="{ mousedown: doThis, mouseup: doThat }"></button>
<!-- 一個事件綁定多個方法 -->
<button @click="one($event), two($event)">Submit</button>
~~~
>[danger] ##### 關于event
* 在正常使用js 綁定事件時候,都會獲取到`event`對象
~~~
<button>獲取evnet</button>
document.querySelector('button').onclick = function (event) {
console.log(event) // 打印出 event 對象
}
~~~
* 在 `vue` 中使用 也可以將么`event`對象會傳遞進來,在**內聯事件處理器**和**方法事件處理器** 傳遞形式不同
~~~ html
<!-- 1.默認傳遞event對象 -->
<button @click="btn1Click">按鈕1</button>
<!-- 2.自己的參數和event對象 -->
<!-- 在模板中想要明確的獲取event對象: $event -->
<button @click="btn3Click('zzz', $event)">按鈕3</button>
~~~
~~~
methods: {
// 1.默認參數: event對象
// 總結: 如果在綁定事件的時候, 沒有傳遞任何的參數, 那么event對象會被默認傳遞進來
btn1Click(event) {
console.log('btn1Click:', event)
},
// 2.明確參數+event對象
btn3Click(name, event) {
console.log('btn3Click:', name, event)
},
},
~~~
>[info] ## 事件修飾符
1. `.stop` - 調用 `event.stopPropagation()` 阻止事件冒泡
2. `.prevent` - 調用 `event.preventDefault()`。阻止默認事件從里到外
3. `.capture` - 添加事件偵聽器時使用 `capture `模式。實現捕獲觸發事件的機制從外到里
4. `.self` - 只當事件是從偵聽器綁定的元素本身觸發時才觸發回調。只會阻止自己身上的行為
5. `.{keyAlias}` - 僅當事件是從特定鍵觸發時才觸發回調。(鍵盤簡寫)
6. `.once` - 只觸發一次回調。
7. `.left` - 只當點擊鼠標左鍵時觸發。
8. `.right` - 只當點擊鼠標右鍵時觸發。
9. `.middle` - 只當點擊鼠標中鍵時觸發。
10. `.passive` - { passive: true } 模式添加偵聽器
>[danger] ##### 阻止事件冒泡 -- stop
1. 多個元素嵌套,有層次關系,這些元素都注冊了相同的事件,如果里面的元素事件觸發了,外面的元素的該事件自動的觸發了,注意相同事件(都是點擊事件,中點擊叫做事件)
2. 事件冒泡從里向外
3. 阻止事件冒泡使用stop
~~~ html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.inner {
width: 200px;
height: 200px;
background-color: darkseagreen;
}
</style>
</head>
<body>
<div id="app">
<div class="inner" id="app" @click="divClick">
<input type="button" value="點擊" @click.stop="inputClick" />
</div>
</div>
<!-- 引入vue cdn -->
<script src="https://unpkg.com/vue@next"></script>
<script>
const vm = Vue.createApp({
methods: {
divClick() {
console.log('最外層div')
},
inputClick() {
console.log('最內層div')
},
},
}).mount('#app')
</script>
</body>
</html>
~~~
* 點擊按鈕效果:
~~~
最內層div
~~~
* 如果沒有增加stop
~~~
最內層div
最外層div
~~~
>[danger] ##### 實現捕獲觸發事件的機制 -- capture
1. 冒泡是從向外依次觸發,使用`capture`,就變成了從 **先顯示外面,在顯示里面**
~~~ html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.inner {
width: 200px;
height: 200px;
background-color: darkseagreen;
}
</style>
</head>
<body>
<div id="app">
<div class="inner" id="app" @click.capture="divClick">
<input type="button" value="點擊" @click="inputClick" />
</div>
</div>
<!-- 引入vue cdn -->
<script src="https://unpkg.com/vue@next"></script>
<script>
const vm = Vue.createApp({
methods: {
divClick() {
console.log('最外層div')
},
inputClick() {
console.log('最內層div')
},
},
}).mount('#app')
</script>
</body>
</html>
~~~
* 打印結果
~~~
最外層div
最內層div
~~~
>[danger] ##### .self -- 組織自己的事件行為
1. 只會阻止自己身上的行為 ,像下面的案例當有多層嵌套的時候,只會阻止有self 冒泡行為
2. 官網的第一個提示:使用修飾符時,順序很重要;相應的代碼會以同樣的順序產生。因此,用` @click.prevent.self`會阻止元素本身及其子元素的點擊的默認行為,而 `@click.self.prevent` 只會阻止對元素自身的點擊的默認行為。
~~~ html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.inner {
width: 200px;
height: 200px;
background-color: darkseagreen;
}
</style>
</head>
<body>
<div id="app">
<div class="outer" @click="div2Handler">
<div class="inner" @click.self="div1Handler">
<input type="button" value="戳他" @click="btnHandler" />
</div>
</div>
</div>
<!-- 引入vue cdn -->
<script src="https://unpkg.com/vue@next"></script>
<script>
const vm = Vue.createApp({
methods: {
div1Handler() {
console.log('這是觸發了 inner div 的點擊事件')
},
btnHandler() {
console.log('這是觸發了 btn 按鈕 的點擊事件')
},
div2Handler() {
console.log('這是觸發了 outer div 的點擊事件')
},
},
}).mount('#app')
</script>
</body>
</html>
~~~
* 打印結果
~~~
這是觸發了 btn 按鈕 的點擊事件
這是觸發了 outer div 的點擊事件
~~~
>[danger] ##### 阻止默認事件 -- prevent
1. 例如a標簽默認事件就是點擊跳轉頁面,為了**阻止a標簽的默認事件觸發我們綁定的事件**,可以使用prevent
2. 圖片的默認事件**禁止拖拽**,如果想給圖片設置拖拽效果的話記得做阻止默認行為
~~~ html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style></style>
</head>
<body>
<div id="app">
<a href="www.baidu.com" @click.prevent.once="linkClick">百度</a>
</div>
<!-- 引入vue cdn -->
<script src="https://unpkg.com/vue@next"></script>
<script>
const vm = Vue.createApp({
methods: {
linkClick: function () {
alert(1)
},
},
}).mount('#app')
</script>
</body>
</html>
~~~
* 運行的效果
~~~
1.a標簽不會頁面跳轉,反而點擊后會彈出彈窗顯示1,當下次點擊時候會跳轉a 標簽地址
~~~
>[danger] ##### 阻止默認事件 -- passive
1 . `passive`主要用在移動端的scroll事件,來提高瀏覽器響應速度,提升用戶體驗。因為passive=true等于提前告訴了瀏覽器,`touchstart`和`touchmove`不會阻止默認事件,手剛開始觸摸,瀏覽器就可以立刻給與響應;否則,手觸摸屏幕了,但要等待`touchstart`和`touchmove`的結果,多了這一步,響應時間就長了,用戶體驗也就差了。
~~~
<!-- 滾動事件的默認行為 (即滾動行為) 將會立即觸發, -->
<!-- 而不會等待 `onScroll` 完成, -->
<!-- 以防止其中包含 `event.preventDefault()` 的情況 -->
<div @scroll.passive="onScroll">...</div>
~~~
>[danger] ##### 特定按鍵 .{keyAlias}
[按鍵別名](https://v3.cn.vuejs.org/guide/events.html#%E6%8C%89%E9%94%AE%E5%88%AB%E5%90%8D)
>[info] ## 官方文檔位置
[官方文檔](https://cn.vuejs.org/guide/essentials/event-handling.html#listening-to-events)
[官網事件地址](https://v3.cn.vuejs.org/api/directives.html#v-on)
- 官網給的工具
- 聲明vue2 和 vue3
- 指令速覽
- Mustache -- 語法
- v-once -- 只渲染一次
- v-text -- 插入文本
- v-html -- 渲染html
- v-pre -- 顯示原始的Mustache標簽
- v-cloak -- 遮蓋
- v-memo(新)-- 緩存指定值
- v-if/v-show -- 條件渲染
- v-for -- 循環
- v-bind -- 知識
- v-bind -- 修飾符
- v-on -- 點擊事件
- v-model -- 雙向綁定
- 其他基礎知識速覽
- 快速使用
- 常識知識點
- key -- 作用 (后續要更新)
- computed -- 計算屬性
- watch -- 偵聽
- 防抖和節流
- vue3 -- 生命周期
- vue-cli 和 vite 項目搭建方法
- vite -- 導入動態圖片
- 組件
- 單文件組件 -- SFC
- 組件通信 -- porp
- 組件通信 -- $emit
- 組件通信 -- Provide / Inject
- 組件通信 -- 全局事件總線mitt庫
- 插槽 -- slot
- 整體使用案例
- 動態組件 -- is
- keep-alive
- 分包 -- 異步組價
- mixin -- 混入
- v-model-- 組件
- 使用計算屬性
- v-model -- 自定義修飾符
- Suspense -- 實驗屬性
- Teleport -- 指定掛載
- 組件實例 -- $ 屬性
- Option API VS Composition API
- Setup -- 組合API 入口
- api -- reactive
- api -- ref
- 使用ref 和 reactive 場景
- api -- toRefs 和 toRef
- api -- readonly
- 判斷性 -- API
- 功能性 -- API
- api -- computed
- api -- $ref 使用
- api -- 生命周期
- Provide 和 Inject
- watch
- watchEffect
- watch vs. watchEffect
- 簡單使用composition Api
- 響應性語法糖
- css -- 功能
- 修改css -- :deep() 和 var
- Vue3.2 -- 語法
- ts -- vscode 配置
- attrs/emit/props/expose/slots -- 使用
- props -- defineProps
- props -- defineProps Ts
- emit -- defineEmits
- emit -- defineEmits Ts
- $ref -- defineExpose
- slots/attrs -- useSlots() 和 useAttrs()
- 自定義指令
- Vue -- 插件
- Vue2.x 和 Vue3.x 不同點
- $children -- 移除
- v-for 和 ref
- attribute 強制行為
- 按鍵修飾符
- v-if 和 v-for 優先級
- 組件使用 v-model -- 非兼容
- 組件
- h -- 函數
- jsx -- 編寫
- Vue -- Router
- 了解路由和vue搭配
- vueRouter -- 簡單實現
- 安裝即使用
- 路由懶加載
- router-view
- router-link
- 路由匹配規則
- 404 頁面配置
- 路由嵌套
- 路由組件傳參
- 路由重定向和別名
- 路由跳轉方法
- 命名路由
- 命名視圖
- Composition API
- 路由守衛
- 路由元信息
- 路由其他方法 -- 添加/刪除/獲取
- 服務器配置映射
- 其他
- Vuex -- 狀態管理
- Option Api -- VUEX
- composition API -- VUEX
- module -- VUEX
- 刷新后vuex 數據同步
- 小技巧
- Pinia -- 狀態管理
- 開始使用
- pinia -- state
- pinia -- getter
- pinia -- action
- pinia -- 插件 ??
- Vue 源碼解讀
- 開發感悟
- 練手項目