0%

【012】Vue基础学习:将原生事件绑定到组件

.native修饰符

我们有时候需要对封装好的组件做一些原生事件的操作,比如点击click事件,这个时候可以使用.native修饰符完成。

模版代码:

1
<v-demo @click.native="onClick"></v-demo>

示例代码:

1
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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>.native 修饰符</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
</head>
<body>
<div id="app">
<v-btn @click.native="onClick"></v-btn>
</div>
<script type="text/javascript">
var VBtn = {
template: `<button>点击我</button>`
};
new Vue({
el: '#app',
data() {
return {
msg: ''
}
},
components: {
'v-btn': VBtn
},
methods: {
onClick(event) {
alert('我被点击了');
}
}
});
</script>
</body>
</html>

在浏览器运行时,点击按钮时,弹出我被点击了,说明.native修饰符生效。如果去掉.native修饰符后,再次点击按钮没有任何反应。

其他情况

.native修饰符虽然在一定场景下很使用,但是在尝试监听一个类似<input>的元素时,该修饰符不起作用。为了解决这个问题,Vue 提供了一个 $listeners 属性,它是一个对象,里面包含了作用在这个组件上的所有监听器。

示例代码:

1
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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>$listeners</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
</head>
<body>
<div id="app">
<div>文本框内容为:{{ msg }}</div>
<v-input @input.native="onInput"></v-input>
</div>
<script type="text/javascript">
var VInput = {
// computed 是计算属性,这个后期会提到
computed: {
inputListeners() {
var vm = this;
// `Object.assign` 将所有的对象合并为一个新对象
return Object.assign(
{},
// 从父级添加所有的监听器
vm.$listeners,
{
// 复写 input 事件
input(event) {
vm.$emit('input', event.target.value);
}
}
)
},
},
template: `
<label>
<span>将原生事件绑定到组件:</span>
<input v-on="inputListeners">
</label>
`
};
new Vue({
el: '#app',
data() {
return {
msg: ''
}
},
components: {
'v-input': VInput
},
methods: {
onInput(event) {
this.msg = event.target.value;
}
}
});
</script>
</body>
</html>

题外:.sync修饰符

  1. .sync 修饰符是为了解决prop进行‘双向绑定’的问题。
  2. 需要注意带有 .sync 修饰符的 v-bind 不能和表达式一起使用 (例如 v-bind:title.sync=”doc.title + ‘!’” 是无效的)。

模版代码:

1
<v-demo :title.sync="msg"></v-demo>

示例代码:

1
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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>.sync 修饰符</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
</head>
<body>
<div id="app">
<div>父组件:{{ msg }}</div>
<v-demo :title.sync="msg"></v-demo>
</div>
<script type="text/javascript">
var VDemo = {
props: [ 'title' ],
template: `<div>{{ title }}</div>`,
mounted() {
setTimeout(() => {
this.$emit('update:title', 123)
}, 2000);
}
};
new Vue({
el: '#app',
data() {
return {
msg: '我是标题'
}
},
components: {
'v-demo': VDemo
}
});
</script>
</body>
</html>

总结

在日常开发中,将input封装成组件这种事还是很常见的,所以第二节中的示例代码还是需要多看看多练习一下。