目录
[一、插值语法 {{ }}](#一、插值语法 {{ }})
[五、条件渲染 vs 列表渲染总结](#五、条件渲染 vs 列表渲染总结)
[示例 1:插值语法 & 基础绑定](#示例 1:插值语法 & 基础绑定)
[示例 2:条件渲染](#示例 2:条件渲染)
[示例 3:列表渲染](#示例 3:列表渲染)
[示例 4:事件处理](#示例 4:事件处理)
[示例 5:动态绑定](#示例 5:动态绑定)
[示例 6:双向绑定](#示例 6:双向绑定)
[示例 7:综合实践](#示例 7:综合实践)
一、插值语法 {``{ }}
-
作用:将数据绑定到 DOM 文本内容。
-
特性:
-
支持 JavaScript 表达式(如
{``{ count + 1 }}
),但不支持语句(如if
)。 -
自动响应数据变化(数据驱动视图)。
-
-
示例:
html<p>{{ message }}</p> <p>{{ user.name }}</p>
二、核心指令
-
条件渲染:
v-if
vsv-show
-
v-if
:-
根据条件销毁或创建元素。
-
适用于切换频率低的场景(如初始化渲染)。
-
支持
v-else
和v-else-if
。
-
-
v-show
:-
通过 CSS
display
控制显示/隐藏。 -
适用于频繁切换的场景(如选项卡)。
-
-
示例:
html<div v-if="isVisible">v-if 内容</div> <div v-show="isActive">v-show 内容</div>
-
-
列表渲染:
v-for
-
作用:遍历数组或对象生成列表。
-
key
的作用:-
唯一标识:帮助 Vue 跟踪节点身份,优化复用逻辑。
-
避免问题:防止列表更新时出现错乱(如状态保留问题)。
-
-
最佳实践:
-
使用唯一 ID (如
:key="item.id"
)。 -
避免用
index
作为 key(除非列表静态且无排序)。
-
-
示例:
html<ul> <li v-for="item in items" :key="item.id">{{ item.name }}</li> </ul>
-
-
属性绑定:
v-bind
(简写:
)-
动态属性 :将数据绑定到 HTML 属性(如
id
、class
)。 -
示例:
html<img :src="imageUrl" /> <div :class="{ active: isActive }"></div>
-
-
事件绑定:
v-on
(简写@
)-
监听事件:如点击、输入等。
-
示例:
html<button @click="handleClick">点击</button>
-
-
双向绑定:
v-model
-
作用 :表单输入与数据的双向同步(语法糖 =
:value
+@input
)。 -
示例:
html<input v-model="message" />
-
三、动态属性绑定
-
动态 Class(
:class
)-
对象语法:按条件添加类名。
html<div :class="{ active: isActive, 'text-danger': hasError }"></div>
-
数组语法:绑定多个类名。
html<div :class="[activeClass, errorClass]"></div>
-
-
动态 Style(
:style
)-
对象语法:绑定样式对象。
html<div :style="{ color: textColor, fontSize: size + 'px' }"></div>
-
数组语法:组合多个样式对象。
html<div :style="[baseStyles, overrideStyles]"></div>
-
四、事件修饰符
-
常用修饰符:
-
.stop
:阻止事件冒泡(等价于event.stopPropagation()
)。 -
.prevent
:阻止默认行为(等价于event.preventDefault()
)。 -
.once
:事件只触发一次。 -
.self
:仅当事件从元素自身触发时生效。
-
-
示例:
html<button @click.stop="handleClick">阻止冒泡</button> <form @submit.prevent="handleSubmit">阻止默认提交</form>
-
按键修饰符:
按键别名:
Vue 为一些常用的按键提供了别名:
.enter
.tab
.delete
(捕获"Delete"和"Backspace"两个按键).esc
.space
.up
.down
.left
.right
系统按键修饰符:
你可以使用以下系统按键修饰符来触发鼠标或键盘事件监听器,只有当按键被按下时才会触发。
.ctrl
.alt
.shift
.meta
html
<!-- 仅在 key 为 Enter 时调用 submit -->
<input @keyup.enter="submit" />
<!-- Alt + Enter -->
<input @keyup.alt.enter="clear" />
<!-- Ctrl + 点击 -->
<div @click.ctrl="doSomething">Do something</div>
五、条件渲染 vs 列表渲染总结
特性 | v-if |
v-show |
v-for (需 key ) |
---|---|---|---|
渲染方式 | 条件为假时销毁元素 | 始终渲染,切换 CSS | 动态生成列表项 |
性能 | 初始渲染开销低 | 切换开销低 | 列表变化时依赖 key 优化 |
适用场景 | 不频繁切换的条件 | 频繁显示/隐藏 | 动态列表数据 |
六、最佳实践
-
v-for
的key
:-
始终使用唯一标识(如数据库 ID)。
-
避免
index
,除非列表简单且无状态。
-
-
v-if
与v-for
优先级:-
避免在同一个元素上同时使用(Vue3 中
v-if
优先级更高)。 -
使用
<template>
包裹解决:html<template v-for="item in items" :key="item.id"> <div v-if="item.isVisible">{{ item.name }}</div> </template>
-
-
事件处理:
- 复杂逻辑应封装到方法中,避免内联表达式。
示例 1:插值语法 & 基础绑定
html
<template>
<!-- 文本插值 -->
<p>{{ message }}</p>
<!-- JavaScript 表达式 -->
<p>{{ count + 1 }}</p>
<!-- 属性绑定 -->
<a :href="'https://vuejs.org'">官网链接</a>
</template>
<script setup>
import { ref } from 'vue'
const message = ref('Hello Vue3!')
const count = ref(0)
</script>
示例 2:条件渲染
html
<template>
<!-- v-if 链式判断 -->
<div>
<p v-if="score >= 90">优秀</p>
<p v-else-if="score >= 60">合格</p>
<p v-else>不合格</p>
</div>
<!-- v-show 切换 -->
<button @click="showA = !showA">切换显示</button>
<div v-show="showA">显示/隐藏内容</div>
</template>
<script setup>
import { ref } from 'vue'
const showA = ref(true)
const score = ref(85)
</script>
示例 3:列表渲染
html
<template>
<!-- 带 key 的列表渲染 -->
<ul>
<li
v-for="(item, index) in books"
:key="item.id"
>
{{ index + 1 }}. {{ item.title }}
</li>
</ul>
<!-- 动态添加项 -->
<input v-model="newBook">
<button @click="books.push({
id: Date.now(),
title: newBook
})">添加书籍</button>
</template>
<script setup>
import { ref } from 'vue'
const books = ref([
{ id: 'b1', title: 'Vue3 入门' },
{ id: 'b2', title: 'TypeScript 进阶' }
])
const newBook = ref('')
</script>
示例 4:事件处理
html
<template>
<!-- 内联事件处理 -->
<button @click="handleClick('按钮点击')">点击事件</button>
<!-- 事件修饰符 -->
<div @click.self="console.log('父元素点击')">
<button @click.stop="console.log('子元素点击')">
阻止冒泡
</button>
</div>
<!-- 按键修饰符 -->
<input
@keyup.enter="console.log('回车按下')"
@keyup.esc="console.log('ESC 按下')"
>
</template>
<script setup>
function handleClick(msg) {
alert(msg)
}
function handleKeyup(e) {
console.log('按键码:', e.keyCode)
}
</script>
示例 5:动态绑定
html
<template>
<!-- 动态 class (对象语法) -->
<div :class="{ active: isActive, 'text-danger': false }">
动态类名
</div>
<!-- 动态 style (数组语法) -->
<div :style="[
{ color: errorColor },
styleObject
]">
动态样式
</div>
</template>
<script setup>
import { ref } from 'vue'
const isActive = ref(true)
const errorColor = ref('red')
const styleObject = ref({
fontSize: '20px',
fontWeight: 'bold'
})
</script>
示例 6:双向绑定
html
<template>
<!-- 文本输入 -->
<input v-model="text" placeholder="输入内容">
<!-- 复选框 -->
<input type="checkbox" v-model="checked">
<!-- 单选按钮 -->
<select v-model="selectedOption">
<option value="A">选项A</option>
<option value="B">选项B</option>
</select>
</template>
<script setup>
import { ref } from 'vue'
const text = ref('')
const checked = ref(false)
const selectedOption = ref('A')
</script>
示例 7:综合实践
html
<template>
<!-- 条件渲染 + 列表渲染 -->
<div v-if="activeTodos.length > 0">
<h3>待办事项 ({{ activeTodos.length }})</h3>
<ul>
<li
v-for="todo in activeTodos"
:key="todo.id"
:class="{ completed: todo.done }"
>
{{ todo.text }}
<button @click="todo.done = true">完成</button>
</li>
</ul>
</div>
<p v-else>全部任务已完成!🎉</p>
<!-- 双向绑定 + 事件修饰符 -->
<form @submit.prevent="addTodo">
<input
v-model.trim="newTodo"
@keyup.enter="addTodo"
>
<button type="submit">添加</button>
</form>
</template>
<script setup>
import { ref, computed } from 'vue'
const todos = ref([
{ id: 1, text: '学习 Vue3', done: true },
{ id: 2, text: '掌握组合式API', done: false }
])
const newTodo = ref('')
const activeTodos = computed(() =>
todos.value.filter(t => !t.done)
)
function addTodo() {
if (newTodo.value.trim()) {
todos.value.push({
id: Date.now(),
text: newTodo.value,
done: false
})
newTodo.value = ''
}
}
</script>