Vue3 模板语法
目录
一、插值语法 {{ }}
二、核心指令
三、动态属性绑定
四、事件修饰符
五、条件渲染 vs 列表渲染总结
六、最佳实践
示例 1:插值语法 & 基础绑定
示例 2:条件渲染
示例 3:列表渲染
示例 4:事件处理
示例 5:动态绑定
示例 6:双向绑定
示例 7:综合实践
一、插值语法 {{ }}
-
作用:将数据绑定到 DOM 文本内容。
-
特性:
-
支持 JavaScript 表达式(如
{{ count + 1 }}
),但不支持语句(如if
)。 -
自动响应数据变化(数据驱动视图)。
-
-
示例:
<p>{{ message }}</p> <p>{{ user.name }}</p>
二、核心指令
-
条件渲染:
v-if
vsv-show
-
v-if
:-
根据条件销毁或创建元素。
-
适用于切换频率低的场景(如初始化渲染)。
-
支持
v-else
和v-else-if
。
-
-
v-show
:-
通过 CSS
display
控制显示/隐藏。 -
适用于频繁切换的场景(如选项卡)。
-
-
示例:
<div v-if="isVisible">v-if 内容</div> <div v-show="isActive">v-show 内容</div>
-
-
列表渲染:
v-for
-
作用:遍历数组或对象生成列表。
-
key
的作用:-
唯一标识:帮助 Vue 跟踪节点身份,优化复用逻辑。
-
避免问题:防止列表更新时出现错乱(如状态保留问题)。
-
-
最佳实践:
-
使用唯一 ID(如
:key="item.id"
)。 -
避免用
index
作为 key(除非列表静态且无排序)。
-
-
示例:
<ul><li v-for="item in items" :key="item.id">{{ item.name }}</li> </ul>
-
-
属性绑定:
v-bind
(简写:
)-
动态属性:将数据绑定到 HTML 属性(如
id
、class
)。 -
示例:
<img :src="imageUrl" /> <div :class="{ active: isActive }"></div>
-
-
事件绑定:
v-on
(简写@
)-
监听事件:如点击、输入等。
-
示例:
<button @click="handleClick">点击</button>
-
-
双向绑定:
v-model
-
作用:表单输入与数据的双向同步(语法糖 =
:value
+@input
)。 -
示例:
<input v-model="message" />
-
三、动态属性绑定
-
动态 Class(
:class
)-
对象语法:按条件添加类名。
<div :class="{ active: isActive, 'text-danger': hasError }"></div>
-
数组语法:绑定多个类名。
<div :class="[activeClass, errorClass]"></div>
-
-
动态 Style(
:style
)-
对象语法:绑定样式对象。
<div :style="{ color: textColor, fontSize: size + 'px' }"></div>
-
数组语法:组合多个样式对象。
<div :style="[baseStyles, overrideStyles]"></div>
-
四、事件修饰符
-
常用修饰符:
-
.stop
:阻止事件冒泡(等价于event.stopPropagation()
)。 -
.prevent
:阻止默认行为(等价于event.preventDefault()
)。 -
.once
:事件只触发一次。 -
.self
:仅当事件从元素自身触发时生效。
-
-
示例:
<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
<!-- 仅在 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>
包裹解决:<template v-for="item in items" :key="item.id"><div v-if="item.isVisible">{{ item.name }}</div> </template>
-
-
事件处理:
-
复杂逻辑应封装到方法中,避免内联表达式。
-
示例 1:插值语法 & 基础绑定
<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:条件渲染
<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:列表渲染
<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:事件处理
<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:动态绑定
<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:双向绑定
<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:综合实践
<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>