一、书写规范

v-on:事件.修饰符="方法",可简写成“ @事件.修饰符="方法" ”
方法内联: 把方法直接写在标签内。如
<button @click="()=>{return count++}">Add</button>方法外联: 把方法写在标签外的逻辑部,标签内直接调用方法。如
<button @click="xxx(参数)">Add</button>
如果不用传递参数,可使用引用写法,如
<button @click="xxx">Add</button>

二、事件

有18类85个事件,常用的几类有:
系统事件Event、
鼠标事件MouseEvent、
键盘事件KeyboardEvent、
焦点事件FocusEvent、
拖动事件DragEvent、
输入事件InputEvent、
滚轮事件WheelEvent、
文件事件UiEvent、
不常用的几类有:CSS事件AnimationEvent、复制剪切事件ClipboardEvent、进度事件ProgressEvent、URL锚事件HashChangeEvent、导航事件PageTransitionEvent、粘贴事件ClipboardEvent、历史记录事件PopStateEvent、Web存储区事件StorageEvent、触摸事件TouchEvent、CSS转换事件TransitionEvent。

三、修饰符

(一)事件执行修饰符

这类修饰符控制事件的执行顺序及是否执行的问题。

1、capture捕获修饰符

概念

  • 父被子触发: 当DOM嵌套时,子在父的体内,任何对子的操作都会被父捕捉到,触发父的事件。
  • 冒泡与捕获: 当父被子触发时,先执行子再向上执行父叫冒泡,先执行父再执行子叫捕获。冒泡与捕获是父被子触发后的执行顺序问题。
  • capture 捕获修饰符: js默认向上执行冒泡,capture修饰符可改变为向下执行捕获。

冒泡与捕获混合
当冒泡与捕获混合在一起时,先执行捕获队列(捕获队列从上向下执行),再执行冒泡队列(冒泡队列从下向上执行)。如下,先执行capture队列[一,三],capture队列从上向下(一>三);再执行冒泡队列[二,四],冒泡队列从下向上(四>二)。最后的排序:一>三>四>二。

<template>
  <div  @click.capture="yi">
    我是一
     <div  @click="er">
       我是二
       <div  @click.capture="sa">
         我是三
         <div  @click="si">
         我是四
         </div>
       </div>
     </div>
  </div>
 </template>
 <script setup>
   const yi=function(){console.log('我是一')}  
   const er=function(){console.log('我是二')}  
   const sa=function(){console.log('我是三')}
   const si=function(){console.log('我是四')} 
 </script>
2、stop阻断

冒泡与捕获是解决执行顺序问题,但如果要避免被子触发,则需要使用stop阻断修饰符。
stop的作用: 把stop放在子标签上,就会使事件到子为止,阻断事件向上触发。
stop的局限性:

  • 只对冒泡父有效,捕获父无效;
  • 除避免自已被子触发外,还会使自已的上级标签也被阻断触发;
  • 必须依借助子标签来放置阻断符。
3、self排除

为了解决stop的局限性,推出了self排除修饰符,他不必借助子就能完成避免被子触发。
self的作用: 把self放在自已身上,把自已排除在触发队列外,避免受到子的触发。
self的局限性 : self的作用只限于自已,上级标签不会被阻断会继续被触发执行。
stop还是self: 两个修饰符都能避免受子的触发,但都有最适合的场景,如果是多级标签需要避免就用stop,如果是一个标签需要避免那就self。

4、prevent 阻止默认事件

有些DOM含有默认事件,不需要指令也会发生。

  • 超链接(href="#")自动跳转
  • 右键单击弹出菜单
  • from表单提交事件(当表单下的button或input标签的type属性为设置为submit,点击时from会发生提交事件)

prevent可以阻止默认事件的发生。阻止超链接跳转:click.prevent;阻止右键菜单:contextmenu.prevent;阻止表单提交:from标签submit.prevent(不是在按钮上而是from标签上)。

5、passive 默认事件立即执行

当同时存在指令事件和默认事件时,通常是先执行指令事件再执行默认事件 ,如果代码事件耗时太长 ,默认事件就会卡顿感 ,passive会使默认事件先执行,以减少卡顿(滚动事件常用)。

6、once 自身只执行一次

只执行一次 ,执行之后不再执行,即使被子触发也是只执行一次。

(二)鼠标事件修饰符

只限鼠标事件的修饰符:.left/.right/.middle。
鼠标事件还需同时按下鼠标左、右、中键才会触发。
鼠标、键盘事件通用修饰符:.ctrl/.alt/.shift/.meta。
鼠标、键盘事件还需同时按下键盘的ctrl、alt、shift、meta键
有的键盘会标明meta键,没有标明meta键时:Mac 键盘是 (⌘)、 Windows 键盘是(⊞)、 Sun 键盘是 (◆)。

(三)键盘事件修饰符

每个键都有键名,所有的键名都可以用作键盘事件的修饰符。
字母键: 键名是小写的字母
数字键: 键名是数字(主键区与小键区的数字都使用此名)
双符号键: 键名是下行符号
鼠标、键盘事件通用修饰符:.ctrl/.alt/.shift/.meta
功能键: 如下一些功能键的键名

  • 回车 => enter
  • 删除 => delete (删除和退格都使用此别名)
  • 退出 => esc
  • 空格 => space
  • 换行 => tab (特殊,因为tab会切换到别的DOM,每次使用都要手动选定。keydown还好,只需选定本身,而keyup要选定前一个DOM,难度更大)
  • 上 => up
  • 下 => down
  • 左 => left (键盘的左,与鼠标的左修饰符同名,但不是同一物)
  • 右 => right(与鼠标的修饰符同名,但不是同一物)

