# 类与样式绑定
# 绑定HTML class
绑定对象
<div :class="{ active: isActive }"></div>
<div
class="static"
:class="{ active: isActive, 'text-danger': hasError }"
></div>
<div :class="classObject"></div>
也可以绑定计算属性
绑定数组
<div :class="[activeClass, errorClass]"></div>
<div :class="[isActive ? activeClass : '', errorClass]"></div>
<div :class="[{ active: isActive }, errorClass]"></div>
# 绑定内联样式
绑定对象
<!-- 支持绑定css属性名的小驼峰式写法 -->
<div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
<!-- 支持绑定原始css属性写法 -->
<div :style="{ 'font-size': fontSize + 'px' }"></div>
<!-- 绑定样式对象 -->
<div :style="styleObject"></div>
也可以绑定计算属性
绑定数组
<div :style="[baseStyles, overridingStyles]"></div>
# 自动前缀
当你在 :style
中使用了需要浏览器特殊前缀 (opens new window)的 CSS 属性时,Vue 会自动为他们加上相应的前缀。Vue 是在运行时检查该属性是否支持在当前浏览器中使用。如果浏览器不支持某个属性,那么将尝试加上各个浏览器特殊前缀,以找到哪一个是被支持的。
# 文本插值
# {{}}
最基本的数据绑定形式是文本插值,它使用的是“Mustache”语法 (即双大括号):
- 支持js表达式
仅支持单一表达式(一个简单的判断方法是是否可以合法地写在 return
后面)。
- 支持函数调用
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
{{ formatDate(date) }}
注意:没有显式包含在列表中的全局对象将不能在模板内表达式中访问。(可以自行在 app.config.globalProperties
(opens new window) 上显式地添加它们,供所有的 Vue 表达式使用。)
# v-html
# v-text
# 属性绑定
# v-bind
<div v-bind:id="dynamicId"></div>
注意:如果绑定的值是 null
或者 undefined
,那么该 attribute 将会从渲染的元素上移除。
简写为::
动态绑定多个值
data() {
return {
objectOfAttrs: {
id: 'container',
class: 'wrapper'
}
}
}
<div v-bind="objectOfAttrs"></div>
动态参数
<a v-bind:[attributeName]="url"> ... </a>
<!-- 简写 -->
<a :[attributeName]="url"> ... </a>
# 条件渲染
# v-if
v-if
指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回真值时才被渲染。
<h1 v-if="awesome">Vue is awesome!</h1>
# v-else
你也可以使用 v-else
为 v-if
添加一个“else 区块”。
<h1 v-if="awesome">Vue is awesome!</h1>
<h1 v-else>Oh no 😢</h1>
注意:
一个 v-else
元素必须跟在一个 v-if
或者 v-else-if
元素后面,否则它将不会被识别。
# v-else-if
v-else-if
提供的是相应于 v-if
的“else if 区块”。它可以连续多次重复使用
<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<div v-else>
Not A/B/C
</div>
注意:
和 v-else
类似,一个使用 v-else-if
的元素必须紧跟在一个 v-if
或一个 v-else-if
元素后面。
<template>
上的 v-if
、v-else
和 `v-else-if
# v-show
另一个可以用来按条件显示一个元素的指令是 v-show
<h1 v-show="ok">Hello!</h1>
不同之处在于 v-show
会在 DOM 渲染中保留该元素;v-show
仅切换了该元素上名为 display
的 CSS 属性。
v-show
不支持在 <template>
元素上使用,也不能和 v-else
搭配使用。
# v-if
vs. v-show
# (opens new window)
v-if
是“真实的”按条件渲染,因为它确保了在切换时,条件区块内的事件监听器和子组件都会被销毁与重建。
v-if
也是惰性的:如果在初次渲染时条件值为 false,则不会做任何事。条件区块只有当条件首次变为 true 时才被渲染。
相比之下,v-show
简单许多,元素无论初始条件如何,始终会被渲染,只有 CSS display
属性会被切换。
总的来说,v-if
有更高的切换开销,而 v-show
有更高的初始渲染开销。因此,如果需要频繁切换,则使用 v-show
较好;如果在运行时绑定条件很少改变,则 v-if
会更合适。
# v-if
和 v-for
当 v-if
和 v-for
同时存在于一个元素上的时候,
v-if
比 v-for
的优先级更高,v-if
会首先被执行。这意味着 v-if
的条件将无法访问到 v-for
作用域内定义的变量别名:请查看列表渲染指南 (opens new window)获取更多细节。
<!--
这会抛出一个错误,因为属性 todo 此时
没有在该实例上定义
-->
<li v-for="todo in todos" v-if="!todo.isComplete">
{{ todo.name }}
</li>
在外新包装一层 <template>
再在其上使用 v-for
可以解决这个问题 (这也更加明显易读):
<template v-for="todo in todos">
<li v-if="!todo.isComplete">
{{ todo.name }}
</li>
</template>
# 列表渲染
# v-for
v-for
指令基于一个数组来渲染一个列表。v-for
指令的值需要使用 item in items
形式的特殊语法,其中 items
是源数据的数组,而 item
是迭代项的别名:
<li v-for="item in items">
{{ item.message }}
</li>
data() {
return {
items: [{ message: 'Foo' }, { message: 'Bar' }]
}
}
你也可以使用 of
作为分隔符来替代 in
,这更接近 JavaScript 的迭代器语法:
template
<div v-for="item of items"></div>
# v-for与对象
也可以使用 v-for
来遍历一个对象的所有属性。遍历的顺序会基于对该对象调用 Object.keys()
的返回值来决定。
data() {
return {
myObject: {
title: 'How to do lists in Vue',
author: 'Jane Doe',
publishedAt: '2016-04-10'
}
}
}
<li v-for="(value, key, index) in myObject">
{{ index }}. {{ key }}: {{ value }}
</li>
属性值、属性名、索引
在 <template>
标签上使用 v-for
来渲染一个包含多个元素的块。
通过key管理状态
<div v-for="item in items" :key="item.id">
<!-- 内容 -->
</div>
# 事件处理
# v-on
它将监听DOM事件,并在事件触发时执行对应的 JavaScript。
<!-- 这里的参数是要监听的事件名称:click -->
<a v-on:click="doSomething"> ... </a>
<!-- 简写 -->
<a @click="doSomething"> ... </a>
简写为:@
事件处理器的值可以是:
内联事件处理器:事件被触发时执行的内联 JavaScript 语句 (与
onclick
类似)。内联事件处理器通常用于简单场景 <button @click="count++">Add 1</button>
方法事件处理器:一个指向组件上定义的方法的属性名或是路径。
方法内够通过被触发事件的 event.target.tagName
访问到该 DOM 元素。
# 事件修饰符
# .stop
# .prevent
.prevent
修饰符会告知 v-on
指令对触发的事件调用 event.preventDefault()
# .self
# .capture
# .once
# .passive
<!-- 单击事件将停止传递 -->
<a @click.stop="doThis"></a>
<!-- 提交事件将不再重新加载页面 -->
<form @submit.prevent="onSubmit"></form>
<!-- 修饰语可以使用链式书写 -->
<a @click.stop.prevent="doThat"></a>
<!-- 也可以只有修饰符 -->
<form @submit.prevent></form>
<!-- 仅当 event.target 是元素本身时才会触发事件处理器 -->
<!-- 例如:事件处理器不来自子元素 -->
<div @click.self="doThat">...</div>
# 按键修饰符
.enter
.tab
.delete
(捕获“Delete”和“Backspace”两个按键).esc
.space
.up
.down
.left
.right
# 系统按键修饰符# (opens new window)
你可以使用以下系统按键修饰符来触发鼠标或键盘事件监听器,只有当按键被按下时才会触发。
.ctrl
.alt
.shift
.meta
- 在 Mac 键盘上,meta 是 Command 键 (⌘)。在 Windows 键盘上,meta 键是 Windows 键 (⊞)。在 Sun 微机系统键盘上,meta 是钻石键 (◆)。在某些键盘上,特别是 MIT 和 Lisp 机器的键盘及其后代版本的键盘,如 Knight 键盘,space-cadet 键盘,meta 都被标记为“META”。在 Symbolics 键盘上,meta 也被标识为“META”或“Meta”。
# .exact
修饰符
.exact
修饰符允许控制触发一个事件所需的确定组合的系统按键修饰符。
<!-- 当按下 Ctrl 时,即使同时按下 Alt 或 Shift 也会触发 -->
<button @click.ctrl="onClick">A</button>
<!-- 仅当按下 Ctrl 且未按任何其他键时才会触发 -->
<button @click.ctrl.exact="onCtrlClick">A</button>
<!-- 仅当没有按下任何系统按键时触发 -->
<button @click.exact="onClick">A</button>
# 鼠标按键修饰符# (opens new window)
.left
.right
.middle
这些修饰符将处理程序限定为由特定鼠标按键触发的事件。
# 表单输入绑定
# v-model
# 文本
# 多行文本
# 复选框
<input
type="checkbox"
v-model="toggle"
true-value="yes"
false-value="no" />
true-value 和 false-value 是 Vue 特有的 attributes,仅支持和 v-model 配套使用。这里 toggle 属性的值会在选中时被设为 'yes',取消选择时设为 'no'。你同样可以通过 v-bind 将其绑定为其他动态值:
# 单选按钮
# 选择器
# 修饰符
# .lazy
默认情况下,v-model
会在每次 input
事件后更新数据 (IME 拼字阶段的状态 (opens new window)例外)。你可以添加 lazy
修饰符来改为在每次 change
事件后更新数据
# .number
如果你想让用户输入自动转换为数字,你可以在 v-model
后添加 .number
修饰符来管理输入
# .trim
如果你想要默认自动去除用户输入内容中两端的空格,你可以在 v-model
后添加 .trim
修饰符:
<!-- 在 "change" 事件后同步更新而不是 "input" -->
<input v-model.lazy="msg" />
<input v-model.number="age" />
<input v-model.trim="msg" />