Vue3内置指令

Vue 3 内置指令完全指南

本文档专门讲解 Vue 3 的内置指令:Vue 自带的、以 v- 开头的所有指令的语法、用法、修饰符和示例,适合新手系统学习。自定义指令的写法见《Vue3自定义指令.md》。


一、什么叫做“内置指令”?

1.1 概念

内置指令是 Vue 框架自带的、不需要你安装或注册就能在模板里直接使用的特殊属性
它们都以 v- 开头,写在标签上,用来绑定数据、控制显示、绑定事件、绑定表单等。
例如 v-ifv-forv-model 都是内置指令。

1.2 指令的四个部分(语法结构)

一个完整的指令可能包含:

部分 说明 示例
名称 v- 开头的指令名 v-if、v-bind
参数 冒号后面的部分(可选) v-bind:href、v-on:click
修饰符 点后面的部分(可选,可多个) v-model.lazy、v-on:click.stop
等号右边的表达式 v-if=”count > 0

示例:

<div v-bind:id="dynamicId"></div>
<a v-on:click.prevent="submit">提交</a>
<input v-model.lazy.trim="name" />
  • v-bind:id:参数是 id,值是 dynamicId
  • v-on:click.prevent:参数是 click,修饰符是 prevent,值是 submit
  • v-model.lazy.trim:修饰符是 lazytrim,值是 name

二、内容渲染类内置指令

2.1 v-text —— 纯文本

作用: 把表达式的值以纯文本形式设为元素的 textContent,会覆盖该元素内原有内容。

语法: v-text="表达式"

<p v-text="message"></p>
<!-- 等价于 -->
<p>{{ message }}</p>

注意: 若内容里包含 HTML 标签,会原样显示成字符串,不会解析。需要解析 HTML 用 v-html(见下)。


2.2 v-html —— 原始 HTML

作用: 把表达式的值当作 HTML 插入到元素中,会覆盖该元素内原有内容。

语法: v-html="表达式"

<div v-html="rawHtml"></div>
const rawHtml = ref('<span style="color:red">红色</span>')

安全警告: 只对完全信任的内容使用 v-html,用户输入或第三方数据可能包含恶意脚本(XSS),不要直接塞进 v-html。


三、条件渲染类内置指令

3.1 v-show

作用: 根据表达式真假切换元素的 display(true 显示,false 隐藏)。元素始终在 DOM 中,只是被隐藏。

语法: v-show="表达式"

<p v-show="isVisible">看得见我</p>
  • isVisibletrue:元素正常显示。
  • isVisiblefalse:元素被加上 style=”display: none;”

特点: 切换成本低(只改 CSS),适合频繁切换的显示/隐藏。


3.2 v-if / v-else-if / v-else

作用: 根据条件是否渲染这块 DOM。为 false 时,对应节点不会出现在 DOM 里(不是隐藏,是移除)。

语法:

  • v-if="表达式"
  • v-else-if="表达式"(可选,必须紧跟在 v-if 或 v-else-if 后)
  • v-else(可选,无值,必须紧跟在 v-if 或 v-else-if 后)
<p v-if="score >= 90">优秀</p>
<p v-else-if="score >= 60">及格</p>
<p v-else>不及格</p>

v-if 与 v-show 对比:

对比 v-if v-show
为假时 不渲染,从 DOM 移除 仍在 DOM,display: none
切换成本 有创建/销毁成本 只改 CSS
适用 很少切换的条件块 频繁切换

四、列表渲染:v-for

作用: 根据数据源循环渲染多个元素。

语法:

  • v-for="(项, 索引?) in 数组"
  • v-for="(值, 键?, 索引?) in 对象"
  • v-for="n in 数字"(从 1 到该数字)

必须配合 :key,且 key 要唯一、稳定,推荐用 id,避免用 index(列表增删时易错位)。

<li v-for="(item, index) in list" :key="item.id">
  {{ index + 1 }}. {{ item.name }}
</li>
<li v-for="(value, key) in user" :key="key">{{ key }}: {{ value }}</li>
<span v-for="n in 5" :key="n">{{ n }}</span>
<!-- 渲染 1 2 3 4 5 -->

注意: 不要在同一元素上同时写 v-forv-if;需要“循环+条件”时用 包一层,在子元素上写 v-if,或用计算属性先过滤再 v-for。


五、属性绑定:v-bind(:)

作用:表达式的值绑定到元素的属性上,属性会随数据变化而更新。

语法: v-bind:属性名="表达式" 或简写 :属性名="表达式"

<img :src="imgUrl" :alt="imgAlt" />
<a :href="url">链接</a>
<div :id="boxId">盒子</div>

绑定多个属性: 无参数的 v-bind 可传一个对象,键为属性名,值为属性值:

<div v-bind="attrObj"></div>
const attrObj = { id: 'a', class: 'box', 'data-x': '1' }

六、事件绑定:v-on(@)

