vue - 内置指令
Vue3 提供了一系列内置指令,用于简化 DOM 操作和实现常见功能。这些指令以 v-
前缀开头,通常用于模板中,以下是详细分类及解析:
一、核心渲染指令
用于控制元素的渲染逻辑和数据绑定。
-
v-text
-
功能:更新元素的文本内容(相当于
textContent
)。 -
示例:
<span v-text="message"></span> <!-- 等价于 --> <span>{{ message }}</span>
-
特点:会覆盖元素原有的文本,而插值表达式
{{}}
只会替换占位符。
-
-
v-html
-
功能:将数据以 HTML 格式插入元素(相当于
innerHTML
)。 -
示例:
<div v-html="rawHtml"></div>
-
注意:动态渲染 HTML 存在 XSS 风险,仅用于可信内容,禁止用于用户输入。
-
-
v-show
-
功能:根据表达式的真假值,通过 CSS
display
属性控制元素显示/隐藏。 -
示例:
<p v-show="isVisible">条件显示</p>
-
特点:元素始终存在于 DOM 中,只是切换显示状态,适合频繁切换的场景。
-
-
v-if
/v-else-if
/v-else
-
功能:根据表达式的真假值,动态创建/销毁元素(条件渲染)。
-
示例:
<div v-if="type === 'A'">A</div> <div v-else-if="type === 'B'">B</div> <div v-else>Other</div>
-
特点:会真实改变 DOM 结构,适合条件较少切换的场景;可与
<template>
配合实现多元素条件渲染。
-
-
v-for
-
功能:基于可迭代数据(数组、对象、字符串等)循环渲染元素。
-
示例:
<!-- 遍历数组 --> <li v-for="(item, index) in items" :key="index"> {{ index }}: {{ item.name }} </li> <!-- 遍历对象 --> <div v-for="(value, key) in user" :key="key"> {{ key }}: {{ value }} </div>
-
注意:必须使用
:key
绑定唯一标识,优化渲染性能并避免状态混乱。
-
二、事件处理指令
用于绑定 DOM 事件。
-
v-on
-
功能:绑定事件监听器,缩写为
@
。 -
示例:
<button v-on:click="handleClick">点击</button> <button @click="handleClick">点击(缩写)</button>
-
扩展:
- 支持事件修饰符:
@click.stop
(阻止冒泡)、@click.prevent
(阻止默认行为)等。 - 支持按键修饰符:
@keyup.enter
(回车键触发)。 - 支持自定义事件:
@custom-event="handleEvent"
。
- 支持事件修饰符:
-
三、属性绑定指令
用于绑定 HTML 属性或组件 props。
-
v-bind
-
功能:动态绑定一个或多个属性,缩写为
:
。 -
示例:
<!-- 绑定 HTML 属性 --> <img v-bind:src="imageUrl" :alt="imageAlt"> <!-- 绑定 class --> <div :class="{ active: isActive, 'text-danger': hasError }"></div> <!-- 绑定 style --> <div :style="{ color: textColor, fontSize: '16px' }"></div> <!-- 绑定组件 props --> <ChildComponent :user="currentUser"></ChildComponent>
-
特点:可绑定任意属性,表达式结果会被解析为属性值。
-
四、表单输入绑定指令
用于在表单元素和数据之间创建双向绑定。
-
v-model
-
功能:简化表单控件的双向数据绑定(本质是
v-bind
+v-on
的语法糖)。 -
支持元素:
input
、textarea
、select
等。 -
示例:
<input v-model="username" type="text"> <textarea v-model="content"></textarea> <select v-model="selectedValue"> <option value="1">选项1</option> </select>
-
修饰符:
.trim
:自动去除输入首尾空格。.number
:将输入转为数字类型。.lazy
:在change
事件而非input
事件触发时更新数据。
-
Vue3 中的 v-model
是表单输入绑定的核心指令,它实现了表单控件与组件数据之间的双向绑定。其本质是语法糖,会根据不同的表单元素自动展开为 v-bind
(绑定值)和 v-on
(监听输入事件)。
下面详细解析 v-model
在各种表单控件中的使用方法:
一、文本输入框(text /textarea)
适用于单行文本、多行文本输入。
- 单行文本(input [type="text"])
<template>
<div>
<label>用户名:</label>
<input type="text" v-model="username">
<p>你输入的是:{{ username }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const username = ref('') // 初始值为空
</script>
- 多行文本(textarea)
<template>
<div>
<label>个人简介:</label>
<textarea v-model="intro" rows="3"></textarea>
<p>简介内容:{{ intro }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const intro = ref('请输入个人简介') // 初始值
</script>
- 注意:
<textarea>
不需要使用{{}}
插值,v-model
直接绑定即可。
二、复选框(checkbox)
复选框分为单个复选框(布尔值)和多个复选框(数组)两种场景。
- 单个复选框(布尔值绑定)
<template>
<div>
<label>
<input type="checkbox" v-model="agree"> 我同意协议
</label>
<p>是否同意:{{ agree ? '是' : '否' }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const agree = ref(false) // 初始未勾选
</script>
- 多个复选框(数组绑定)
<template>
<div>
<label>爱好:</label>
<div>
<label>
<input type="checkbox" v-model="hobbies" value="reading"> 阅读
</label>
<label>
<input type="checkbox" v-model="hobbies" value="sports"> 运动
</label>
<label>
<input type="checkbox" v-model="hobbies" value="coding"> 编程
</label>
</div>
<p>选中的爱好:{{ hobbies }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const hobbies = ref([]) // 初始为空数组
</script>
- 多个复选框的
v-model
绑定到同一个数组,选中的值会自动添加到数组中。
三、单选按钮(radio)
多个单选按钮组成一组,通过 name
属性关联,v-model
绑定选中的值。
<template>
<div>
<label>性别:</label>
<div>
<label>
<input type="radio" v-model="gender" value="male" name="gender"> 男
</label>
<label>
<input type="radio" v-model="gender" value="female" name="gender"> 女
</label>
</div>
<p>选中的性别:{{ gender }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const gender = ref('male') // 初始选中"男"
</script>
四、下拉选择框(select)
下拉选择框分为单选和多选两种模式。
- 单选下拉框
<template>
<div>
<label>城市:</label>
<select v-model="city">
<option value="">请选择</option>
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
<option value="guangzhou">广州</option>
</select>
<p>选中的城市:{{ city }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const city = ref('') // 初始未选择
</script>
- 多选下拉框(添加 multiple 属性)
<template>
<div>
<label>喜欢的水果(按住Ctrl可多选):</label>
<select v-model="fruits" multiple size="3">
<option value="apple">苹果</option>
<option value="banana">香蕉</option>
<option value="orange">橙子</option>
<option value="grape">葡萄</option>
</select>
<p>选中的水果:{{ fruits }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const fruits = ref([]) // 初始为空数组
</script>
- 多选模式下,
v-model
绑定到数组,选中的选项值会添加到数组中。 size
属性控制下拉框可见选项数量。
五、其他表单控件
- 数字输入框(input [type="number"])
<template>
<div>
<label>年龄:</label>
<input type="number" v-model="age" min="0" max="120">
<p>年龄值:{{ age }}(类型:{{ typeof age }})</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const age = ref(18) // 初始值为数字类型
</script>
- 日期选择器(input [type="date"])
<template>
<div>
<label>出生日期:</label>
<input type="date" v-model="birthday">
<p>出生日期:{{ birthday }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const birthday = ref('2000-01-01') // 初始值为日期字符串(YYYY-MM-DD)
</script>
六、v-model 修饰符
Vue3 提供了三个常用修饰符,用于处理表单输入:
- .trim:自动去除输入内容的首尾空格
<input type="text" v-model.trim="username">
- .number:将输入值转为数字类型(若无法转换则保留字符串)
<input type="text" v-model.number="age">
<!-- 输入"18"会转为数字18,输入"abc"仍为字符串"abc" -->
- .lazy:在
change
事件触发时更新数据(默认是input
事件)
<input type="text" v-model.lazy="search">
<!-- 输入时不实时更新,失去焦点或按回车后才更新 -->
总结
v-model
是 Vue 表单处理的核心,通过自动适配不同表单控件,实现了简洁的双向绑定:
- 文本类(text/textarea):绑定字符串
- 单个复选框:绑定布尔值
- 多个复选框:绑定数组(收集选中值)
- 单选按钮 / 单选下拉框:绑定选中的值
- 多选下拉框:绑定数组(收集选中值)
配合修饰符 .trim
、.number
、.lazy
可以更灵活地处理表单输入,大幅简化了传统 DOM 操作的繁琐流程。
五、其他实用指令
-
v-pre
-
功能:跳过元素及其子元素的编译过程,直接渲染原始内容。
-
示例:
<div v-pre>{{ 这里的表达式不会被编译 }}</div>
-
适用场景:展示包含
{{ }}
的原始文本,提升编译性能。
-
-
v-cloak
-
功能:在 Vue 实例编译完成前隐藏元素,避免未编译的模板闪烁。
-
用法:
[v-cloak] { display: none; }
<div v-cloak>{{ message }}</div>
-
原理:编译完成后,Vue 会自动移除
v-cloak
属性。
-
-
v-once
-
功能:元素或组件只渲染一次,后续数据变化不会重新渲染。
-
示例:
<div v-once>{{ message }}</div>
-
适用场景:优化静态内容的渲染性能。
-
六、特殊元素
在 Vue 3 中,<component>
、<slot>
和 <template>
都是特殊的内置元素,各自承担着独特的功能,是 Vue 组件系统的核心组成部分。
1. <component>
:动态组件渲染
- 作用:用于动态渲染不同的组件,根据
is
属性的值决定渲染哪个组件。 - 特点:Vue 原生内置,支持动态切换组件,常用于 tabs、条件渲染等场景。
示例:
<template>
<!-- 根据 currentComponent 的值动态渲染组件 -->
<component :is="currentComponent" />
<button @click="currentComponent = 'ComponentA'">显示A</button>
<button @click="currentComponent = 'ComponentB'">显示B</button>
</template>
<script setup>
import { ref } from 'vue'
import ComponentA from './ComponentA.vue'
import ComponentB from './ComponentB.vue'
const currentComponent = ref('ComponentA') // 初始渲染 ComponentA
</script>
-
is
属性的值可以是:
- 组件的选项对象(如导入的组件)
- 组件的注册名称(字符串)
- HTML 标签名(如
'div'
,用于渲染原生元素)
2. <slot>
:组件内容分发
- 作用:用于定义组件的 “插槽”,允许父组件向子组件内部插入内容,实现组件的复用和定制化。
- 特点:Vue 原生的内容分发机制,支持默认插槽、具名插槽和作用域插槽。
示例:
<!-- 子组件 Child.vue -->
<template>
<div class="child">
<!-- 默认插槽:接收父组件传入的默认内容 -->
<slot>默认内容(父组件没传内容时显示)</slot>
<!-- 具名插槽:接收父组件指定名称的内容 -->
<slot name="header"></slot>
</div>
</template>
<!-- 父组件 Parent.vue -->
<template>
<Child>
<!-- 默认插槽内容 -->
<p>这是默认插槽的内容</p>
<!-- 具名插槽内容(v-slot 可简写为 #) -->
<template #header>
<h2>这是头部插槽的内容</h2>
</template>
</Child>
</template>
-
作用域插槽
:子组件可以向插槽传递数据,父组件使用
v-slot:name="scope"
接收:
<!-- 子组件 --> <slot name="item" :data="user"></slot> <!-- 父组件 --> <template #item="scope"> <p>{{ scope.data.name }}</p> <!-- 使用子组件传递的数据 --> </template>
3. <template>
:模板片段容器
-
作用:作为一个不可见的容器,用于包裹多个元素或组件,本身不会被渲染到 DOM 中。
-
特点
:
- 不产生实际 DOM 节点,仅用于逻辑分组。
- 常与
v-if
、v-for
、v-slot
等指令配合使用。
常见用法:
-
配合
v-if
/v-else
分组元素:<template v-if="isShow"> <p>段落1</p> <p>段落2</p> </template>
-
配合
v-for
循环多个元素:<template v-for="(item, index) in list" :key="index"> <p>{{ item.name }}</p> <div>{{ item.desc }}</div> </template>
-
定义具名插槽:
<template #footer> <button>底部按钮</button> </template>
总结
<component>
:动态渲染组件,核心是:is
属性。<slot>
:实现组件内容分发,支持灵活定制子组件内容。<template>
:作为模板片段容器,用于逻辑分组,不渲染实际 DOM。
总结
Vue3 内置指令可分为以下几类:
- 渲染控制:
v-text
、v-html
、v-show
、v-if
/v-else
、v-for
- 事件处理:
v-on
(@
) - 属性绑定:
v-bind
(:
) - 表单绑定:
v-model
- 性能/编译控制:
v-pre
、v-cloak
、v-once
这些指令覆盖了日常开发的大部分场景,通过简化 DOM 操作,使开发者更专注于数据逻辑而非 DOM 细节。