指令 (Directives) 是带有 v- 前缀的特殊 attribute。指令 attribute 的值预期是单个 JavaScript 表达式 (v-for 是例外情况,稍后我们再讨论)。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。

v-once 一次性地插值

v-html 原始 HTML

v-bind 绑定HTML属性

绑定HTML class属性

对象语法

  1. <div
  2. class="static"
  3. v-bind:class="{ active: isActive, 'text-danger': hasError }"
  4. ></div>
  5. data: {
  6. isActive: true,
  7. hasError: false
  8. }

上面的语法表示 active 这个 class 存在与否将取决于数据 property isActivetruthiness

  1. <div v-bind:class="classObject"></div>
  2. data: {
  3. classObject: {
  4. active: true,
  5. 'text-danger': false
  6. }
  7. }
  1. <div v-bind:class="classObject"></div>
  2. data: {
  3. isActive: true,
  4. error: null
  5. },
  6. computed: {
  7. classObject: function () {
  8. return {
  9. active: this.isActive && !this.error,
  10. 'text-danger': this.error && this.error.type === 'fatal'
  11. }
  12. }
  13. }

数组语法

我们可以把一个数组传给 v-bind:class,以应用一个 class 列表:

  1. <div v-bind:class="[activeClass, errorClass]"></div>
  1. data: {
  2. activeClass: 'active',
  3. errorClass: 'text-danger'
  4. }

据条件切换列表中的 class,可以用三元表达式:

  1. <div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>

在数组语法中也可以使用对象语法:

  1. <div v-bind:class="[{ active: isActive }, errorClass]"></div>

用在组件上

当在一个自定义组件上使用 class property 时,这些 class 将被添加到该组件的根元素上面。这个元素上已经存在的 class 不会被覆盖。

例如,如果你声明了这个组件:

  1. Vue.component('my-component', {
  2. template: '<p class="foo bar">Hi</p>'
  3. })

然后在使用它的时候添加一些 class:

  1. <my-component class="baz boo"></my-component>

HTML 将被渲染为:

  1. <p class="foo bar baz boo">Hi</p>

对于带数据绑定 class 也同样适用:

  1. <my-component v-bind:class="{ active: isActive }"></my-component>

isActive 为 truthy[1] 时,HTML 将被渲染成为:

  1. <p class="foo bar active">Hi</p>

绑定 HTML style 内联样式

对象语法

v-bind:style 的对象语法十分直观——看着非常像 CSS,但其实是一个 JavaScript 对象。CSS property 名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用引号括起来) 来命名:

  1. <div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
  1. data: {
  2. activeColor: 'red',
  3. fontSize: 30
  4. }

直接绑定到一个样式对象通常更好,这会让模板更清晰:

  1. <div v-bind:style="styleObject"></div>
  1. data: {
  2. styleObject: {
  3. color: 'red',
  4. fontSize: '13px'
  5. }
  6. }

同样的,对象语法常常结合返回对象的计算属性使用。

数组语法

v-bind:style 的数组语法可以将多个样式对象应用到同一个元素上:

  1. <div v-bind:style="[baseStyles, overridingStyles]"></div>

自动添加前缀

v-bind:style 使用需要添加浏览器引擎前缀的 CSS property 时,如 transform,Vue.js 会自动侦测并添加相应的前缀。

多重值

2.3.0+

从 2.3.0 起你可以为 style 绑定中的 property 提供一个包含多个值的数组,常用于提供多个带前缀的值,例如:

  1. <div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>

这样写只会渲染数组中最后一个被浏览器支持的值。在本例中,如果浏览器支持不带浏览器前缀的 flexbox,那么就只会渲染 display: flex

v-on 事件处理

可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。

  1. <div id="example-1">
  2. <button v-on:click="counter += 1">Add 1</button>
  3. <p>The button above has been clicked {{ counter }} times.</p>
  4. </div>
  1. var example1 = new Vue({
  2. el: '#example-1',
  3. data: {
  4. counter: 0
  5. }
  6. })
  1. <div id="example-2">
  2. <!-- `greet` 是在下面定义的方法名 -->
  3. <button v-on:click="greet">Greet</button>
  4. </div>
  5. <el-button type="primary" @click="resetForm('form')">查询</el-button>