作用: 给元素绑定事件(如 click、input、submit)。

语法: v-on:事件名="处理函数或内联语句" 或简写 @事件名="..."

<button @click="count++">+1</button>
<button @click="handleClick">点击</button>
<button @click="handleClick($event)">需要事件对象</button>
<button @click="submit(id, $event)">传参+事件对象</button>

常用事件修饰符:

修饰符 作用
.prevent 调用 event.preventDefault(),如阻止表单提交、链接跳转
.stop 调用 event.stopPropagation(),阻止冒泡
.once 事件最多触发一次
.capture 使用捕获阶段
.self 仅当 event.target 是当前元素时触发
<form @submit.prevent="onSubmit">...</form>
<div @click="onDiv">
  <button @click.stop="onBtn">按钮</button>
</div>
<button @click.once="doOnce">只触发一次</button>

按键修饰符: @keyup.enter@keyup.esc@keydown.ctrl 等。


七、双向绑定:v-model

作用:表单控件上实现双向绑定:数据变→视图变,用户输入→数据变。

语法: v-model="变量",可加修饰符 .lazy.number.trim

<input v-model="text" />
<textarea v-model="intro"></textarea>
<input v-model.number="age" type="number" />
<input v-model.trim="keyword" />
<input v-model.lazy="message" />

单选框、复选框、下拉框:

<input type="radio" v-model="gender" value="男" />
<input type="checkbox" v-model="agree" />
<input type="checkbox" v-model="hobbies" value="读书" />
<select v-model="selected">
  <option value="">请选择</option>
  <option value="a">A</option>
</select>
  • 单个 checkbox 绑布尔值;多个 checkbox 绑数组
  • radio、select 单选绑单个值(字符串或数字)。

八、插槽:v-slot(#)

作用:父组件里为子组件的插槽提供内容;可接收子组件通过插槽传出的数据(作用域插槽)。

语法: v-slot:插槽名="作用域" 或简写 #插槽名="作用域";默认插槽可写 #defaultv-slot

<Child>
  <template #header>标题</template>
  <template #default>默认内容</template>
  <template #footer>底部</template>
</Child>

作用域插槽(子传数据给父):

<Child>
  <template #default="{ user }">
    {{ user.name }} - {{ user.age }}
  </template>
</Child>

详见《Vue3插槽.md》。


九、其它内置指令

9.1 v-pre

作用: 该元素及其子元素不参与编译,双花括号和指令会原样显示。

<div v-pre>{{ 这里不会编译 }}</div>

用途: 展示代码示例、避免误编译。


9.2 v-once

作用: 元素只渲染一次,之后数据再变也不会更新。

<p v-once>{{ msg }}</p>

用途: 静态、不需要响应的内容,可略省性能。


9.3 v-memo(Vue 3.2+)

作用: 只有依赖数组里的值变化时,才重新渲染该节点及其子节点;用于大列表等性能优化。

语法: v-memo="[依赖1, 依赖2, ...]"

<div v-for="item in list" :key="item.id" v-memo="[item.id, item.selected]">
  {{ item.name }}
</div>

9.4 v-cloak

作用: 配合 CSS 使用,在 Vue 未完成编译前隐藏未编译的模板(如双花括号),避免闪烁。

<style>
  [v-cloak] { display: none; }
</style>
<div v-cloak>{{ message }}</div>

十、内置指令总览表

指令 作用 常用修饰符/说明
v-text 设置元素文本内容 会覆盖子内容
v-html 插入原始 HTML 仅信任内容使用,防 XSS
v-show 按条件切换 display 元素始终在 DOM
v-if 条件为真才渲染 可与 v-else-if、v-else 连用
v-else-if 否则如果 紧跟 v-if / v-else-if
v-else 否则 紧跟 v-if / v-else-if
v-for 列表渲染 必须配合 :key,且唯一
v-on / @ 绑定事件 .prevent、.stop、.once、.enter 等
v-bind / : 绑定属性 无参 v-bind 可传对象
v-model 表单双向绑定 .lazy、.number、.trim
v-slot / # 插槽内容 #default、#名字、作用域插槽
v-pre 不编译 原样输出
v-once 只渲染一次 后续不更新
v-memo 依赖不变则跳过更新 数组依赖
v-cloak 配合 CSS 防未编译闪烁 需样式 [v-cloak]

十一、学习建议

  1. 先练熟 v-ifv-forv-bindv-onv-model,这些用得最多。
  2. v-for 一定加 :key,且用稳定唯一值(如 id),避免用 index。
  3. v-ifv-show 分清:少切换用 v-if,频繁切换用 v-show。
  4. 事件用 @、属性用 :、v-model 记 .lazy.number.trim
  5. 插槽、自定义指令需要时再查《Vue3插槽.md》《Vue3自定义指令.md》。

把本文档里的示例在项目里敲一遍、改一改数据看效果,会掌握得更牢。祝你学习顺利。

发表评论