事件

@Events
事件类型 Classification
包括:鼠标事件、键盘事件等等
常见事件类型
类型 说明
click 鼠标单击
dbclick 鼠标双击
keyup 按下某键并松开
keydown 某键按下
mouseup 鼠标松开
mousedown 鼠标按下
mousemove 鼠标移动
mouseover 鼠标悬停
... ...
Html 原生使用
获取 Element 元素 再分配事件;更多信息,请访问HTML5事件 传统方式事件侦听方式
1. 元素属性形式
<div onclick="alert('hi,there.')">点击我</div>
2. 对象属性形式
let el = document.querySelector('div')
el.onclick = function (e) {
    console.log(e);
    console.log(this);
}
3. 事件侦听方式 - 可以添加多个事件侦听;可以移除事件侦听
el.addEventListener(event-type, event-handle, capture)
el.removeEventListener(event-type, event-handle, capture)
Vue使用 Usage
更多信息,请访问 事件处理 - Event Handling
建议采用模块化开发,可以复用业务;详细信息,请参考 Module
v-on
使用 v-on 指令来监听 DOM 事件,并在事件触发时执行对应的 JavaScript |事件处理函数 handle
<div v-on:click="doSomething"> ... </div>
可简写为 @
<div @click="doSomething"> ... </div>
内联事件
直接操作数据;适合简单逻辑
<div @click="console.log('hi')">console log</div>
单击,count 加1;count 要使用才可以响应;否则仅仅利用 vue devTool 数据无法响应
<div @click="count++">do something</div>
<div>使用数据{{count}}</div>
普通事件
1. 无参
<div @click="doClick">do something</div>
使用具名函数
function doClick() {
  console.log('hello,world');
}
使用匿名函数 - 函数表达式;必须先声明再使用
const doClick = () => {
  console.log('hello,world');
}
2. 携带参数 - 注意单引号和双引号的配对使用
<div @click="doClickPara('18')">do something with para</div>
function doClickPara(para) {
  console.log(para);
}
3. 仅使用事件对象;如使用事件对象对应的 target 获取自定义属性 data-
结构中无须指定
逻辑中可以可以使用任何形参代替事件对象;常用的有e、event等
<div @click="doClickData" data-id="101">do something with data-</div>
function doClickData(e) {
  console.log(e.target.dataset);
}
4. 同时使用事件对象和参数
结构中需要使用 特殊变量 $event 以便和普通参数区分开来
逻辑中可以使用任意形参代替特殊变量 $event
<div 
  @click="doClickParaData('18', $event)" 
  data-id="101"
>do something with para and data- </div>
function doClickParaData(para,e) {
  console.log(para, e.target.dataset);
}
列表渲染商品数据,单击获取每个产品的 id - 在详情页利用 id 拉取对应的商品并渲染
<div v-for="item in goods" :key="item.id">
  <div>{{ item.name }}</div>
  <button @click="getItem(item.id, $event)">More</button>
</div>
const getItem = (id, e) => {
  console.log(id, e);
}
其它 Other
Bubbling、Capturing
决定事件执行的顺序
事件冒泡 Bubbling - 默认行为;单击 son,目标 son 先执行,然后冒泡到 fa 执行
<div class="fa" @click="doFa">
  <div class="son" @click="doSon"></div>
</div>
事件捕获 Capturing - 单击 son,先被 fa 捕获执行,再传播到目标 son执行
<div class="fa" @click.capture="doFa">
  <div class="son" @click="doSon"></div>
</div>
target、currentTarget
target:触发事件的目标 - 点的谁
currentTarget:当前响应事件的目标;随着事件流的变化,当前目标也在变化
单击 fa:点的是 fa;向上没有父级或者说没有冒泡,响应事件的也是 fa,所以 target 和 currentTarget 都是 fa
单击son:首先 son 响应事件,所以 target 和 currentTarget 都是 son;然后事件冒泡到 fa,fa 响应的是 son 绑定的事件,所以 target 是 son,currentTarget 是 fa
更多信息,请访问 Event - targetDelegation
<div class="fa" @click="doFa">
  <div class="son" @click="doSon"></div>
</div>
如果 son 指定 stop,事件不会冒泡到 fa
<div class="fa" @click="doFa">
  <div class="son" @click.stop="doSon"></div>
</div>
如果 fa 指定 self,仅仅响应我自己绑定的事件 - 自嗨模式,不会响应 son 冒泡的事件:target 是我,事件处理器不来自子元素
<div class="fa" @click.self="doFa">
  <div class="son" @click="doSon"></div>
</div>
Summary & Homework
Summary
classification
v-on/@
Homework
[] 商品详情页 DetailsView.vue → 商品数量增加 inc() 和减少 dec()
方案1:使用内联事件
<div @click.stop="num++">inc</div>
方案2:使用具名函数
<div @click.stop="inc">inc</div>
function inc() {
  num.value++
}
方案3:使用匿名函数
<div @click.stop="inc">inc</div>
const inc = () => {
  num.value++
}
参考结构
<footer>
  <div class="price">
    <div class="total">¥100</div>
    <div class="nums">
      <button>-</button>
      <span class="num">1</span>
      <button class="inc">+</button>
    </div>
  </div>
  <div class="btns">
    <button>立即购买</button>
    <button class="cart">加入购物车</button>
  </div>
</footer>
参考样式
footer {
  line-height: 40px;
}

.price {
  display: flex;
  justify-content: space-between;
}

.nums {
  display: flex;
  align-items: center;
  gap: 10px;
}

.nums button {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: 1px solid #f40;
}

.nums .num {
  width: 30px;
  text-align: center;
}

.nums button.inc {
  background-color: #f40;
  color: #fff;
}

.btns {
  display: flex;
  gap: 10px;
}

.btns button {
  flex: 1;
  border-radius: 20px;
  border: 1px solid #f40;
}

.btns button.cart {
  background-color: #f40;
  color: #fff;
}
[] 导航/标签页 TabCard;实现1 - 内联事件实现2 - 内联事件;列表渲染
使用 <nav> 和 <a> 实现
单击标签,对应的标签高亮显示
阻止 <a> 的默认事件
分别使用事件代理、不使用事件代理实现,并体会2者的区别