接着前面的内容:https://www.cnblogs.com/yanggb/p/12584237.html

事件处理

使用javascript当然少不了事件处理,即使是vue也不会例外。

监听事件

在vue中可以使用【v-on】指令监听dom事件,并在触发的时候运行一些javascript代码。

<div id="example-1">
<button v-on:click="counter += 1">Add 1</button>
<p>The button above has been clicked {{ counter }} times.</p>
</div>
var example1 = new Vue({
el: '#example-1',
data: {
counter: 0
}
})

在上面的例子中,给button绑定了一个点击的事件,点击该按钮就会触发counter+1的处理逻辑。

事件处理方法

实际的事件处理逻辑当然是比上面的简单例子要复杂得多,这种情况下如果直接把javascript代码写在【v-on】指令中是不可行的,因为该指令中只支持单表达式。因此【v-on】指令还支持接收一个需要调用的方法名称。

<div id="example-2">
<!-- greet是在下面定义的方法名 -->
<button v-on:click="greet">Greet</button>
</div>
var example2 = new Vue({
el: '#example-2',
data: {
name: 'Vue.js'
},
// 在methods对象中定义方法
methods: {
greet: function (event) {
// this在方法里指向当前Vue实例
alert('Hello ' + this.name + '!')
// event是原生DOM事件
if (event) {
alert(event.target.tagName)
}
}
}
}) // 也可以用JavaScript直接调用方法(不通过事件绑定触发)
example2.greet() // 'Hello Vue.js!'

这样,点击按钮之后就会依次弹出提示内容是【Hello Vue.js!】和【BUTTON】的提示框。

此外,这里要特别注意代码中的注释内容,注意事项可以分为以下的几点。

1.如果方法有入参的话,在模板中可以这样编写:

<button v-on:click="greet('yanggb')">Greet</button>

2.如果方法有入参,但是模板中没有传递参数的话,方法在调用的时候的第一个默认实参会是事件(event)本身,因此这个时候如果你单单用if条件去判断该参数是否存在是不行的,结果总是会返回true,因此如果方法有入参但是你调用方法的时候却不需要传参,而在方法中的判断却依赖了该入参的时候,最好是给一个0值,确保不会出现意料之外的问题,比如点击事件不生效。

<button v-on:click="greet(0)">Greet</button>

3.在method对象中定义的方法,方法体中的this如果没有特殊情况都是指向的当前vm实例。

内联处理器中的方法

除了直接绑定到一个方法,也可以在内联javascript语句中调用方法。

<div id="example-3">
<button v-on:click="say('hi')">Say hi</button>
<button v-on:click="say('what')">Say what</button>
</div>
new Vue({
el: '#example-3',
methods: {
say: function (message) {
alert(message)
}
}
})

这种方式在需要传递参数的场景中会用到,在前面的注意事项中已经说过了。这里要特别说明的是,有一些场景可能会需要在内联语句处理器中访问原始的dom事件,这种情况下可以使用特殊变量【$event】并将它传入方法中。

<button v-on:click="warn('Form cannot be submitted yet.', $event)">
Submit
</button>
// ...
methods: {
warn: function (message, event) {
// 现在我们可以访问原生事件对象
if (event) {
event.preventDefault()
}
alert(message)
}
}

这个参数实际上也就是当前触发的事件本身,vue将其赋值给了一个全局属性【$event】,以方便我们使用。事实上,当我们不传递参数的时候,方法的第一个参数就会默认赋值为event,而当我们需要传递参数且需要使用事件本身的时候,【$event】也就派上了大用场。

事件修饰符

在事件处理程序中调用【event.preventDefault()】或者【event.stopPropagation()】使非常常见的需求。虽然我们可以在方法中轻松实现这一点(需要借助event),但是vue提供了一种更好的方式,可以使我们免去处理dom事件的细节,而只关注方法的数据逻辑,使方法变得纯粹,不揉杂其他与数据没有直接关联的逻辑。这种更好的方法,就是【v-on】指令的【事件修饰符】,这种修饰符以【.】开头的指令后缀来表示。

