事件处理与表单输入
# 事件处理与表单输入
Vue 使用 v-on 指令(缩写 @)监听 DOM 事件,使用 v-model 实现表单输入的双向绑定。本章先以 Options API + CDN 方式入门,再以 Composition API + SFC 方式演示工程化写法。
# 事件处理
在 JavaScript 语言中,当用户与 UI 组件交互时,UI 组件能够激发一个相应事件。例如,用户按动按钮、滚动文本、移动鼠标或按下按键等,都将产生一个相应的事件。
Vue3.0 使用 v-on 指令(缩写为 @ 符号)来监听 DOM 事件,并在触发事件时执行一些 JavaScript 函数。
语法为 v-on:click="函数名" 或 @click="函数名"。
# 1 事件处理
如果你有看过前面的章节,应该知道响应用户操作事件的函数是放在 methods 里面的。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vue3.0计算属性</title>
<script src="vue.global.js"></script>
</head>
<body>
<span id="app">
<button @click="say">说点什么</button>
</span>
<script>
Vue.createApp({
data() {
},
methods: {
say() {
alert("艾边成,真酷!")
}
},
}).mount("#app")
</script>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 2 传递参数
Vue 事件绑定,除了支持直接绑定到一个方法外,也可以在内联 JavaScript 语句中调用方法。说白了,就是可以直接在函数中传递参数。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vue3.0计算属性</title>
<script src="vue.global.js"></script>
</head>
<body>
<span id="app">
<button @click="say('老陈说')">老陈说</button>
<br/><br/>
<button @click="say('老头说')">老头说</button>
</span>
<script>
Vue.createApp({
data() {
},
methods: {
say(title) {
alert(title + ",爱编程的人真酷!")
}
},
}).mount("#app")
</script>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 3 事件来源
如果界面上有多个按钮或表单,你想根据用户的不同操作,响应不同的事件,这时你可以通过监听事件源的方式进行处理。
在软件系统中,我们常常见到的打开、保存、导出、打印等多个按钮在同一个功能菜单时,就可以用这种方式。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vue3.0计算属性</title>
<script src="vue.global.js"></script>
<style>
.menu {
border: 1px solid darkgreen;
width: 100px;
height: 150px;
padding-top: 20px;
padding-left: 20px;
}
</style>
</head>
<body>
<div class="menu" id="app">
<button name="save" @click="opt">保存</button>
<br/> <br/>
<button name="open" @click="opt">打开</button>
<br/> <br/>
<button name="print" @click="opt">打印</button>
</div>
<script>
Vue.createApp({
data() {
},
methods: {
opt(event) {
let opt = event.target.name
let src = event.target.tagName
alert('知道你点了 ' + opt + ' '
+ src + ',我马上处理.')
}
},
}).mount("#app")
</script>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
输出结果:

细心的人,可能会想到,如果想要监听事件源,又想要传递参数时,Vue 又当如何处理,不要急,你想到的,我也想到了,Vue 创始人也想到了。
传递参数时,将 $event 参数也传过去就好了。
<div class="menu" id="app">
<button name="save" @click="opt('保存',$event)">保存</button>
<br/> <br/>
<button name="open" @click="opt('打开',$event)">打开</button>
<br/> <br/>
<button name="print" @click="opt('打印',$event)">打印</button>
</div>
<script>
Vue.createApp({
data() {
},
methods: {
opt(name, event) {
let opt = event.target.name
let src = event.target.tagName
alert('知道你点了 ' + opt + '(' + name + ') '
+ src + ',我马上处理.')
}
},
}).mount("#app")
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
输出结果为:

