Vue3 中的事件
在 Vue3 中,我们可以通过 v-on 或简写的 @ 来绑定事件。在事件处理程序中,可以使用 $event 访问原生 DOM 事件。
我们可以使用 v-on 或简写的 @ 来绑定事件,例如:
<template>
<button @click="handleClick">Click me!</button>
</template>
<script>
export default {
methods: {
handleClick() {
console.log('button clicked');
},
},
};
</script>
在上面的例子中,我们为 <button> 元素绑定了一个 click 事件,并在 handleClick 方法中处理了该事件。
我们也可以使用对象语法绑定多个事件和处理函数:
<template>
<button @click="handleClick" @mouseover="handleMouseOver">Hover me!</button>
</template>
<script>
export default {
methods: {
handleClick() {
console.log('button clicked');
},
handleMouseOver() {
console.log('mouse over button');
},
},
};
</script>
在上面的例子中,我们为 <button> 元素绑定了 click 和 mouseover 两个事件,并分别在 handleClick 和 handleMouseOver 方法中处理这两个事件。
此外还可以定义变量形式动态绑定事件

事件修饰符是用来改变事件处理行为的特殊标记。Vue 3.x 支持以下事件修饰符:
(改变的是默认行为~,不是禁用事件,在标签和事件嵌套的时候一定要记得阻止冒泡发生)
.stop - 阻止事件继续传播。.prevent - 阻止默认行为。.capture - 将事件处理添加到捕获阶段,而不是冒泡阶段。.self - 只有在事件目标是当前元素本身时触发事件处理函数。.once - 事件将只被处理一次。.passive - 指示事件监听器永远不会调用 event.preventDefault()。这可以提高滚动性能。例如,你可以使用 .stop 修饰符来阻止事件继续传播,如下所示:
<div @click.stop="doThis"></div>
使用 .prevent 修饰符阻止默认行为:
<form @submit.prevent="onSubmit"></form>
使用 .capture 修饰符将事件处理添加到捕获阶段,如下所示:
<div @click.capture="doThis"></div>
使用 .self 修饰符只有在事件目标是当前元素本身时才会触发事件处理函数:
<div @click.self="doThis"></div>
使用 .once 修饰符让事件只被处理一次:
<div @click.once="doThis"></div>
使用 .passive 修饰符指示事件监听器永远不会调用 event.preventDefault():
<div @touchstart.passive="doThis"></div>
在 Vue 中,处理事件时可以使用 $event 访问原始 DOM 事件对象。例如,可以在模板中这样使用:
<button @click="handleClick($event)">Click me</button>
在上面的代码中,@click 是 Vue 的事件绑定语法,handleClick 是定义在 Vue 实例中的事件处理函数,$event 是传递给事件处理函数的原始 DOM 事件对象。
在事件处理函数中,可以通过参数来接收 $event 对象。例如:
methods: {
handleClick(event) {
console.log(event.target) // 输出点击的元素
}
}
在上面的代码中,handleClick 方法接收一个参数 event,它就是传递给事件处理函数的原始 DOM 事件对象。可以通过访问 event 的属性和方法来获取事件的详细信息,例如 target 属性可以获取触发事件的原始 DOM 元素。
总之,使用 $event 来访问原始 DOM 事件对象是 Vue 中非常常用的技巧,可以帮助开发者更方便地处理事件和获取事件信息。
除了原生事件外,Vue 3.x 还支持自定义事件。自定义事件通常用于跨组件通信。你可以使用 vm.$emit 发出自定义事件,如下所示:
// 在组件中发出事件
this.$emit('my-event', data)
// 在组件外监听事件
vm.$on('my-event', handler)
在上面的代码中,my-event 是自定义事件名称,data 是将传递给事件处理程序的数据。
举个例子吧:我们需要在子组件中修改父组件的属性值(后面我们可以使用pina实现组件间的数据共享)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://unpkg.com/vue@next"></script>
<title>Components</title>
</head>
<body>
<div id="applictation">
<switcher bcolor="red" radius="20px" @myclick="switchState1"></switcher>第一个组件的开关状态:{{state1}}
<!-- <switcher bcolor="blue" radius="5px"></switcher>第二个组件的开关状态:{{state2}} -->
</div>
<script>
const App = {
data() {
return {
state1: '关'
}
},
methods: {
parentclick(title) {
alert(title + "被点击了")
},
switchState1(state){
this.state1=state?'开' : '关'
}
}
}
// 自定义组件
const switchComponet = {
data() {
return {
isOpen: false,
left: '0px'
}
},
methods: {
click() {
this.isOpen = !this.isOpen;
this.left = this.isOpen ? '30px' : '0px';
// this.state1 = this.isOpen ? '开' : '关'; // 同步修改state1的值
this.$emit('myclick', this.isOpen);
}
},
props: ['bcolor', 'radius'],
template: `<div :style="{width:'60px',height:'30px', backgroundColor: isOpen ? bcolor : 'gray', borderRadius: radius, position: 'relative' }" @click="click">
<div :style="{width:'30px',height:'30px', backgroundColor: 'pink', borderRadius: radius, position: 'absolute', left: left}"></div>
</div>`
}
app = Vue.createApp(App);
// 注册组件
app.component("switcher", switchComponet);
app.mount("#applictation");
</script>
</body>
</html>
父组件的模板代码:
<template>
<div>
<Switcher :bcolor="red" :radius="20" @myclick="switchState1" />
第一个组件的开关状态:{{state1}}
</div>
</template>
<script>
import { defineComponent, ref } from 'vue';
import Switcher from './Switcher.vue'; // 引入Switcher组件
export default defineComponent({
components: {
Switcher,
},
setup() {
const state1 = ref('关');
const switchState1 = (state) => {
state1.value = state ? '开' : '关';
};
return {
state1,
switchState1,
};
},
});
</script>
Switcher组件的模板代码:
<template>
<div :style="{width:'60px',height:'30px', backgroundColor: isOpen ? bcolor : 'gray', borderRadius: radius + 'px', position: 'relative' }" @click="switchState">
<div :style="{width:'30px',height:'30px', backgroundColor: 'pink', borderRadius: radius + 'px', position: 'absolute', left: left}"></div>
</div>
</template>
<script>
import { defineComponent, ref } from 'vue';
export default defineComponent({
props: {
bcolor: {
type: String,
default: 'gray',
},
radius: {
type: Number,
default: 0,
},
},
setup(props, { emit }) {
const isOpen = ref(false);
const left = ref('0px');
const switchState = () => {
isOpen.value = !isOpen.value;
left.value = isOpen.value ? '30px' : '0px';
emit('myclick', isOpen.value);
};
return {
isOpen,
left,
switchState,
};
},
});
</script>
在上面的代码中,我们将Switcher组件定义在了单独的文件Switcher.vue中,并在父组件中通过import语句引入了该组件。这样可以使组件代码更加清晰、易读、易维护。
在父组件的模板代码中,我们只需要像之前一样使用<Switcher>标签即可,不需要再写template标签了。同时,我们也不需要在父组件的setup()函数中定义Switcher组件的相关逻辑了,因为这些逻辑已经在Switcher.vue组件中定义了。
总体来说,将组件的模板代码和组件定义分离可以使代码更加清晰、易读、易维护,尤其是在开发大型应用时,更加方便管理和组织代码。
在 Vue 3.x 中,事件处理非常简单。你可以通过 v-on 指令添加事件处理程序,并使用对象语法绑定多个事件和处理程序。Vue 3.x 还支持事件修饰符,用于更改事件处理行为。另外,你还可以使用 $event 访问原始 DOM