.stop
.prevent
.capture
.self
.once
.passive
<!-- 阻止单击事件继续传播 -->
<a v-on:click.stop="doThis"></a> <!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form> <!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a> <!-- 只有修饰符 -->
<form v-on:submit.prevent></form> <!-- 添加事件监听器时使用事件捕获模式 -->
<!-- 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 -->
<div v-on:click.capture="doThis">...</div> <!-- 只当在event.target是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div v-on:click.self="doThat">...</div>

使用修饰符要注意修饰符的顺序,因为相应的代码会以同样的顺序产生。比如,使用【v-on:click.prevent.self】会阻止所有的点击,而使用【v-on:click.self.prevent】只会阻止对元素自身的点击(元素的爸爸,爷爷或太爷爷都能点击)。

【.once】修饰符是2.1.4中新增的事件修饰符。

<!-- 点击事件将只会触发一次 -->
<a v-on:click.once="doThis"></a>

不像其它只能对原生的 DOM 事件起作用的修饰符,【.once】修饰符还能被用到自定义的组件事件上。

【.passive】修饰符是2.3.0中新增的事件修饰符,是vue为了对应addEventListener中的passive选项专门提供的。

<!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发 -->
<!-- 而不会等待onScroll完成 -->
<!-- 这其中包含event.preventDefault()的情况 -->
<div v-on:scroll.passive="onScroll">...</div>

因为其设计特性,这个【.passive】修饰符尤其能够提升移动端的性能。但是要注意的是,不要把【.passive】和【.pervent】修饰符一起使用,因为这种情况下【.pervent】修饰符会被忽略,同时浏览器还会展示一个警告。请记住,【.passive】的作用是告诉浏览器不要阻止事件的默认行为,【.passive】的作用是告诉浏览器不要阻止事件的默认行为,【.passive】的作用是告诉浏览器不要阻止事件的默认行为。

按键修饰符

在监听键盘事件的时候,我们经常会需要检查详细的按键,因此vue允许为【v-on】指令在监听键盘事件的时候添加相关的按键修饰符。

<!-- 只有在key是Enter时调用vm.submit() -->
<input v-on:keyup.enter="submit">

按键修饰符的语法是,你可以直接将【KeybordEvent.key】暴露的任意有效按键名转换为kebab-case(横线分隔命名)来作为修饰符。

<input v-on:keyup.page-down="onPageDown">

比如在上面这个例子中,处理函数只会在$event.key等于PageDown的时候被调用。

按键码

所谓的按键码,就是用数字去代替按键名,比如13表示的是enter按键。

虽然说keyCode(按键码)的事件用法已经被废弃了,并且可能不会被最新的浏览器支持,但是在vue中使用按键码作为按键修饰符还是允许的。

<input v-on:keyup.13="submit">

为了在必要的情况下支持旧的浏览器,vue提供了绝大多数常用的按键码的别名。

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

而有一些按键(比如.esc和所有的方向键)在ie9中却有着不同的key值,因此如果你想要支持ie9的话,这些内置的别名应该是首选。简单来说,为了避免不必要的麻烦,请使用vue内置的按键别名。

此外,vue还支持通过全局的【config.keyCodes】对象自定义按键修饰符别名。

// 可以使用v-on:keyup.f1
Vue.config.keyCodes.f1 = 112

这样,就可以使用112来表示f1按键名,而且原来的f1按键名依然能使用。

系统修饰键

vue在2.1.0中新增了一些系统修饰符(组合按键),来实现仅在按下相应的按键的时候才去触发鼠标或键盘事件的监听器。

.ctrl
.alt
.shift
.meta
<!-- Alt + C -->
<input @keyup.alt.67="clear"> <!-- Ctrl + Click -->
<div @click.ctrl="doSomething">Do something</div>

