事件处理与双向绑定:v-model 原理

事件处理与双向绑定:v-model 原理

上篇讲了 v-model 用法,这篇深入一点,说说事件处理和 v-model 的底层原理。

事件处理基础

@ 绑定事件:

<template>
  <button @click="handleClick">点击</button>
</template>

<script setup>
function handleClick() {
  console.log('点击了')
}
</script>

带参数:

<template>
  <button @click="handleClick('参数', $event)">
    点击传参
  </button>
</template>

<script setup>
function handleClick(msg, event) {
  console.log(msg, event)
}
</script>

$event 是原生事件对象。

事件修饰符

常用修饰符:

<!-- 阻止冒泡 -->
<button @click.stop="handleClick">停止</button>

<!-- 阻止默认行为 -->
<form @submit.prevent="handleSubmit">提交</form>

<!-- 只触发一次 -->
<button @click.once="doOnce">只执行一次</button>

<!-- 捕获模式 -->
<div @click.capture="handleCapture">捕获</div>

<!-- 键盘事件 -->
<input @keyup.enter="submit" />
<input @keyup.esc="cancel" />

可以串联多个修饰符:@click.stop.prevent

v-model 的原理

v-model 本质上是两个指令的组合。

文本输入框

<!-- v-model 等同于: -->
<input :value="message" @input="message = $event.target.value" />

即::value 绑定数据 + @input 更新数据。

复选框

<template>
  <!-- v-model -->
  <input type="checkbox" v-model="checked" />

  <!-- 等同于 -->
  <input
    type="checkbox"
    :checked="checked"
    @change="checked = $event.target.checked"
  />
</template>

<script setup>
const checked = ref(false)
</script>

v-model 修饰符

.trim

自动去除首尾空格:

<input v-model.trim="username" />

.number

自动转成数字:

<input v-model.number="age" />

.lazy

input 事件变成 change 事件,失去焦点才更新:

<input v-model.lazy="message" />

常见的表单绑定场景

文本框

<input v-model="text" />
<p>{{ text }}</p>

多行文本

<textarea v-model="message"></textarea>

复选框(单个)

<input type="checkbox" v-model="agree" />
<span v-if="agree">已同意</span>

复选框(多个)

<template>
  <label v-for="hobby in hobbies" :key="hobby.value">
    <input type="checkbox" :value="hobby.value" v-model="selected" />
    {{ hobby.label }}
  </label>
  <p>已选:{{ selected }}</p>
</template>

<script setup>
const hobbies = [
  { label: '读书', value: 'reading' },
  { label: '运动', value: 'sport' },
  { label: '音乐', value: 'music' }
]
const selected = ref([])
</script>

单选框

<input type="radio" value="A" v-model="choice" />
<input type="radio" value="B" v-model="choice" />

选择框

<select v-model="city">
  <option value="bj">北京</option>
  <option value="sh">上海</option>
  <option value="sz">深圳</option>
</select>

多选加 multiple

<select v-model="cities" multiple>
  <option value="bj">北京</option>
  <option value="sh">上海</option>
</select>

总结

  • @事件名 绑定事件处理函数
  • 事件修饰符:.stop.prevent.enter
  • v-model = :value + @input,或者 :checked + @change
  • 修饰符:.trim.number.lazy

下篇说组件,怎么把模板、逻辑、样式封装成一个可复用的组件。

最后更新 4/30/2026, 8:57:45 AM