可通过如下方法查询键名:

<template>
<input type="text"  @keyup="sa">
<template>
<script setup>
  const sa=function(e){console.log(e.key)}
</script>

查询到的键名大写字母要改成小写,如果中间的字母是大写,改成小写还要在中间加 - 号(短横线命名)

(四)exact 排它键修饰符

排除所有的键,如果有其他键被按下,果断不执行,如下:没有任何按键被按下,才会执行。

<button @click.exact="onClick">A</button>

不能排除身前修饰符键,因身前修饰符键会先执行,如下:

<button @click.ctrl.exact="onCtrlClick">A</button>

在"ctrl"被按下时,如果还有其它按键被按下,click事件不被执行.

(五)v-model特殊修饰符

v-model不是事件,但也可以使用修饰符,三个v-model修饰符如下
.lazy: 确定输完才触发(也就是说只有光标离开input输入框或enter回车后,绑定的值才会改变)
.number: input输入的内容为字符串类型,即使你输入的是数字也会是字符串类型,number修饰符能把你输入的数字保存为Number类型
.trim: 自动过滤用户输入的首尾空格赋给绑定的变量
使用效果如下:

<template>
<input v-model.lazy="msg" />
<h1>{{msg}}</h1>
<input v-model.number="val" />
<h1>我的类型是{{typeof(val)}}</h1>
<input v-model.trim="text" />
<h1>我后不会有空格{{text}}我前不会有空格</h1>
</template>
 <script setup>
import { ref } from 'vue';
   const msg=ref() 
   const val=ref() 
   const text=ref()
 </script>

(六)多条修饰符的执行

排在先的先执行
如:click.prevent.self,先执行prevent,整个区域(子和父)都受prevent影响,阻止了父与子的默认行为“跳转”,点击子和父都不会跳转;再执行self,将自已排除在子事件之外,避免受到子的事件触发
如:click.self.prevent,先执行self,将自已排除在子事件之外,再执行prevent,因自已排除在子事件之外,此时的prevent只作用于自已,子的默认行“跳转”不受影响,点击子会跳转,点击自已不会跳转。
如下:

<template>
  <a href="/1#" @click.self.prevent="yi">我会跳转到1#<div >div</div></a>
  <a href="/#" @click.prevent.self="yy">我不会跳转到# <div >div</div></a>       
</template>
<script setup>
  const yi=function(){console.log('我是一')}  
  const yy=function(){console.log('我是二')}  
</script>

四、事件对象event

1、事件对象传递

自动传递

事件会自动向外联函数传递一个名为“event”的事件对象(不必通过实参传递),在函数中不需设置形参接收,在函数体内用“event”专有名词即可直接使用此事件对象。

手动传递

调用方式传递一个名为$event的实参(注意实参前面的$),在函数中需设置形参接收,在函数体内用形参使用此事件对象。如@click="xxx($event)"

自动手动共存

当采用调用方式传递了名为$event的实参时,自动手动传递在函数体内并存,可以使用形参也可以使用“event”专有名词来使用事件对象。如形参名也为event,会替换自动接收的对象event。

<template>
    <button @click="dd">uuu</button>
    <button @click="dd($event)">uuu</button>
</template>
<script setup>
    function dd(evt){console.log(event,evt)}
</script>

2、event事件对象

事件对象概念

事件对象包装着一系列的事件状态,如事件发生的DOM信息、键盘按键的状态、鼠标的位置、鼠标按钮的状态等。
对象详解 event 对象

event对象常用属性

type: 事件的类型,如onlick中的click,如event.type可获得事件的类型
target: 事件源,就是发生事件的元素,如event.target可获得事件源对象

子属性target常用下级属性

textContent: 获取文本内容,如:event.target.textContent可获得事件作用标签的文本
nodeName/tagName: 获取节点名称,如event.target.tagName 可获得作用标签的名称
parentNode: 获取父级节点对象
children: 获取子节点数组,children[]通过key值可获取相对应的子节点对象

五、空事件(不带方法的事件)

如:<form @click></form>点击事件不带处理方法。
空事件不带修饰符将毫无意义,有些修饰符能使空事件发挥强大作用。如在子的空事件加stop修饰符,子空间内将不会触发父事件。
如在空事件加prevent修饰符,将不会触发默认事件。
如在空事件加passive修饰符,默认事件立即执行。
如在<a>标签加@click.self.prevent,可使点击子跳转,点击自已不跳转。



1、杂记 反单引号
普通引号内不能放置变量,反单引号内可以可放置变量,变量需要用 ${}包裹。如下:

<script setup>
import { ref } from 'vue'
const name = ref('变量')
alert(`我可以放置${name.value}!`)    
alert('我不可以放置 ${name.value}!')  
</script>

2、杂记 实参与形参
在声明函数时,可以在函数名称后面的小括号中放置形参,在调用函数时,需要传递相应的参数,这些参数被称为实参。
形参只是占位符,无实际意义。实参可以是基础数据类型、数组、对象、变量、函数。
形参和实参的匹配问题:
实参个数等于形参个数:输出正确结果
实参个数多以形参个数:只取到形参的个数
实参个数小于形参个数:未传数值的形参定义为undefined(形参的默认值为undefined)
自定义缺省实参:
js的默认缺省实参值为undefined,可以自定缺省实参值,方式如下:
function get(a='没传实参就用我吧') {alert(a)},get()调用时没实参会打印自定义的缺省实参'没传实参就用我吧'。