要注意的第一点是,在不同的操作系统下,这些修饰符对应的系统键盘的按键是不一样的,在开发的时候要将这些客观条件考虑进逻辑处理中。

要注意的第二点是,修饰键与常规的按键是不同的,在和keyup事件一起使用的时候,事件触发的时候修饰键必须是处于按下状态。换句话来说就是,只有在按住ctrl按键的情况下释放其他的按键才会去触发keyup.ctrl事件,而单单释放ctrl是不会触发事件的。但是如果你想要这样的行为也是可以的,请为ctrl申请别名或使用keyCode,即keyup.17,这时候就能达到单按键触发keyup事件的效果了。

更多的,vue在2.5.0中还新增了一个【.exact】修饰符,用于允许开发者控制由精确的系统修饰符组合触发的事件。

<!-- 即使Alt或Shift被一同按下时也会触发 -->
<button @click.ctrl="onClick">A</button> <!-- 有且只有Ctrl单独被按下的时候才触发 -->
<button @click.ctrl.exact="onCtrlClick">A</button> <!-- 没有任何系统修饰符被按下的时候才触发 -->
<button @click.exact="onClick">A</button>

在上面的三个例子中,很清楚的表示了【.exact】在一些需要精准控制组合按键事件触发的特殊场景中十分有用。

鼠标按键修饰符

vue在2.2.0中新增了几个鼠标按键修饰符。

.left
.right
.middle

这些修饰符会限制处理函数仅相应特定的鼠标按钮。

为什么需要在html(模板)中监听事件的思考

你可能注意到了,这种事件监听的方式违背了关注点分离(separation of concern)这个长期依赖的优良传统。但是在vue中,所有的事件处理方法和表达式都是被严格地通过【v-on】指令绑定在当前视图的ViewModel上,并不会导致任何维护上的困难。

这里总结出一些在html(模板)中使用【v-on】绑定事件处理的好处:

1.扫一眼html模板,便能轻松定位在javascript代码中定义的对应方法。

2.因为你无需在JavaScript里面手动绑定事件,因此你的ViewModel代码可以是非常纯粹的逻辑,和dom完全解耦(不需要写dom操作的相关逻辑),更易于测试。

3.当一个ViewModel被销毁的时候,所有的事件处理器都会被自动删除,无需开发者担心如何去清理它们。

"我还是很喜欢你,像仲夏流萤四起,弦月沉西。"

