三、Vue3 模板语法

文章目录

    • 一、插值语法
    • 二、指令(Directives)
      • [1. `v-bind`:给属性装上"动态天线"](#1. v-bind:给属性装上“动态天线”)
      • [2. `v-on`:网页的"神经末梢"](#2. v-on:网页的“神经末梢”)
      • [3. `v-if` vs `v-show`:网页元素的"生死"与"隐身"](#3. v-if vs v-show:网页元素的“生死”与“隐身”)
      • [4. `v-for`:无情的"复印机"](#4. v-for:无情的“复印机”)
        • [为什么必须绑定 `:key`?](#为什么必须绑定 :key?)
        • 案例
      • [5. `v-model`:神奇的"双向奔赴"](#5. v-model:神奇的“双向奔赴”)
      • 总结

模板语法就是教你在 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 就是双向绑定

  1. 数据 -> 视图 :你在 JS 里把 message.value = 'Hello',输入框里立刻显示 'Hello'。

  2. 视图 -> 数据 :用户在输入框里把 '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 双向绑定

相关推荐
zhedream2 小时前
十万级列表的跨页多选方案:el-table 踩坑与治理实践
vue.js·element
rising start2 小时前
二、Vue3 核心基础:API 对比、Setup 与响应式详解
前端·javascript·vue.js
我穿棉裤了3 小时前
解决el-form表单校验时显示的红色星号与文字对齐的问题
前端·javascript·vue.js
超人不会飞_Jay3 小时前
2026.6.4 Vue用户中心项目笔记
前端·vue.js·笔记
懂懂tty4 小时前
Vue3 编译优化
前端·javascript·vue.js
踩着两条虫4 小时前
VTJ.PRO v2.4.0 多人协作与 AI 批量识图实战评测
vue.js·人工智能·低代码·figma
低保和光头哪个先来4 小时前
源码篇 生命周期
前端·javascript·vue.js
ct9784 小时前
Vue 项目性能优化
前端·vue.js·性能优化
辞忧九千七4 小时前
Vue3 学习:组件通信完全指南
vue.js