# 4 多事件处理
一个操作,多个函数响应,这便是多事件也。在 Vue3.0 中,这些函数都放在 @click 里并用逗号分隔即可。
这种处理方式,真的很赞,就像你转发分享这篇文章一样。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vue3.0计算属性</title>
<script src="vue.global.js"></script>
<style>
.menu {
border: 1px solid darkgreen;
width: 100px;
height: 150px;
padding-top: 20px;
padding-left: 20px;
}
</style>
</head>
<body>
<div class="menu" id="app">
<button @click="add(6),sub(3)">加减</button>
</div>
<script>
let result = 0
Vue.createApp({
data() {
},
methods: {
add(num) {
result += num
},
sub(num) {
result -= num
alert('结果是:' + result) // 结果是:3
}
},
}).mount("#app")
</script>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# 5 按键修饰符
不知你在用键盘输入多项内容之后,是否有按下回车键的习惯,如果没有,那证明你打字很慢,如果有,那证明你不是程序员,而是打字员(哈哈~~,什么鬼逻辑)。
在较完善的系统中,当用户按下回车键(或其他键)时,都会有响应的。为了解决这个问题,Vue 允许为 v-on 或者 @ 在监听键盘事件时添加按键修饰符。
Vue 为最常用的键提供了 .enter(回车) 、.tab 、 .delete (捕获“删除”和“退格”键)、.esc(取消) 、.up(上)、.down(下)、.left(左)、.right(右)等。
例如:@keyup.enter="submit"
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vue3.0计算属性</title>
<script src="vue.global.js"></script>
<style>
.menu {
border: 1px solid darkgreen;
width: 100px;
height: 150px;
padding-top: 20px;
padding-left: 20px;
}
</style>
</head>
<body>
<div class="menu" id="app">
<button @keyup.enter="submit" @click="submit" type="submit">确定</button>
</div>
<script>
let result = 0
Vue.createApp({
data() {
},
methods: {
submit() {
alert('你明明按下了回车键,别耍赖,赶紧分享文章')
}
},
}).mount("#app")
</script>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# 表单输入
在 Vue3.0 中,事件处理用 v-on 指令,表单输入绑定则用 v-model 指令。
v-model 指令在表单 <input>、<textarea> 及 <select> 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。
# 1 文本输入
在 HTML 标签中,文本输入有单行(text)和多行(textarea)输入。
温馨提醒: v-model 会忽略所有表单元素的 value 的初始值而总是将当前活动实例的数据作为数据来源。你应该通过 JavaScript 该组件的 data 选项中声明初始值。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vue3.0表单绑定</title>
<script src="vue.global.js"></script>
</head>
<body>
<div id="app">
<input v-model="msg" placeholder="单行输入"/>
<p>单行输入结果: {{ msg }}</p>
<hr style="background-color: #4CAF50;height: 1px"/>
<textarea v-model="msg2" placeholder="多行输入"></textarea>
<p>多行输入结果: {{ msg2 }}</p>
</div>
<script>
Vue.createApp({
data() {
return {
msg: '',
msg2: ''
}
}
}).mount("#app")
</script>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 1.1 文本框的 number 修饰符
template : `
<div>
{{message}}
<input v-model.number="message" type="number" />
<button @click="getMessage">获取文本内容</button>
</div>
`
2
3
4
5
6
7
在文本框元素中使用 v-model.number ,得到的结果是一个数字类型的值,而不是字符串。
# 1.2 文本框的 trim 修饰符
template : `
<div>
{{message}}
<input v-model.trim="message" />
<button @click="getMessage">获取文本内容</button>
</div>
`
2
3
4
5
6
7
在文本框元素中使用 v-model.trim ,得到的结果会去掉两端的空格、Tab、回车等特殊字符。
# 2 复选框 checkbox
在开发产品时,单个复选框常在勾选协议中见到。
# 2.1 单个 checkbox 与数据绑定
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vue3.0计算属性</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app">
<input type="checkbox" v-model="checkboxFlag" />checkbox<br>
<button @click="getCheckboxFlag">获取checkbox设置</button>
</div>
<script>
const app = Vue.createApp({ // 创建一个vue应用实例
data() {
return {
checkboxFlag: true,
}
},
methods: {
getCheckboxFlag() {
console.info(this.checkboxFlag)
}
},
}).mount("#app")
</script>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
当 checkbox 被选中时,值是 true,否则值是 false

# 2.2 自定义单个 checkbox 的值
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vue3.0计算属性</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app">
<input type="checkbox" v-model="checkboxFlag2" true-value="选中" false-value="未选中" />checkbox<br>
<button @click="getCheckboxFlag2">获取checkbox设置</button>
</div>
<script>
const app = Vue.createApp({ // 创建一个vue应用实例
data() {
return {
checkboxFlag2: "选中",
}
},
methods : {
getCheckboxFlag2() {
console.info(this.checkboxFlag2)
},
},
}).mount("#app")
</script>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
使用 true-value 和 false-value 自定义 checkbox 的值

# 2.3 一组 checkbox 与数据绑定
一组复选框,常在选择个人兴趣爱好等见到。复选框,单选时,绑定到布尔值,多选时,绑定到同一个数组。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vue3.0计算属性</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app">
<input type="checkbox" v-model="checkboxArr" value="football" />足球<br>
<input type="checkbox" v-model="checkboxArr" value="basketball" />篮球<br>
<input type="checkbox" v-model="checkboxArr" value="tableTennis" />乒乓球<br>
<button @click="getCheckboxArr">获取checkbox设置</button>
</div>
<script>
const app = Vue.createApp({ // 创建一个vue应用实例
data() {
return {
checkboxArr: [],
}
},
methods : {
getCheckboxArr() {
console.info(this.checkboxArr)
},
},
}).mount("#app")
</script>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
一组 checkbox 与同一个数据 checkboxArr 绑定,得到的结果是一个数组