vue2.x学习笔记(十)的更多相关文章

  1. python3.4学习笔记(十四) 网络爬虫实例代码,抓取新浪爱彩双色球开奖数据实例

    python3.4学习笔记(十四) 网络爬虫实例代码,抓取新浪爱彩双色球开奖数据实例 新浪爱彩双色球开奖数据URL:http://zst.aicai.com/ssq/openInfo/ 最终输出结果格 ...

  2. Learning ROS for Robotics Programming Second Edition学习笔记(十) indigo Gazebo rviz slam navigation

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 moveit是书的最后一章,由于对机械臂完全不知,看不懂 ...

  3. python3.4学习笔记(十八) pycharm 安装使用、注册码、显示行号和字体大小等常用设置

    python3.4学习笔记(十八) pycharm 安装使用.注册码.显示行号和字体大小等常用设置Download JetBrains Python IDE :: PyCharmhttp://www. ...

  4. vue2.0学习笔记之路由(二)路由嵌套+动画

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. vue2.0学习笔记之路由(二)路由嵌套

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. python3.4学习笔记(十九) 同一台机器同时安装 python2.7 和 python3.4的解决方法

    python3.4学习笔记(十九) 同一台机器同时安装 python2.7 和 python3.4的解决方法 同一台机器同时安装 python2.7 和 python3.4不会冲突.安装在不同目录,然 ...

  7. python3.4学习笔记(十六) windows下面安装easy_install和pip教程

    python3.4学习笔记(十六) windows下面安装easy_install和pip教程 easy_install和pip都是用来下载安装Python一个公共资源库PyPI的相关资源包的 首先安 ...

  8. python3.4学习笔记(十五) 字符串操作(string替换、删除、截取、复制、连接、比较、查找、包含、大小写转换、分割等)

    python3.4学习笔记(十五) 字符串操作(string替换.删除.截取.复制.连接.比较.查找.包含.大小写转换.分割等) python print 不换行(在后面加上,end=''),prin ...

  9. python3.4学习笔记(十二) python正则表达式的使用,使用pyspider匹配输出带.html结尾的URL

    python3.4学习笔记(十二) python正则表达式的使用,使用pyspider匹配输出带.html结尾的URL实战例子:使用pyspider匹配输出带.html结尾的URL:@config(a ...

  10. python3.4学习笔记(十) 常用操作符,条件分支和循环实例

    python3.4学习笔记(十) 常用操作符,条件分支和循环实例 #Pyhon常用操作符 c = d = 10 d /= 8 #3.x真正的除法 print(d) #1.25 c //= 8 #用两个 ...

随机推荐

  1. Python第五章-内置数据结构02-列表

    Python 内置的数据结构 二.列表(list) 想一想: 前面学习的字符串可以用来存储一串信息,那么想一想,怎样存储咱们班所有同学的名字呢? 定义100个变量,每个变量存放一个学生的姓名可行吗?有 ...

  2. JavaScript JSON 与 AJAX

    JavaScript JSON 与 AJAX JSON 是一种轻量的数据交互格式,与 AJAX 配合完成前端页面与服务端的信息传递,本文介绍 JSON 的使用.原生 AJAX 写法.JSONP 跨域解 ...

  3. RabbitMQ AMQP 事务机制

    1,在之前的文章中介绍了RabbitMQ的五种队列形式 其中,在工作队列中,为了保证消费者的公平性,采用了channel.basicQos(1),保证了每次只发一条消息给消费者消费,并且使用手动签收的 ...

  4. ThreadAbortException是可以传递的

    今天在写线程Aborted代码时,发现嵌套的try catch中的ThreadAbortException错误是可以从内部传递到外部的,想想这也是必然的,在内部该线程已经中断了,外部必然是中断了,再仔 ...

  5. Codeforces题解集 1.0

    记录 Codeforces 2019年12月19日到 2020年2月12日 的部分比赛题 Educational Codeforces Round 82 (Rated for Div. 2) D Fi ...

  6. Java读源码之ReentrantLock

    前言 ReentrantLock 可重入锁,应该是除了 synchronized 关键字外用的最多的线程同步手段了,虽然JVM维护者疯狂优化 synchronized 使其已经拥有了很好的性能.但 R ...

  7. Vue的父子组件v-model双向绑定,父组件修改子组件中绑定的v-model属性

    先来看下实现的效果,父组件中有个文本框,在点击下面按钮时弹出抽屉,抽屉里也有个文本框,文本框里的初始值要和父组件的文本框同步,并且修改抽屉里的文本框值时 父组件里的文本框值也要跟着改变 网上有大概三种 ...

  8. 感染(low)bfs 、感染(mid) 二分、感染(high) 二分 + 维护单调 队列去除无用的点

    感染(low) Description n户人家住在一条直线上,从左往右依次编号为1,2,-,n.起初,有m户人家感染了COVID-19,而接下来的每天感染的人家都会感染他家左右两家的人,问t天后总共 ...

  9. GO gRPC教程-环境安装(一)

    前言 gRPC 是一个高性能.开源和通用的 RPC 框架,面向移动和 HTTP/2 设计,带来诸如双向流.流控.头部压缩.单 TCP 连接上的多复用请求等特.这些特性使得其在移动设备上表现更好,更省电 ...

  10. ERROR:TypeError: Cannot read property 'upgrade' of undefined