一、写在前面
如果说上一篇文章解决的是:
Vue3 项目是怎么跑起来的?
那么这一篇要解决的问题就是:
Vue3 页面到底怎么写?
很多新手刚接触 Vue3 时,最先感到陌生的并不是项目结构,而是模板里的这些写法:
<template>
<h1>{{ title }}</h1>
<img :src="imgUrl" />
<button @click="changeTitle">修改标题</button>
<p v-if="isShow">这是一段文字</p>
<li v-for="item in list" :key="item.id">{{ item.name }}</li>
</template>
你一眼看过去就会发现,Vue 模板不像纯 HTML:
-
多了
{``{ }} -
多了
: -
多了
@ -
多了
v-if -
多了
v-for
这些东西,本质上就是 Vue 模板语法 和 Vue 指令。
它们的作用只有一个:
让页面不再只是静态展示,而是能和数据、逻辑、交互联动起来。
所以这一篇文章,我们就把 Vue3 最常用、也是最基础的模板能力系统过一遍。
你学完这篇之后,至少要做到:
-
能看懂最基础的 Vue 页面
-
能自己写简单的数据展示和页面交互
-
能初步理解"数据驱动页面"到底是什么意思
二、什么是 Vue3 的模板语法?
先说最核心的一句话:
Vue 的模板,本质上是在 HTML 基础上,增加了一层"数据与逻辑绑定能力"。
也就是说,你写 Vue 页面时,外表看起来像 HTML,
但实际上它已经不是单纯的 HTML 了。
比如原生 HTML 里你可能会这样写一个标题:
<h1>你好,Vue3</h1>
这是静态内容,页面写死了就是"你好,Vue3"。
而在 Vue 里,你可以这样写:
<template>
<h1>{{ title }}</h1>
</template>
<script setup>
const title = '你好,Vue3'
</script>
这样标题内容就来自数据,而不是写死在页面里。
所以你可以把 Vue 模板理解成:
-
表面上是在写标签
-
实际上是在让标签和数据、逻辑建立联系
这就是 Vue 模板语法存在的意义。
三、插值表达式 {``{ }}:把数据显示到页面上
这是 Vue 模板里最基础、最常见的语法。
1. 基本写法
<template>
<h1>{{ message }}</h1>
</template>
<script setup>
const message = '欢迎学习 Vue3'
</script>
页面最终会显示:
欢迎学习 Vue3
这里的 {``{ message }} 就叫做 插值表达式。
它的作用非常直接:
把脚本里的数据插入到模板中显示出来。
2. 插值表达式能放什么?
通常可以放:
-
变量
-
简单表达式
-
字符串拼接
-
三元表达式
例如:
<template>
<p>{{ name }}</p>
<p>{{ age + 1 }}</p>
<p>{{ '姓名:' + name }}</p>
<p>{{ isLogin ? '已登录' : '未登录' }}</p>
</template>
<script setup>
const name = '张三'
const age = 20
const isLogin = true
</script>
这说明 {``{ }} 不只是"取变量",它本质上还能写一些简单表达式。
3. 插值表达式适合做什么?
最常见的用途包括:
-
显示标题
-
显示用户名
-
显示价格
-
显示状态文字
-
显示拼接后的内容
例如商品卡片:
<template>
<div>
<h2>{{ productName }}</h2>
<p>价格:{{ price }} 元</p>
</div>
</template>
<script setup>
const productName = '机械键盘'
const price = 299
</script>
4. 插值表达式不能乱写复杂逻辑
新手常见问题是:
把太多逻辑直接塞进 {``{ }} 里。
虽然简单表达式可以写,但不建议把复杂处理全写在模板中。
因为模板的核心职责还是"展示",而不是承担太重的逻辑计算。
所以你可以先建立一个习惯:
模板里尽量展示结果,不要堆太复杂的逻辑。
四、v-bind:给标签属性绑定动态数据
有了 {``{ }} 之后,很多人会自然想到一个问题:
如果我想动态修改标签的属性怎么办?
比如:
-
图片地址
src -
链接地址
href -
输入框的
value -
class
-
id
-
title
这时候就要用到 v-bind。
1. 基本写法
<template>
<img v-bind:src="imgUrl" />
</template>
<script setup>
const imgUrl = 'https://example.com/demo.png'
</script>
这里的意思就是:
把
imgUrl这个数据绑定到图片的src属性上。
2. 简写方式 :
v-bind 很常用,所以 Vue 提供了简写方式:
<template>
<img :src="imgUrl" />
</template>
这和下面是完全一样的:
<img v-bind:src="imgUrl" />
实际开发中,大家更常用简写形式,因为更简洁。
3. 常见使用场景
绑定链接地址
<template>
<a :href="url">点击跳转</a>
</template>
<script setup>
const url = 'https://vuejs.org/'
</script>
绑定标题提示
<template>
<button :title="tip">鼠标移入查看提示</button>
</template>
<script setup>
const tip = '这是一个按钮'
</script>
绑定 class 或 id
<template>
<div :class="className">内容区域</div>
</template>
<script setup>
const className = 'box'
</script>
4. {``{ }} 和 v-bind 的区别
这是新手特别容易混的地方。
{``{ }} 作用于标签内容
<h1>{{ title }}</h1>
表示标题内部显示数据。
v-bind 作用于标签属性
<img :src="imgUrl" />
表示标签属性由数据控制。
你可以简单记成:
-
显示文字内容 用
{``{ }} -
控制标签属性 用
v-bind
五、@click:事件绑定,让页面"动起来"
前面我们解决的是"数据怎么显示到页面",
接下来要解决的是:
用户点击按钮时,页面怎么响应?
这就要用到 Vue 的事件绑定。
1. 最常见的事件:点击事件
<template>
<button @click="showMessage">点我</button>
</template>
<script setup>
const showMessage = () => {
alert('你好,Vue3')
}
</script>
这里的 @click="showMessage" 表示:
当按钮被点击时,执行
showMessage这个函数。
2. @click 是什么?
它本质上可以理解为:
-
监听按钮点击事件
-
一旦点击,就执行你指定的方法
你也可以把它看成 v-on:click 的简写。
完整写法是:
<button v-on:click="showMessage">点我</button>
简写后就是:
<button @click="showMessage">点我</button>
实际开发中几乎都写简写形式。
3. 一个最基础的交互案例
<template>
<div>
<h1>{{ title }}</h1>
<button @click="changeTitle">修改标题</button>
</div>
</template>
<script setup>
import { ref } from 'vue'
const title = ref('你好,Vue3')
const changeTitle = () => {
title.value = '标题已经被修改'
}
</script>
当你点击按钮后,页面上的标题就会自动变化。
这个例子非常重要,因为它已经体现了 Vue 的核心思想:
修改数据,页面自动更新。
你没有手动去操作 DOM,没有写 document.querySelector,
只是改了数据,界面就跟着变了。
六、v-model:表单双向绑定
这是 Vue 初学阶段非常有代表性的一个指令。
它主要用于表单元素,比如:
-
输入框
-
文本域
-
单选框
-
复选框
-
下拉框
1. 最基础的输入框绑定
<template>
<div>
<input v-model="username" />
<p>你输入的是:{{ username }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const username = ref('')
</script>
当你在输入框里输入内容时,下面的文字会实时变化。
这说明:
-
输入框改了,数据变了
-
数据变了,页面也更新了
这就是所谓的 双向绑定。
2. 什么叫双向绑定?
可以把它拆成两个方向理解:
从数据到页面
如果 username 变了,输入框显示的内容也会跟着变。
从页面到数据
如果用户在输入框里输入内容,username 这个数据也会跟着变。
所以叫"双向绑定"。
3. 为什么 v-model 对新手很重要?
因为它特别直观,能让你第一次真正感受到:
页面和数据是联动的。
以前你写原生 JS,想获取输入框内容,可能要:
-
找 DOM
-
取值
-
手动处理
而在 Vue 里,一个 v-model 就把这些基础联动打通了。
七、v-if 和 v-show:控制元素显示与隐藏
页面开发里经常有这种需求:
-
登录后显示欢迎信息
-
没登录时显示登录按钮
-
点击按钮后展开内容
-
根据条件决定一段文字要不要出现
这时候就要用到条件渲染。
1. v-if 的基本写法
<template>
<p v-if="isShow">这段文字会显示</p>
</template>
<script setup>
const isShow = true
</script>
当 isShow 为 true 时,这段文字显示;
为 false 时,这段文字不显示。
2. 配合按钮切换显示状态
<template>
<div>
<button @click="toggleText">切换显示</button>
<p v-if="isShow">这是一段可切换显示的文字</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const isShow = ref(true)
const toggleText = () => {
isShow.value = !isShow.value
}
</script>
点击按钮后,文字会一会显示、一会消失。
3. v-show 的基本写法
<template>
<p v-show="isShow">这段文字也能切换显示</p>
</template>
它的表面效果和 v-if 很像,但底层处理方式不同。
4. v-if 和 v-show 的区别
这是一个非常高频的面试和基础问题。
v-if
是"真正决定这个元素要不要渲染"。
如果条件不成立,这个元素压根不会出现在页面结构中。
v-show
是"元素先存在,再通过样式控制是否显示"。
通常是通过 display: none 这种方式隐藏。
5. 怎么选?
你可以先这样理解:
-
切换不频繁 ,可以优先考虑
v-if -
切换很频繁 ,可以优先考虑
v-show
对新手来说,先记住核心区别就够了:
v-if更像"创建 / 删除元素",v-show更像"显示 / 隐藏元素"。
八、v-for:根据数据批量渲染列表
这是 Vue 页面开发中非常核心的能力。
因为真实项目里,很多内容都不是写死的,而是来自数组数据,比如:
-
学生名单
-
商品列表
-
消息列表
-
评论区
-
待办事项
这时候就要用 v-for 来循环渲染。
1. 最基础的列表渲染
<template>
<ul>
<li v-for="item in list" :key="item.id">
{{ item.name }}
</li>
</ul>
</template>
<script setup>
const list = [
{ id: 1, name: '语文' },
{ id: 2, name: '数学' },
{ id: 3, name: '英语' }
]
</script>
页面会显示一个列表:
-
语文
-
数学
-
英语
这里的意思是:
遍历
list数组,把每一项都渲染成一个li。
2. item in list 怎么理解?
可以理解成:
-
list是你要循环的数据源 -
item是每次循环拿到的当前项
也就是说,循环第一次时:
item = { id: 1, name: '语文' }
第二次时:
item = { id: 2, name: '数学' }
所以模板中写:
{{ item.name }}
就能依次显示每一项的名字。
3. 也可以拿到索引
<template>
<ul>
<li v-for="(item, index) in list" :key="item.id">
{{ index }} - {{ item.name }}
</li>
</ul>
</template>
这里的 index 就是当前项的下标。
九、为什么 v-for 一定要加 key?
这是新手最容易"会写但不理解"的一个点。
你会经常看到这样的写法:
<li v-for="item in list" :key="item.id">
{{ item.name }}
</li>
很多人知道要加 key,但不知道为什么。
1. key 的作用是什么?
简单说:
key是 Vue 用来识别每一项"身份"的标记。
当列表更新时,Vue 需要知道:
-
哪一项是旧的
-
哪一项是新的
-
哪一项被删除了
-
哪一项只是位置变了
这时候 key 就非常重要。
2. 为什么不能随便不写?
如果不写 key,或者乱写,Vue 在更新列表时就不容易精准识别每一项,
可能导致一些不必要的更新,甚至在复杂场景下出现显示异常。
所以你可以先记住一个非常实用的原则:
只要写
v-for,就尽量提供一个稳定、唯一的key。
最理想的 key 通常是数据自己的唯一 id。
例如:
:key="item.id"
3. 能不能用下标当 key?
可以写,但不推荐作为默认习惯。
因为下标会随着列表增删改查发生变化,
而 key 更适合使用"稳定不变的唯一标识"。
所以新手阶段你先养成一个好习惯:
-
有唯一 id,就优先用 id
-
不要一上来就默认写
index
十、一个综合小案例:把这些基础指令串起来
下面给你一个很适合初学者理解的综合案例。
<template>
<div class="box">
<h1>{{ title }}</h1>
<input v-model="newTask" placeholder="请输入任务内容" />
<button @click="addTask">添加任务</button>
<p v-if="list.length === 0">当前还没有任务</p>
<ul v-else>
<li v-for="item in list" :key="item.id">
{{ item.name }}
</li>
</ul>
</div>
</template>
<script setup>
import { ref } from 'vue'
const title = ref('我的待办列表')
const newTask = ref('')
const list = ref([
{ id: 1, name: '学习 Vue3' },
{ id: 2, name: '完成练习' }
])
const addTask = () => {
if (newTask.value.trim() === '') return
list.value.push({
id: Date.now(),
name: newTask.value
})
newTask.value = ''
}
</script>
<style scoped>
.box {
width: 400px;
margin: 20px auto;
}
</style>
这个案例里已经包含了很多基础点:
-
{``{ }}显示标题 -
v-model绑定输入框 -
@click绑定按钮事件 -
v-if判断列表是否为空 -
v-for渲染任务列表 -
:key标记每一项身份
你会发现,Vue3 的模板语法虽然看起来种类不少,
但本质上都是在围绕两件事展开:
-
页面显示什么
-
页面怎么根据数据变化而变化
十一、新手最常见的错误
这一部分非常重要,因为很多初学者不是"完全不会",而是容易在小地方出错。
1. 把 {``{ }} 用到属性里
错误写法:
<img src="{{ imgUrl }}" />
这是不对的。
正确写法应该是:
<img :src="imgUrl" />
记住:
-
标签内容用
{``{ }} -
标签属性用
v-bind或:
2. 事件里直接写错函数名
例如模板里写:
<button @click="changeName">按钮</button>
但脚本里没有定义 changeName,页面点击就会报错。
所以事件绑定时,一定要确认函数真的存在。
3. v-for 忘了写 key
虽然有时候页面也能显示,但这不是好习惯。
从一开始就养成规范写法,后面会省很多事。
4. v-if 和 v-for 一起乱用
新手前期经常在同一个标签上同时写很多复杂逻辑,结果自己把自己绕晕。
前期建议你先把逻辑拆开,写清楚,别急着一口气写太多。
5. 还没理解"数据驱动页面"
很多新手写 Vue 时,脑子里仍然在想:
- 我要怎么手动改页面内容?
但 Vue 的思路是:
先改数据,页面自己更新。
这个思维一定要尽早切换过来。
十二、这一篇你到底要掌握到什么程度?
学完这一篇,你不需要立刻变得很熟练,
但至少应该做到下面这些事:
-
能用
{``{ }}把数据显示到页面 -
能用
v-bind绑定图片、链接等属性 -
能用
@click给按钮绑定事件 -
能用
v-model做输入框双向绑定 -
能用
v-if / v-show控制内容显示隐藏 -
能用
v-for渲染列表 -
知道
key不能随便省略
如果这些你已经能独立敲出来,那说明你已经真正迈进 Vue3 模板层的门了。
十三、总结
这一篇文章,我们把 Vue3 最常用的模板语法和基础指令系统过了一遍。
核心内容其实可以浓缩成下面几句话:
-
{``{ }}:把数据显示到页面内容中 -
v-bind/::把数据绑定到标签属性上 -
@click:给页面元素绑定事件 -
v-model:实现表单双向绑定 -
v-if / v-show:控制元素显示与隐藏 -
v-for:根据数组数据批量渲染页面 -
key:给列表中的每一项一个稳定身份标识
如果说 Vue3 最核心的思想之一是"数据驱动视图",
那么这一篇,其实就是你第一次真正开始把这个思想落实到代码里。
因为从现在开始,你写页面时,思路不再只是:
- 页面长什么样
而要开始变成:
-
页面显示哪些数据
-
数据变化时页面如何自动更新
-
用户操作后数据怎么联动变化
这就是 Vue 开始和普通静态页面拉开差距的地方。