使用v-on指令(简写为@)监听DOM事件。
<template>
<div>
<!-- 完整语法 -->
<button v-on:click="count++">点击次数: {{ count }}</button>
<!-- 简写语法 -->
<button @click="count++">点击次数: {{ count }}</button>
<!-- 调用方法 -->
<button @click="handleClick">点击我</button>
</div>
</template>
<script setup>
import { ref } from 'vue'
const count = ref(0)
function handleClick() {
console.log('按钮被点击了')
count.value++
}
</script>
<template>
<div>
<button @click="count++">增加</button>
<button @click="count--">减少</button>
<button @click="say('hello')">打招呼</button>
<p>计数: {{ count }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const count = ref(0)
function say(message) {
alert(message)
}
</script>
<template>
<div>
<!-- 自动传入event -->
<button @click="handleClick">点击1</button>
<!-- 使用$event传入event -->
<button @click="handleClickWithArg('hello', $event)">点击2</button>
<!-- 箭头函数 -->
<button @click="(event) => handleEvent(event)">点击3</button>
</div>
</template>
<script setup>
function handleClick(event) {
console.log(event.target.tagName)
}
function handleClickWithArg(message, event) {
console.log(message, event.target)
}
function handleEvent(event) {
console.log(event)
}
</script>
<template>
<div>
<!-- 阻止默认行为 -->
<form @submit.prevent="onSubmit">
<button type="submit">提交</button>
</form>
<!-- 阻止事件冒泡 -->
<div @click="divClick">
<button @click.stop="buttonClick">点击</button>
</div>
<!-- 捕获模式 -->
<div @click.capture="handleCapture">
<button>捕获</button>
</div>
<!-- 只触发一次 -->
<button @click.once="handleOnce">只触发一次</button>
<!-- 只当事件在该元素本身触发时才触发回调 -->
<div @click.self="handleSelf">
<button>点击</button>
</div>
<!-- 修饰符可以链式调用 -->
<form @submit.prevent.stop="onSubmit"></form>
</div>
</template>
<script setup>
function onSubmit() {
console.log('表单提交')
}
function divClick() {
console.log('div被点击')
}
function buttonClick() {
console.log('button被点击')
}
function handleCapture() {
console.log('捕获阶段')
}
function handleOnce() {
console.log('只执行一次')
}
function handleSelf() {
console.log('self触发')
}
</script>
<template>
<div>
<!-- 按下Enter键 -->
<input @keyup.enter="submit" placeholder="按Enter提交">
<!-- 按下Delete或Backspace键 -->
<input @keyup.delete="handleDelete">
<!-- 常用按键别名 -->
<input @keyup.esc="handleEsc">
<input @keyup.space="handleSpace">
<input @keyup.tab="handleTab">
<input @keyup.up="handleUp">
<input @keyup.down="handleDown">
<!-- 使用键码 -->
<input @keyup.page-down="handlePageDown">
</div>
</template>
<script setup>
function submit() {
console.log('提交')
}
function handleDelete() {
console.log('删除')
}
function handleEsc() {
console.log('取消')
}
function handleSpace() {
console.log('空格')
}
function handleTab() {
console.log('Tab')
}
function handleUp() {
console.log('向上')
}
function handleDown() {
console.log('向下')
}
function handlePageDown() {
console.log('PageDown')
}
</script>
<template>
<div>
<!-- Ctrl + Click -->
<button @click.ctrl="handleCtrlClick">Ctrl+点击</button>
<!-- Alt + Enter -->
<input @keyup.alt.enter="handleAltEnter">
<!-- Shift + Click -->
<button @click.shift="handleShiftClick">Shift+点击</button>
<!-- Meta(Cmd/Win) + Click -->
<button @click.meta="handleMetaClick">Meta+点击</button>
<!-- .exact修饰符:精确匹配 -->
<button @click.ctrl.exact="handleCtrlOnly">只有Ctrl</button>
<button @click.exact="handleClickOnly">没有修饰键</button>
</div>
</template>
<script setup>
function handleCtrlClick() {
console.log('Ctrl + Click')
}
function handleAltEnter() {
console.log('Alt + Enter')
}
function handleShiftClick() {
console.log('Shift + Click')
}
function handleMetaClick() {
console.log('Meta + Click')
}
function handleCtrlOnly() {
console.log('只按了Ctrl')
}
function handleClickOnly() {
console.log('没有修饰键')
}
</script>
<template>
<div>
<button @click.left="handleLeftClick">左键点击</button>
<button @click.right="handleRightClick">右键点击</button>
<button @click.middle="handleMiddleClick">中键点击</button>
</div>
</template>
<script setup>
function handleLeftClick() {
console.log('左键')
}
function handleRightClick() {
console.log('右键')
}
function handleMiddleClick() {
console.log('中键')
}
</script>
<template>
<div>
<form @submit.prevent="handleSubmit">
<div>
<label>用户名:</label>
<input
v-model="form.username"
@blur="validateUsername"
@keyup.enter="handleSubmit"
>
<span v-if="errors.username">{{ errors.username }}</span>
</div>
<div>
<label>密码:</label>
<input
type="password"
v-model="form.password"
@blur="validatePassword"
>
<span v-if="errors.password">{{ errors.password }}</span>
</div>
<button type="submit">提交</button>
<button type="button" @click.stop="handleReset">重置</button>
</form>
</div>
</template>
<script setup>
import { reactive } from 'vue'
const form = reactive({
username: '',
password: ''
})
const errors = reactive({
username: '',
password: ''
})
function validateUsername() {
if (!form.username) {
errors.username = '用户名不能为空'
} else if (form.username.length < 3) {
errors.username = '用户名至少3个字符'
} else {
errors.username = ''
}
}
function validatePassword() {
if (!form.password) {
errors.password = '密码不能为空'
} else if (form.password.length < 6) {
errors.password = '密码至少6个字符'
} else {
errors.password = ''
}
}
function handleSubmit() {
validateUsername()
validatePassword()
if (!errors.username && !errors.password) {
console.log('提交表单', form)
alert('提交成功!')
}
}
function handleReset() {
form.username = ''
form.password = ''
errors.username = ''
errors.password = ''
}
</script>