文章目录
-
- 一、插值语法
- 二、指令(Directives)
模板语法就是教你在 HTML 标签里怎么去写 Vue 的控制逻辑。
一、插值语法
使用双大括号 {``{ }} 将 JS 变量或表达式直接嵌入到 HTML 文字中。
html
<p>当前登录用户:{{ username }}</p>
<p>加急工单翻倍数量:{{ count * 2 }}</p>
二、指令(Directives)
指令是带有 v- 前缀的特殊属性,负责给 HTML 标签赋予动态超能力。
1. v-bind:给属性装上"动态天线"
传统的 HTML 属性是死板 的(比如 <img src="a.jpg">),它只能认字符串。
v-bind 的作用就是给属性装上一根天线,让它可以接收 JS 里的变量。只要变量一变,属性的值跟着变。
- 简写 :直接把
v-bind:简写成一个冒号:。
案例
假设我们要做一个"用户主页卡片",用户的头像、主页链接,甚至是不是 VIP 的样式,都是动态从后端获取的:
html
<script setup>
import { ref } from 'vue'
const avatarUrl = ref('https://vuejs.org/images/logo.png')
const profileUrl = ref('https://vuejs.org/guide/introduction.html')
const isVip = ref(true) // 是否是 VIP 用户
</script>
<template>
<div class="user-card">
<img :src="avatarUrl" alt="用户头像" />
<a :href="profileUrl">点击查看个人主页</a>
<div :class="{ 'vip-style': isVip, 'normal-style': !isVip }">
会员状态:{{ isVip ? '尊贵VIP' : '普通用户' }}
</div>
</div>
</template>
<style scoped>
.vip-style {
color: gold;
border: 2px solid gold;
padding: 10px;
}
.normal-style {
color: #333;
}
</style>
2. v-on:网页的"神经末梢"
用户在网页上的所有动作(点击、打字、鼠标悬停、回车),Vue 都想监听到。v-on 就是网页的神经末梢。
- 简写 :把
v-on:简写成@。
案例
做一个简单的"点赞与计数"功能,带上传参和阻止默认事件:
html
<script setup>
import { ref } from 'vue'
const likes = ref(0)
// 1. 无参数方法
function addLike() {
likes.value++
}
// 2. 带参数方法
function deleteItem(itemName) {
alert(`删除了:${itemName}`)
}
// 3. 事件修饰符方法
function handleFormSubmit() {
alert('表单提交成功(页面没有刷新!)')
}
</script>
<template>
<div class="box">
<button @click="addLike">点赞 ({{ likes }})</button>
<button @click="deleteItem('大西瓜')">删除西瓜</button>
<form @submit.prevent="handleFormSubmit">
<input type="text" placeholder="输入内容" />
<button type="submit">提交表单</button>
</form>
</div>
</template>
3. v-if vs v-show:网页元素的"生死"与"隐身"
这两个指令看起来效果一模一样(都是让东西显示/隐藏),但底层逻辑天差地别:
-
v-if是"肉体毁灭":条件为 false 时,Vue 直接把这个 HTML 标签从网页里拔掉,在 F12 开发者工具里连渣都不剩。 -
v-show是"物理隐身":不管真假,标签永远都在网页里。假的时候,Vue 只是偷偷给它加了 CSS 样式:display: none;。
案例
html
<script setup>
import { ref } from 'vue'
const isLogged = ref(false) // 登录状态
const showMenu = ref(false) // 菜单显示状态
function toggleLogin() { isLogged.value = !isLogged.value }
function toggleMenu() { showMenu.value = !showMenu.value }
</script>
<template>
<div class="container">
<button @click="toggleLogin">切换登录状态</button>
<button @click="toggleMenu">切换菜单显示</button>
<hr />
<div v-if="isLogged" class="admin-panel">
<h3>敏感数据后台</h3>
<p>只有登录后,这段 HTML 才会创建出来。</p>
</div>
<div v-else>
<p>请先登录...</p>
</div>
<ul v-show="showMenu" class="menu-list">
<li>首页</li>
<li>关于我们</li>
<li>联系我们</li>
</ul>
</div>
</template>
总结:
频繁切换?用
v-show(省去创建/销毁的性能开销)。运行后很少改变,或者涉及权限安全?用
v-if(不满足条件时压根不渲染,初次加载快,且安全)。
4. v-for:无情的"复印机"
v-for 就是个循环复印机,拿着一个数组,按照你写的模板一遍遍地把数据"印"在网页上。
- 口诀 :
v-for="(每一项, 下标) in 数组" :key="唯一标识"
为什么必须绑定 :key?
Vue 在更新网页时用的是虚拟 DOM 比对(Diff 算法)。
想象一下,网页上有 3 个输入框(张三、李四、王五)。如果没有 :key(身份证号),当你把"李四"删掉时,Vue 只知道"少了一个框",它会图省事直接把第 3 个框(王五)删掉,然后把第 2 个框的内容改成王五。这就会导致:如果你在李四的输入框里打了字,删掉李四后,那些字会莫名其妙错位跑到王五的框里去!
有了 :key="item.id",Vue 就能精准识别:"哦,李四彻底消失了,王五只是往上挪了一位,位置保留。"
案例
html
<script setup>
import { ref } from 'vue'
// 模拟待办事项列表,每个事项都有一个唯一的 id
const todoList = ref([
{ id: 101, text: '学习 Vue3 基础' },
{ id: 102, text: '去健身房跑步' },
{ id: 103, text: '给女朋友买礼物' }
])
function deleteTodo(id) {
// 过滤掉被删除的 id
todoList.value = todoList.value.filter(item => item.id !== id)
}
</script>
<template>
<div class="todo-app">
<h3>我的待办事项</h3>
<ul>
<li v-for="(item, index) in todoList" :key="item.id">
序号: {{ index + 1 }} ------ 内容: {{ item.text }}
<button @click="deleteTodo(item.id)">❌ 删除</button>
</li>
</ul>
</div>
</template>
5. v-model:神奇的"双向奔赴"
普通绑定是单向的(JS 变了,页面变)。但表单(输入框)是让用户打字的,用户打字了,JS 里的变量怎么知道?
v-model 就是双向绑定:
-
数据 -> 视图 :你在 JS 里把
message.value = 'Hello',输入框里立刻显示 'Hello'。 -
视图 -> 数据 :用户在输入框里把 'Hello' 删掉改成了 'Hi',JS 里的
message.value自动变成了'Hi'。
深入底层原理:它是怎么实现的?
v-model 没有任何魔法,它只是一个语法糖(组合包)。
当你写 <input v-model="searchText" /> 时,Vue 底层其实偷偷帮你把它拆成了两句话:
html
<input
:value="searchText"
@input="searchText = $event.target.value"
/>
-
:value="searchText":单向绑定,负责把 JS 变量塞进输入框(数据 -> 视图)。 -
@input="...":监听输入事件,只要用户打字,就触发事件,把输入框当前最新的值($event.target.value)赋值给 JS 变量(视图 -> 数据)。
案例
html
<script setup>
import { ref } from 'vue'
const text1 = ref('我是快捷方式')
const text2 = ref('我是底层原理')
</script>
<template>
<div class="form-demo">
<div class="box">
<p>输入框1 的值是: {{ text1 }}</p>
<input v-model="text1" type="text" placeholder="标准双向绑定" />
</div>
<hr />
<div class="box">
<p>输入框2 的值是: {{ text2 }}</p>
<input
:value="text2"
@input="text2 = $event.target.value"
type="text"
placeholder="原理解析绑定"
/>
</div>
</div>
</template>
<style scoped>
.box { margin: 20px 0; }
input { padding: 8px; width: 250px; }
</style>
总结
记住这五个核心指令的定位,写 Vue 页面就能游刃有余了:
-
需要改标签属性(URL、样式、图片 src) 用
:(v-bind) -
需要监听用户动作(点击、提交、按键) 用
@(v-on) -
需要控制显示隐藏 频繁切换用
v-show,权限安全/单次决定用v-if -
需要遍历数组渲染列表 用
v-for并务必带上:key -
用户输入框、表单收集数据 用
v-model双向绑定