李恒道 发表于 2022-3-1 18:46:52

[油猴脚本开发指南]事件处理

# 监听事件

我们可以使用v-on监听dom事件,执行对应的js代码,

可以使用v-on:click='methodName'或@click="methodName"

二者等价,后者是前者的语法糖

```
Vue.createApp({
data() {
    return {
      counter: 0
    }
}
}).mount('#basic-event')
```

```js
<div id="basic-event">
<button @click="counter += 1">Add 1</button>
<p>The button above has been clicked {{ counter }} times.</p>
</div>

```

![图片.png](data/attachment/forum/202203/01/184242aleeysw42v0plwr8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

# 事件处理方法

之前我们简单调用了一小段js代码,可以调用对应的methods来执行更复杂的操作

```js
Vue.createApp({
data() {
    return {
      name: 'Vue.js'
    }
},
methods: {
    greet(event) {
      // `methods` 内部的 `this` 指向当前活动实例
      alert('Hello ' + this.name + '!')
      // `event` 是原生 DOM event
      if (event) {
      alert(event.target.tagName)
      }
    }
}
}).mount('#event-with-method')
```

```js
<div id="event-with-method">
<!-- `greet` 是在下面定义的方法名 -->
<button @click="greet">Greet</button>
</div>

```

我们也可以传入一些参数



```js
<div id="event-with-method">
<!-- `greet` 是在下面定义的方法名 -->
<button @click="greet("Hello")">Greet</button>
</div>
```

# 访问原生dom事件

点击会产生一个原生dom事件

如果我们写@click='greet'

则等价于

greet($event)

这个$event就是原生的dom事件,如果我们传入了参数

则需要greet('Hello',$event)

显示传入$event才可以传入

为什么必须是$event,因为Vue实际在调用的外部包裹了一个函数,其变量名强制设定为了

$event

相当于

function Vue封装函数($event){

greet('Hello',$event)

}

# 多事件处理

我们可以同时绑定多个事件,使用逗号分割

```js
<!-- 这两个 one() 和 two() 将执行按钮点击事件 -->
<button @click="one($event), two($event)">
Submit
</button>

```

# 事件修饰符

在常见的代码编写之中,我们经常需要调用preventDefault或stopPropagation等函数

preventDeafult阻止了元素的默认行为

如我们点击了a标签链接,通过调用该函数,可以禁止打开链接

stopPropagation阻止了事件的冒泡

如存在

```js
<div><p>click</p></div>
```

当我们点击click会向上冒泡,事件的上级也会接收到click事件

当我们调用stopPropagation,则会停止冒泡,不会继续向上级传播

我们可以在函数中调用,但是vue提供了一个更好的方式,就是事件修饰符



```js
    .stop
    .prevent
    .capture
    .self
    .once
    .passive
```

我们可以书写如下的代码

```js
<!-- 阻止单击事件继续冒泡 -->
<a @click.stop="doThis"></a>

<!-- 提交事件不再重载页面 -->
<form @submit.prevent="onSubmit"></form>

<!-- 修饰符可以串联 -->
<a @click.stop.prevent="doThat"></a>

<!-- 只有修饰符 -->
<form @submit.prevent></form>

<!-- 添加事件监听器时使用事件捕获模式 -->
<!-- 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 -->
<div @click.capture="doThis">...</div>

<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div @click.self="doThat">...</div>

```

capture则是在元素自身触发之前

会由上级元素一路捕获到点击元素,而capture相当于在捕获期间触发对应的函数

self则是必须是点击自身元素才可以触发对应函数

# 修饰符顺序问题

```js
使用修饰符是按顺序进行执行的,如@click.prevent.self会阻止子元素以及自身的默认行为
而@click.self.prevent,只阻止自身,而不阻止子元素的默认行为
```

举个例子

```js
来源https://www.oschina.net/question/1785591_2273843?sort=default
    <div @click="alert(1)">
      <a href="/#" @click.prevent.self="alert(2)">
      <div @click="alert(3)"></div>
      </a>
    </div>
```

这里当我们点击a标签或子元素div标签,都会触发prevent,这时候都会阻止默认行为

如果点击div3

则会触发alert(3)

阻止默认行为,非自身点击,不提示alert(2)

然后提示alert(1)

如果点击div2

阻止默认行为,自身点击,提示alert(2)

然后提示alert(1)

但是如果是.self.prevent

当点击子元素的时候,没有通过.self的运算符,所以不会阻止原生事件触发

只有点击自身元素的时候才会进行事件触发

如果你对两者进行比较,相信发现了区别,修饰符的先后顺序决定了执行结果,vue也是这样处理的

相当于在编译的时候prevent.self变成了

function(){

prevent函数调用

self函数调用

我们的函数调用()

}

我们也有只允许点击一次的语法糖

```js
<a @click.once="doThis"></a>
```

注意,原生修饰符只能用于dom元素,而once可以应用于组件。相当于它只是一个逻辑上的语法修饰符,而与原生无关

# .passive运算符

这里我没有特别理解,大概查了一下资料,可能与事实存在一定的出入

passive用于保证不调用默认阻止事件

```js
<!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发,   -->
<!-- 而不会等待 `onScroll` 完成,                  -->
<!-- 以防止其中包含 `event.preventDefault()` 的情况-->
<div @scroll.passive="onScroll">...</div>

```

通过.passfive保证不调用阻止事件,其默认行为将会立即触发

而不会等待onScroll执行后再触发默认执行事件

该修饰符可以提升移动端的性能。

注意passive不能与prevent一起使用,因为语义冲突

# 按键修饰符

监听按键修饰符的时候,我们需要检查特定的按键

Vue允许为@或v-on添加按键修饰符

```js
<!-- 只有在 `key` 是 `Enter` 时调用 `vm.submit()` -->
<input @keyup.enter="submit" />

```

只有按enter的时候才会调用对应函数

可以将键盘事件暴露的任意有限键名转换为横杠写法来作为修饰符

键盘事件可以参考https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values

```js
<input @keyup.page-down="onPageDown" />

```

当事件名为PageDown的时候将会被调用

# 按键别名

Vue还对常用的键提供了别名

```js
    .enter
    .tab
    .delete (捕获“删除”和“退格”键)
    .esc
    .space
    .up
    .down
    .left
    .right
```

# 系统修饰键

可以用该修饰符来实现按下对应按键才触发监听器

```js
    .ctrl
    .alt
    .shift
    .meta
```

例如

```js
<!-- Alt + Enter -->
<input @keyup.alt.enter="clear" />

<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">Do something</div>

```

# tips

修饰符与常规按键不同,在于keyup事件连用

事件触发的时候修饰键必须按下,

只有按下Ctrl的时候触发其他按键

才可以触发keyup.ctrl

单释放ctrl不会触发事件

# .exact修饰符

使用exact可以更精准的控制组合事件

```js
<!-- 即使 Alt 或 Shift 被一同按下时也会触发 -->
<button @click.ctrl="onClick">A</button>

<!-- 有且只有 Ctrl 被按下的时候才触发 -->
<button @click.ctrl.exact="onCtrlClick">A</button>

<!-- 没有任何系统修饰符被按下的时候才触发 -->
<button @click.exact="onClick">A</button>

```

# 鼠标按钮修饰符

```js
    .left
    .right
    .middle
```

会限制函数仅处理特定的鼠标按钮

# 结语

撒花~

王一之 发表于 2022-3-1 18:57:05

ggnb!高产两节!

李恒道 发表于 2022-3-1 19:07:21

王一之 发表于 2022-3-1 18:57
ggnb!高产两节!

还没写完...修饰符方面太碎了
页: [1]
查看完整版本: [油猴脚本开发指南]事件处理