大家好,我是程序员柏风,AI 最全的 Vibecoding 学习地图 http://coderoadmap.cn 作者。
模板与指令
这一课你将能做到
- 用
{{ }}插值把数据渲染到页面 - 用
v-bind动态绑定 HTML 属性 - 用
v-if/v-show控制元素显隐,并知道何时用哪个 - 用
v-for渲染列表,理解key的作用 - 用
v-on绑定事件,掌握常用事件修饰符
为什么要学
模板是 Vue 的「视图层」。你写的 HTML 不再是死的,而是能根据数据动态变化。指令(directive)就是 Vue 给 HTML 加的「超能力属性」,让标签会思考。
人话:指令就像 HTML 标签的「遥控器」。v-if 是开关,v-for 是复印机,v-bind 是变色龙,v-on 是门铃。
先建立图像
<script setup>
import { ref } from 'vue'
const show = ref(true)
const list = ref(['苹果', '香蕉', '橙子'])
</script>
<template>
<button @click="show = !show">切换</button>
<p v-if="show">我出现了</p>
<ul>
<li v-for="(item, i) in list" :key="i">{{ i + 1 }}. {{ item }}</li>
</ul>
</template>
渲染结果:
[切换]
我出现了
1. 苹果
2. 香蕉
3. 橙子
跟着做
步骤 1:插值与表达式
<script setup>
import { ref } from 'vue'
const name = ref('Vue')
const num = ref(10)
</script>
<template>
<p>{{ name }}</p>
<p>{{ num * 2 }}</p>
<p>{{ num > 5 ? '大' : '小' }}</p>
</template>
{{ }} 里可以写任意 JS 表达式,但不能写语句(如 if、for)。
步骤 2:v-bind 绑定属性
<script setup>
import { ref } from 'vue'
const url = ref('https://vuejs.org')
const isActive = ref(true)
</script>
<template>
<a :href="url">官网</a>
<p :class="{ active: isActive }">动态 class</p>
<p :style="{ color: 'red', fontSize: '20px' }">动态 style</p>
</template>
v-bind: 简写为 :。:class 支持对象/数组语法,非常强大。
步骤 3:v-if vs v-show
<script setup>
import { ref } from 'vue'
const type = ref('A')
const visible = ref(true)
</script>
<template>
<p v-if="type === 'A'">A 分支</p>
<p v-else-if="type === 'B'">B 分支</p>
<p v-else>其他分支</p>
<p v-show="visible">v-show 控制</p>
</template>
v-if:真正创建/销毁 DOM,切换开销大,适合条件很少变的场景v-show:只是display: none,频繁切换用它
步骤 4:v-for 列表渲染
<script setup>
import { ref } from 'vue'
const users = ref([
{ id: 1, name: '张三' },
{ id: 2, name: '李四' }
])
</script>
<template>
<div v-for="user in users" :key="user.id">
{{ user.name }}
</div>
</template>
:key 必须是唯一且稳定的值,帮助 Vue 高效复用 DOM。
步骤 5:v-on 与事件修饰符
<script setup>
function handleClick(e) {
console.log('点击了', e.target)
}
function handleSubmit() {
console.log('表单提交')
}
</script>
<template>
<button @click="handleClick">普通点击</button>
<form @submit.prevent="handleSubmit">
<button type="submit">提交</button>
</form>
<input @keyup.enter="handleSubmit" placeholder="回车提交">
</template>
常用修饰符:.prevent 阻止默认行为、.stop 阻止冒泡、.enter 回车键、.once 只触发一次。
讲清楚要点
- 插值
{{ }}:把数据渲染为文本,自动转义 HTML(防 XSS)。 v-bind(简写:):把数据绑定到属性,属性值是 JS 表达式。- **
v-on(简写@)**:绑定事件,方法写在<script setup>` 里。 v-if是惰性渲染:条件为假时 DOM 不存在;v-show始终渲染,只是隐藏。v-for的key:不要用index当 key(除非列表静态),用数据唯一 id。- 事件修饰符:链式调用,如
@click.stop.prevent。
你可能会懵的地方
-
v-if和v-for能写在同一个标签上吗? 不推荐。v-if优先级高于v-for,但一起写可读性差。通常先计算过滤后的列表,再v-for。 -
{{ }}里能调用方法吗? 能,如{{ formatDate(date) }},但每次渲染都会执行,复杂逻辑用computed更好。 -
v-html是干嘛的? 把数据作为 HTML 渲染,有 XSS 风险,除非内容可信,否则别用。 -
修饰符是什么原理? Vue 在编译时把修饰符转成对应的事件处理逻辑,如
.prevent生成e.preventDefault()。 -
为什么
:key不能用 index? 列表顺序变化时,index 作为 key 会导致 Vue 错误复用 DOM,产生 bug。
错法对照
| 错法 | 问题 | 正解 |
|---|---|---|
v-if="show" 和 v-for 同标签 | 优先级混乱,可读性差 | 先过滤数据,再循环 |
v-for 不加 :key | 控制台警告,更新异常 | 加唯一 :key |
{{ if (x) { ... } }} | 插值里不能写语句 | 用方法或计算属性 |
v-bind:href="url" 写成 href="{{ url }}" | 属性不能用插值 | 用 :href="url" |
用 v-show 做权限控制 | DOM 里仍存在,可被查看 | 用 v-if 真正移除 |
卡点急救
- 页面不更新:检查是否用
ref声明数据,普通变量不会触发响应式。 v-for报错:确认:key已添加且唯一。- 事件没反应:检查方法名拼写,确认方法在
<script setup>顶层定义。
面试常问
-
v-if和v-show的区别和使用场景?v-if有更高的切换开销,v-show有更高的初始渲染开销。频繁切换用v-show,条件很少改变用v-if。 -
v-for为什么要加key?key是 Vue 虚拟 DOM diff 算法的「身份证」,帮助识别节点身份,高效复用和重排 DOM。 -
v-model是什么? 语法糖,等价于:value="x" @input="x = $event.target.value",下一课表单详解。
自测三问
v-if和v-show在 DOM 层面的区别?v-for的:key为什么不能用 index?@click.stop.prevent中两个修饰符分别做什么?
小结一句话
指令让 HTML 从「静态标签」变成「动态视图」,掌握插值、属性绑定、条件渲染、列表渲染和事件处理,就掌握了 Vue 模板的核心。
延伸
- Vue 官方文档 - 模板语法
- 下一课:组件系统——props、emits、slots。