指令(Directives)是 Vue 模板中最具特色的语法,它们是带有
v-前缀的特殊属性。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。
<element v-directive="expression"></element>
一个完整的指令包含:
v- 前缀 + 指令名<a v-bind:href="url" target="_blank">链接</a>
<!-- ↑ ↑ ↑
指令 参数 表达式
-->
<button v-on:click.prevent="handleSubmit">提交</button>
<!-- ↑ ↑ ↑ ↑
指令 参数 修饰符 表达式
-->
| 指令 | 用途 | 示例 |
|---|---|---|
v-text | 更新元素的 textContent | <span v-text="msg"></span> |
v-html | 更新元素的 innerHTML | <div v-html="html"></div> |
v-show | 切换 display 属性 | <div v-show="visible"></div> |
v-if | 条件渲染 | <div v-if="seen"></div> |
v-else | 否则分支 | <div v-else></div> |
v-else-if | 否则如果 | <div v-else-if="type"></div> |
v-for | 列表渲染 | <li v-for="item in list"></li> |
v-on | 事件绑定 | <button v-on:click="fn"></button> |
v-bind | 属性绑定 | <img v-bind:src="url"> |
v-model | 双向绑定 | <input v-model="value"> |
v-slot | 插槽 | <template v-slot:header></template> |
v-pre | 跳过编译 | <span v-pre>{{ msg }}</span> |
v-cloak | 防止闪烁 | <div v-cloak>{{ msg }}</div> |
v-once | 只渲染一次 | <span v-once>{{ msg }}</span> |
一些指令可以接受参数,在指令名称后以冒号表示:
<!-- v-bind 参数:要绑定的属性名 -->
<img v-bind:src="imageSrc">
<a v-bind:href="url">链接</a>
<div v-bind:class="{ active: isActive }"></div>
<!-- v-on 参数:要监听的事件名 -->
<button v-on:click="doSomething">点击</button>
<input v-on:focus="onFocus">
Vue 2.6.0+ 支持动态参数,用方括号括起来:
<!-- 动态属性名 -->
<a v-bind:[attributeName]="url">链接</a>
<!-- 动态事件名 -->
<button v-on:[eventName]="handler">按钮</button>
new Vue({
data: {
attributeName: 'href',
eventName: 'click',
url: 'https://vuejs.org'
},
methods: {
handler: function() {
console.log('clicked')
}
}
})
动态参数的限制
null 则移除绑定<!-- ❌ 错误:包含空格 -->
<a v-bind:['attr' + name]="value"></a>
<!-- ✅ 正确:使用计算属性 -->
<a v-bind:[computedAttr]="value"></a>
修饰符是以点开头的特殊后缀,用于指出指令应该以特殊方式绑定:
<!-- 阻止默认行为 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 阻止事件冒泡 -->
<div v-on:click.stop="doThis"></div>
<!-- 事件只触发一次 -->
<button v-on:click.once="doThis"></button>
<!-- 按键修饰符 -->
<input v-on:keyup.enter="submit">
<input v-on:keyup.esc="cancel">
<!-- 表单修饰符 -->
<input v-model.lazy="msg">
<input v-model.number="age">
<input v-model.trim="text">
事件修饰符
| 修饰符 | 说明 |
|---|---|
.stop | 阻止事件冒泡 |
.prevent | 阻止默认行为 |
.capture | 使用事件捕获模式 |
.self | 只当事件在该元素本身触发时触发 |
.once | 事件只触发一次 |
.passive | 提升移动端滚动性能 |
按键修饰符
| 修饰符 | 键码 |
|---|---|
.enter | 回车 |
.tab | Tab |
.esc | Esc |
.space | 空格 |
.up / .down / .left / .right | 方向键 |
表单修饰符
| 修饰符 | 说明 |
|---|---|
.lazy | 在 change 事件后同步 |
.number | 自动转为数字 |
.trim | 自动过滤首尾空格 |
Vue 为常用指令提供了缩写:
<!-- 完整写法 -->
<a v-bind:href="url">链接</a>
<!-- 缩写 -->
<a :href="url">链接</a>
<!-- 动态参数缩写 -->
<a :[key]="value">链接</a>
<!-- 完整写法 -->
<button v-on:click="doSomething">点击</button>
<!-- 缩写 -->
<button @click="doSomething">点击</button>
<!-- 动态参数缩写 -->
<button @[event]="handler">点击</button>
v-text 和 {{ }} 功能类似,但有细微差别:
<!-- 两种写法效果相同 -->
<span v-text="message"></span>
<span>{{ message }}</span>
<!-- 区别:v-text 会替换整个元素内容 -->
<p v-text="message">这段文字会被替换</p>
<!-- 插值表达式可以部分替换 -->
<p>前缀文字 {{ message }} 后缀文字</p>
v-once 让元素和组件只渲染一次,后续重新渲染时视为静态内容:
<div id="app">
<p v-once>{{ message }}</p>
<p>{{ message }}</p>
<button @click="message = 'Changed'">改变</button>
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'Initial'
}
})
</script>
点击按钮后,第一个 <p> 仍然显示 "Initial",第二个显示 "Changed"。
v-pre 跳过这个元素和它的子元素的编译过程:
<!-- 显示原始的 {{ message }},不会被编译 -->
<span v-pre>{{ message }}</span>
适合显示原始 Mustache 标签的场景。
v-cloak 用于防止页面加载时出现未编译的 Mustache 标签:
<style>
[v-cloak] {
display: none;
}
</style>
<div id="app" v-cloak>
{{ message }}
</div>
在 Vue 实例编译完成前,带有 v-cloak 的元素会被隐藏,编译完成后自动移除该属性。
指令是 Vue 模板的核心特性:
v- 前缀标识v-bind 和 v-on 有缩写形式熟练掌握指令是编写 Vue 模板的基础。