# 3 单选框(radio)
在开发产品时,单选按钮,用于多选一,在选择性别时常见。
# 3.1 一组 radio 与数据绑定
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vue3.0计算属性</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app">
<input type="radio" v-model="radioValue" value="football" />足球<br>
<input type="radio" v-model="radioValue" value="basketball" />篮球<br>
<input type="radio" v-model="radioValue" value="tableTennis" />乒乓球<br>
<button @click="getRadioValue">获取radio设置</button>
</div>
<script>
const app = Vue.createApp({ // 创建一个vue应用实例
data() {
return {
radioValue: "tableTennis",
}
},
methods : {
getRadioValue() {
console.info(this.radioValue)
},
},
}).mount("#app")
</script>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
radio 是单选(只能选择其中的一个),因此得到的值是一个 字符串

# 4 select
如果选择项很多,那可用多选下拉菜单 select,以节约布局空间。
# 4.1 select 与数据绑定
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vue3.0计算属性</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app">
<select v-model="selectValue">
<option value="football">足球</option>
<option value="basketball">篮球</option>
<option value="tableTennis">乒乓球</option>
</select>
<br>
<button @click="getRadioValue">获取select设置</button>
</div>
<script>
const app = Vue.createApp({ // 创建一个vue应用实例
data() {
return {
selectValue: "",
}
},
methods : {
getRadioValue() {
alert(this.selectValue)
},
},
}).mount("#app")
</script>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
在 select 标签上使用 v-model 绑定数据 selectValue

# 4.2 select 的选项从数据获得
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vue3.0计算属性</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app">
<select v-model="selectValue">
<option v-for="item in selectOptionArr" :value="item.value">{{item.text}}</option>
</select>
<br>
<button @click="getSelectValue">获取select设置</button>
</div>
<script>
const app = Vue.createApp({ // 创建一个vue应用实例
data() {
return {
selectOptionArr: [
{text: "足球", value: "football"},
{text: "篮球", value: "basketball"},
{text: "乒乓球", value: "tableTennis"}
],
}
},
methods : {
getSelectValue() {
alert(this.selectValue)
},
},
}).mount("#app")
</script>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
使用 v-for 得到 option 元素,运用数组的形式,效果和上一小节一致。
# 4.3 select 的返回对象
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vue3.0计算属性</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app">
<select v-model="selectValue">
<option v-for="item in selectOptionArr2" :value="item.value">{{item.text}}</option>
</select>
<br>
<button @click="getSelectValue">获取select设置</button>
</div>
<script>
const app = Vue.createApp({ // 创建一个vue应用实例
data() {
return {
selectOptionArr2: [
{text: "足球", value: {name:"football", text:"足球"}},
{text: "篮球", value: {name:"basketball", text:"篮球"}},
{text: "乒乓球", value: {name:"tableTennis", text:"乒乓球"}}
],
}
},
methods : {
getSelectValue() {
console.info(this.selectValue)
},
},
}).mount("#app")
</script>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
option 绑定的数据 selectOptionArr2 中,value 是一个对象。这样 select 的返回值就是对应的对象。

# Composition API 写法
在 <script setup> 中,事件绑定用 @事件名,表单双向绑定用 v-model,与模板写法一致,但数据定义在 setup 中。
# 事件绑定
<script setup lang="ts">
import { ref } from 'vue'
const count = ref(0)
function dec() {
count.value--
}
function inc() {
count.value++
}
</script>
<template>
<input type="button" value="-" @click="dec">
<h2>{{count}}</h2>
<input type="button" value="+" @click="inc">
</template>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- 【@事件名】用来将标签属性与函数绑定,事件发生后执行函数内代码
# 表单绑定
<script setup lang="ts">
import { ref } from "vue";
const user = ref({
name: 沉梦听雨
age:18,
sex:'男',
fav:['游泳','打球']
})
function saveUser() {
console.log(user.value)
}
</script>
<template>
<div class="outer">
<div>
<label for="">请输入姓名</label>
<input type="text" v-model="user.name"/>
</div>
<div>
<label for="">请输入年龄</label>
<input type="text" v-model="user.age"/>
</div>
<div>
<label for="">请选择性别</label>
男 <input type="radio" value="男" v-model="user.sex"/>
女 <input type="radio" value="女" v-model="user.sex"/>
</div>
<div>
<label for="">请选择爱好</label>
游泳 <input type="checkbox" value="游泳" v-model="user.fav"/>
打球 <input type="checkbox" value="打球" v-model="user.fav"/>
健身 <input type="checkbox" value="健身" v-model="user.fav"/>
</div>
<div>
<input type="button" value="保存" @click="saveUser">
</div>
</div>
</template>
<style scoped>
div {
margin-bottom: 8px;
}
.outer {
width: 100%;
position: relative;
padding-left: 80px;
}
label {
text-align: left;
width: 100px;
display: inline-block;
position: absolute;
left :0;
}
</style>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
- 用 v-model 实现双向绑定,即
- javascript 数据可以同步到表单标签
- 反过来用户在表单标签输入的新值也会同步到 javascript 这边
- 双向绑定只适用于表单这种带【输入】功能的标签,其它标签的数据绑定,单向就足够了
- 复选框这种标签,双向绑定的 javascript 数据类型一般用数组