事件修饰符

  1. <!-- 阻止单击事件继续传播 -->
  2. <a v-on:click.stop="doThis"></a>
  3. <!-- 提交事件不再重载页面 -->
  4. <form v-on:submit.prevent="onSubmit"></form>
  5. <!-- 修饰符可以串联 -->
  6. <a v-on:click.stop.prevent="doThat"></a>
  7. <!-- 只有修饰符 -->
  8. <form v-on:submit.prevent></form>
  9. <!-- 添加事件监听器时使用事件捕获模式 -->
  10. <!-- 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 -->
  11. <div v-on:click.capture="doThis">...</div>
  12. <!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
  13. <!-- 即事件不是从内部元素触发的 -->
  14. <div v-on:click.self="doThat">...</div>
  15. <!-- 点击事件将只会触发一次 -->
  16. <a v-on:click.once="doThis"></a>
  17. <!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发 -->
  18. <!-- 而不会等待 `onScroll` 完成 -->
  19. <!-- 这其中包含 `event.preventDefault()` 的情况 -->
  20. <div v-on:scroll.passive="onScroll">...</div>

使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。

不要把 .passive 和 .prevent 一起使用,因为 .prevent 将会被忽略,同时浏览器可能会向你展示一个警告。 请记住,.passive 会告诉浏览器你不想阻止事件的默认行为。

v-on 可以监听多个方法

  1. <input type="text" v-on="{ input:onInput,focus:onFocus,blur:onBlur, }">

v-model 表单输入绑定

可以用 v-model 指令在表单 <input><textarea><select> 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。

v-model 会忽略所有表单元素的 valuecheckedselected attribute 的初始值而总是将 Vue 实例的数据作为数据来源。你应该通过 JavaScript 在组件的 data 选项中声明初始值。

.number 修饰符

自动将用户的输入值转为数值类型,可以给 v-model 添加 number 修饰符

  1. <input v-model.number="age" type="number">

image.png

  1. <el-form-item label="合同台量" prop="contractsLiftCount">
  2. <el-input v-model.number="form.contractsLiftCount" />
  3. </el-form-item>

vue 3.x

vue3的变化

  • 变更:在自定义组件上使用v-model时, 属性以及事件的默认名称变了
  • 变更:v-bind.sync修饰符在 Vue 3 中又被去掉了, 合并到了v-model
  • 新增:同一组件可以同时设置多个 v-model
  • 新增:开发者可以自定义 v-model修饰符

1.原来的方式保留

  1. <input v-model="foo">

2.可绑定多个 v-model

  1. <InviteeForm v-model:name="inviteeName" v-model:email="inviteeEmail"/>

其实上面这种方式就相当于之前的 .sync 。

3.额外处理

  1. <Comp v-model:foo.trim="text" v-model:bar.number="number" />

我们可以给这个属性添加额外的处理。

Vue2 中, 在组件上使用 v-model其实就相当于传递了value属性, 并触发了input事件:

  1. <!-- Vue 2 -->
  2. <search-input v-model="searchValue"><search-input>
  3. <!-- 相当于 -->
  4. <search-input :value="searchValue" @input="searchValue=$event"><search-input>

这时**v-model**只能绑定在组件的**value**属性

在Vue3 中,在自定义组件上使用v-model,相当于传递一个modelValue 属性, 同时触发一个update:modelValue事件:

  1. <modal v-model="isVisible"></modal>
  2. <!-- 相当于 -->
  3. <modal :modelValue="isVisible" @update:modelValue="isVisible = $event"></modal>

如果要绑定属性名, 只需要给v-model传递一个参数就行, 同时可以绑定多个v-model

  1. <modal v-model:visible="isVisible" v-model:content="content"></modal>
  2. <!-- 相当于 -->
  3. <modal
  4. :visible="isVisible"
  5. :content="content"
  6. @update:visible="isVisible"
  7. @update:content="content"
  8. />

这个写法完全没有.sync什么事儿了, 所以啊,Vue 3 中又抛弃了.sync写法, 统一使用v-model

v-for 列表渲染

为什么不推荐用 index 做 key

  • 用 index 作为 key 时,在对数据进行,逆序添加,逆序删除等破坏顺序的操作时,会产生没必要的真实 DOM更新,从而导致效率低
  • 用 index 作为 key 时,如果结构中包含输入类的 DOM,会产生错误的 DOM 更新
  • 在开发中最好每条数据使用唯一标识固定的数据作为 key,比如后台返回的 ID,手机号,身份证号等唯一值
  • 如果不存在对数据逆序添加,逆序删除等破坏顺序的操作时,仅用于渲染展示用时,使用 index 作为 key 也是可以的(但是还是不建议使用,养成良好开发习惯)。

    v-if v-else v-else-if 条件渲染

v-if 指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 truthy 值的时候被渲染。

  1. <p v-if="seen">现在你看到我了</p>
  1. <h1 v-if="awesome">Vue is awesome!</h1>
  2. <h1 v-else>Oh no 😢</h1>
  1. <div v-if="type === 'A'">
  2. A
  3. </div>
  4. <div v-else-if="type === 'B'">
  5. B
  6. </div>
  7. <div v-else-if="type === 'C'">
  8. C
  9. </div>
  10. <div v-else>
  11. Not A/B/C
  12. </div>

