Skip to content

模板渲染与事件处理

在 Vue3 中,模板渲染和事件处理是构建交互式应用的核心部分。本章将介绍 Vue3 中的模板渲染技巧和事件处理方法。

列表渲染

v-for 指令

v-for 指令用于基于数组渲染列表。

基本用法

vue
<template>
  <ul>
    <li v-for="item in items" :key="item.id">
      {{ item.name }}
    </li>
  </ul>
</template>

<script setup>
import { ref } from 'vue'

const items = ref([
  { id: 1, name: '苹果' },
  { id: 2, name: '香蕉' },
  { id: 3, name: '橙子' }
])
</script>

key 值的作用

key 属性是 Vue 用于识别列表项的唯一标识,它可以帮助 Vue 更高效地更新 DOM。

为什么需要 key?

  • 当列表项顺序变化时,Vue 可以根据 key 来跟踪每个元素的身份,避免不必要的 DOM 操作
  • 提高渲染性能,特别是在大型列表中
  • 避免子组件状态混乱

如何选择 key?

  • 优先使用唯一且稳定的 ID,如数据库中的 ID
  • 避免使用索引作为 key,特别是当列表项可能被重新排序时
  • 确保 key 在列表中是唯一的

事件处理

v-on 指令

v-on 指令用于绑定事件监听器,简写为 @

基本用法

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

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

事件修饰符

Vue 提供了多种事件修饰符,用于简化事件处理逻辑。

常用事件修饰符

修饰符作用示例
.stop阻止事件冒泡@click.stop="handleClick"
.prevent阻止默认行为@submit.prevent="handleSubmit"
.capture使用捕获模式@click.capture="handleClick"
.self仅当事件目标是元素本身时触发@click.self="handleClick"
.once事件只触发一次@click.once="handleClick"
.passive告诉浏览器事件监听器不会调用 preventDefault@scroll.passive="handleScroll"

示例

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

  <!-- 阻止冒泡 -->
  <div @click="handleDivClick">
    <button @click.stop="handleButtonClick">点击我</button>
  </div>

  <!-- 只触发一次 -->
  <button @click.once="handleClickOnce">只点击一次</button>
</template>

<script setup>
function handleSubmit() {
  console.log('表单提交')
}

function handleDivClick() {
  console.log('div 被点击')
}

function handleButtonClick() {
  console.log('按钮被点击')
}

function handleClickOnce() {
  console.log('只点击一次')
}
</script>

按键修饰符

按键修饰符用于监听特定按键的事件。

常用按键修饰符

修饰符对应按键示例
.enter回车键@keyup.enter="handleEnter"
.tabTab 键@keyup.tab="handleTab"
.delete删除键@keyup.delete="handleDelete"
.escEsc 键@keyup.esc="handleEsc"
.space空格键@keyup.space="handleSpace"
.up上箭头@keyup.up="handleUp"
.down下箭头@keyup.down="handleDown"
.left左箭头@keyup.left="handleLeft"
.right右箭头@keyup.right="handleRight"

示例

vue
<template>
  <input @keyup.enter="handleEnter" placeholder="按回车键提交">
  <input @keyup.esc="handleEsc" placeholder="按 Esc 键取消">
</template>

<script setup>
function handleEnter() {
  console.log('按了回车键')
}

function handleEsc() {
  console.log('按了 Esc 键')
}
</script>

表单输入绑定

v-model 指令

v-model 指令用于在表单元素和数据之间创建双向绑定。

基本用法

vue
<template>
  <input v-model="message" placeholder="输入消息">
  <p>你输入的消息: {{ message }}</p>
</template>

<script setup>
import { ref } from 'vue'

const message = ref('')
</script>

不同表单元素的 v-model

文本输入框
vue
<input v-model="text" type="text">
多行文本框
vue
<textarea v-model="textarea"></textarea>
复选框
vue
<!-- 单个复选框 -->
<input v-model="checked" type="checkbox">

<!-- 多个复选框 -->
<input v-model="checkedNames" type="checkbox" value="张三"> 张三
<input v-model="checkedNames" type="checkbox" value="李四"> 李四
<input v-model="checkedNames" type="checkbox" value="王五"> 王五
javascript
import { ref } from 'vue'

// 单个复选框
const checked = ref(false)

// 多个复选框
const checkedNames = ref([])
单选按钮
vue
<input v-model="picked" type="radio" value="选项1"> 选项1
<input v-model="picked" type="radio" value="选项2"> 选项2
javascript
import { ref } from 'vue'

const picked = ref('选项1')
下拉框
vue
<select v-model="selected">
  <option value="">请选择</option>
  <option value="选项1">选项1</option>
  <option value="选项2">选项2</option>
  <option value="选项3">选项3</option>
</select>
javascript
import { ref } from 'vue'

const selected = ref('')

v-model 修饰符

常用修饰符

修饰符作用示例
.lazy在 change 事件中更新数据v-model.lazy="message"
.number将输入值转换为数字v-model.number="age"
.trim去除输入值的首尾空格v-model.trim="message"

示例

vue
<template>
  <!-- 懒加载,在失去焦点时更新 -->
  <input v-model.lazy="message" placeholder="输入消息">
  
  <!-- 转换为数字 -->
  <input v-model.number="age" type="number" placeholder="输入年龄">
  
  <!-- 去除首尾空格 -->
  <input v-model.trim="name" placeholder="输入姓名">
</template>

<script setup>
import { ref } from 'vue'

const message = ref('')
const age = ref(0)
const name = ref('')
</script>

实战示例

待办事项列表

vue
<template>
  <div>
    <h2>待办事项列表</h2>
    
    <!-- 添加待办事项 -->
    <form @submit.prevent="addTodo">
      <input v-model="newTodo" placeholder="输入待办事项" />
      <button type="submit">添加</button>
    </form>
    
    <!-- 待办事项列表 -->
    <ul>
      <li v-for="todo in todos" :key="todo.id">
        <input 
          type="checkbox" 
          v-model="todo.completed"
          @change="updateTodo(todo)"
        />
        <span :class="{ completed: todo.completed }">{{ todo.text }}</span>
        <button @click="deleteTodo(todo.id)">删除</button>
      </li>
    </ul>
    
    <!-- 统计信息 -->
    <p>已完成: {{ completedCount }} / 总计: {{ todos.length }}</p>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue'

// 待办事项列表
const todos = ref([
  { id: 1, text: '学习 Vue3', completed: false },
  { id: 2, text: '完成作业', completed: true },
  { id: 3, text: '运动', completed: false }
])

// 新待办事项
const newTodo = ref('')

// 计算已完成的待办事项数量
const completedCount = computed(() => {
  return todos.value.filter(todo => todo.completed).length
})

// 添加待办事项
function addTodo() {
  if (newTodo.value.trim()) {
    todos.value.push({
      id: Date.now(),
      text: newTodo.value.trim(),
      completed: false
    })
    newTodo.value = ''
  }
}

// 更新待办事项
function updateTodo(todo) {
  console.log('更新待办事项:', todo)
}

// 删除待办事项
function deleteTodo(id) {
  todos.value = todos.value.filter(todo => todo.id !== id)
}
</script>

<style scoped>
.completed {
  text-decoration: line-through;
  color: #999;
}
</style>

通过本章的学习,我们掌握了 Vue3 中的模板渲染和事件处理技巧,包括列表渲染、事件修饰符、按键修饰符和表单输入绑定等。这些技能是构建交互式 Vue 应用的基础,将帮助我们创建更加灵活和响应式的用户界面。

© 2026 编程马·菜鸟教程 版权所有