Appearance
模板渲染与事件处理
在 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" |
.tab | Tab 键 | @keyup.tab="handleTab" |
.delete | 删除键 | @keyup.delete="handleDelete" |
.esc | Esc 键 | @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"> 选项2javascript
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 应用的基础,将帮助我们创建更加灵活和响应式的用户界面。