[key](https://cn.vuejs.org/v2/guide/conditional.html#%E7%94%A8-key-%E7%AE%A1%E7%90%86%E5%8F%AF%E5%A4%8D%E7%94%A8%E7%9A%84%E5%85%83%E7%B4%A0) 管理可复用的元素

带参数的指令

一些指令能够接收一个“参数”,在指令名称之后以冒号表示。例如,v-bind 指令可以用于响应式地更新 HTML attribute

v-bind 参数

v-bind 指令可以用于响应式地更新 HTML attribute。

  1. <a v-bind:href="url">...</a>

在这里 href 是参数,告知 v-bind 指令将该元素的 href attribute 与表达式 url 的值绑定。

v-on 参数

  1. <a v-on:click="doSomething">...</a>

动态参数

从 2.6.0 开始,可以用方括号括起来的 JavaScript 表达式作为一个指令的参数:

  1. <!--
  2. 注意,参数表达式的写法存在一些约束,如之后的“对动态参数表达式的约束”章节所述。
  3. -->
  4. <a v-bind:[attributeName]="url"> ... </a>

这里的 attributeName 会被作为一个 JavaScript 表达式进行动态求值,求得的值将会作为最终的参数来使用。例如,如果你的 Vue 实例有一个 data property attributeName,其值为 "href",那么这个绑定将等价于 v-bind:href

同样地,你可以使用动态参数为一个动态的事件名绑定处理函数:

  1. <a v-on:[eventName]="doSomething"> ... </a>

在这个示例中,当 eventName 的值为 "focus" 时,v-on:[eventName] 将等价于 v-on:focus

对动态参数的值的约束

动态参数预期会求出一个字符串,异常情况下值为 null。这个特殊的 null 值可以被显性地用于移除绑定。任何其它非字符串类型的值都将会触发一个警告。

对动态参数表达式的约束

动态参数表达式有一些语法约束,因为某些字符,如空格和引号,放在 HTML attribute 名里是无效的。例如:

  1. <!-- 这会触发一个编译警告 -->
  2. <a v-bind:['foo' + bar]="value"> ... </a>

变通的办法是使用没有空格或引号的表达式,或用计算属性替代这种复杂表达式。
在 DOM 中使用模板时 (直接在一个 HTML 文件里撰写模板),还需要避免使用大写字符来命名键名,因为浏览器会把 attribute 名全部强制转为小写:

  1. <!--
  2. 在 DOM 中使用模板时这段代码会被转换为 `v-bind:[someattr]`。
  3. 除非在实例中有一个名为“someattr”的 property,否则代码不会工作。
  4. -->
  5. <a v-bind:[someAttr]="value"> ... </a>


缩写 v-bindv-on

v- 前缀作为一种视觉提示,用来识别模板中 Vue 特定的 attribute。当你在使用 Vue.js 为现有标签添加动态行为 (dynamic behavior) 时,v- 前缀很有帮助,然而,对于一些频繁用到的指令来说,就会感到使用繁琐。同时,在构建由 Vue 管理所有模板的单页面应用程序 (SPA - single page application) 时,v- 前缀也变得没那么重要了。因此,Vue 为 v-bindv-on 这两个最常用的指令,提供了特定简写:

v-bind 缩写

  1. <!-- 完整语法 -->
  2. <a v-bind:href="url">...</a>
  3. <!-- 缩写 -->
  4. <a :href="url">...</a>
  5. <!-- 动态参数的缩写 (2.6.0+) -->
  6. <a :[key]="url"> ... </a>

v-on 缩写

  1. <!-- 完整语法 -->
  2. <a v-on:click="doSomething">...</a>
  3. <!-- 缩写 -->
  4. <a @click="doSomething">...</a>
  5. <!-- 动态参数的缩写 (2.6.0+) -->
  6. <a @[event]="doSomething"> ... </a>

它们看起来可能与普通的 HTML 略有不同,但 :@ 对于 attribute 名来说都是合法字符,在所有支持 Vue 的浏览器都能被正确地解析。而且,它们不会出现在最终渲染的标记中。缩写语法是完全可选的,但随着你更深入地了解它们的作用,你会庆幸拥有它们。

修饰符

修饰符 (modifier) 是以半角句号 . 指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。例如,.prevent 修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault()

  1. <form v-on:submit.prevent="onSubmit">...</form>

在接下来对 v-onv-for 等功能的探索中,你会看到修饰符的其它例子。