现在介绍 Vue.js 中 更多的内置指令

基本指令

v-cloak

v-cloak 不需要表达式,它会在 Vue 实例结束编译时从绑定的 HTML 元素上移除,经常和 CSS 的 display: none; 配合使用:

<div id="app" v-cloak>
{{ message }}
</div>
<script>
var app = new Vue({
el: '#app',
data: {
message: '这是一段文本'
}
})
</script>

这时虽然已经加了指令,但其实没有起到任何作用,Vue.js 文件还没加载完时,在页面上会显示 {{ message }} 的字样,直到 Vue 创建实例、编译模板时,DOM才会被替换,所以这个过程屏幕是有闪动的。只要加一句 CSS 就可以解决问题了:

[v-cloak] {
display: none;
}

一般情况下,v-cloak 是一个解决初始化慢导致页面闪动的最佳实践,对于简单的项目很实用,但在具有工程化的项目里,项目的 HTML 结构只有一个空的 div 元素,剩余的内容都由路由去挂载不同的组件完成,所以不再需要 v-cloak。

v-once

v-once 也是一个不需要表达式的指令,作用是定义它的元素或组件只渲染一次,包括元素或组件的所有子节点。首次渲染后,不再随数据的变化重新渲染,将被视为静态内容,例如:

<div id="app">
<div v-once>{{ message }}</div>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
message: '这是一段文本'
}
})
</script>

v-once 在业务中很少使用,当你需要进一步优化性能时,可能会用到。

条件渲染指令

v-if、v-else-if、v-else

与 JavaScript 的条件语句 if、else、else if 类似,Vue.js 的条件命令可以根据表达式的值在 DOM 中渲染或销毁元素的组件,例如:

<div id="app">
<p v-if="status === 1">当status === 1,显示改行</p>
<p v-else-if="status === 2">当status === 2,显示改行</p>
<p v-else>否则显示改行</p>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
status: 3
}
})
</script>

v-else -if 需要紧跟 v-if,v-else 需要紧跟 v-else-if 或 v-if,表达式的值为真时,当前元素/组件及所有子节点将被渲染,为假时被移除。

如果一次判断的是多个元素,可以在 Vue.js 内置的<template>元素上使用条件指令,最终渲染的结果不会包含该元素,例如:

<div id="app">
<template v-if="status === 1">
<p>这是一段文本</p>
<p>这是一段文本</p>
<p>这是一段文本</p>
</template>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
status: 1
}
})
</script>

Vue 在渲染元素时,出于效率考虑,会尽可能地复用已有的元素而非重新渲染,例如:

<div id="app">
<template v-if="type === 'name'">
<label>用户名:</label>
<input placeholder="输入用户名">
</template>
<template v-else>
<label>邮箱:</label>
<input placeholder="输入邮箱">
</template>
<button @click="change">点我切换</button>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
type: 'name'
},
methods: {
change: function () {
this.type = this.type === 'name' ? 'mail' : 'name';
}
}
})
</script>

点击切换按钮,虽然 DOM 变了,但是在输入框键入的内容并没有改变,只是替换了 placeholder 的内容,说明 <input> 元素被复用了。

如果你不希望这么做,可以使用 Vue.js 提供的 key 属性,它可以让你决定是否要复用元素,key 的值必须是唯一的,例如:

div id="app">
<template v-if="type === 'name'">
<label>用户名:</label>
<input placeholder="输入用户名" key="name-input">
</template>
<template v-else>
<label>邮箱:</label>
<input placeholder="输入邮箱" key="mail-input">
</template>
<button @click="change">点我切换</button>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
type: 'name'
},
methods: {
change: function () {
this.type = this.type === 'name' ? 'mail' : 'name';
}
}
})
</script>

给两个 <input> 元素都增加 key 后,就不会被复用了,切换时键入的内容也会被删除,不过<lable> 元素仍然是被复用的,因为没有添加 key 属性。

v-show

v-show 的用法与 v-if 基本一致,只不过 v-show 是改变元素的 CSS 属性 display。当 v-show 表达式的值为 false 时,元素会被隐藏,查看 DOM 结构会看到元素上加载了内联样式 display: none; ,例如:

<div id="app">
<p v-show="status === 1">当 status 为 1 时显示改行</p>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
status: 2
}
})
</script>

渲染后的结果为:

<p style="display: none;">当 status 为 1 时显示改行</p>

v-show 不能在 <template> 上使用

v-if 与 v-show 的选择

v-if 与 v-show 具有类似的功能,不过 v-if 才是真正的条件渲染,它会根据表达式适当地销毁或重建元素及绑定的事件或子组件。若表达式初始值为 false,则一开始元素/组件并不会渲染,只有当条件第一次变为真时才开始编译。

而 v-show 只是简单的 CSS 属性切换,无论条件真与否,都会被编译。因此,v-if 更适合条件不经常改变的场景,因为它切换开销相对较大,而 v-show 适用于频繁切换条件的常见。

列表渲染指令 v-for

基本用法

v-for 可以将一个数组遍历或枚举一个对象循环显示。它的表达式需结合 in 来使用,类似 item in items 的形式,举例:

<div id="app">
<ul>
<li v-for="book in books">{{ book.name }}</li>
</ul>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
books: [
{ name: 'Java 编程思想'},
{ name: 'Java 核心技术'},
{ name: '深入理解 Java 虚拟机'}
]
}
})
</script>

除了数组的属性,对象的属性也是可以遍历的,例如:

<div id="app">
<span v-for="value in user">{{ value }} </span>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
user: {
name: 'kindleheart',
age: 20,
gender: '男'
}
}
})
</script>

遍历对象属性时,有两个可选参数,分别是键名和索引:

<div id="app">
<ul>
<li v-for="(value, key, index) in user">
{{ value }} - {{ key }} - {{ index }}
</li>
</ul>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
user: {
name: 'kindleheart',
age: 20,
gender: '男'
}
}
})
</script>

v-for 还可以迭代整数:

<div id="app">
<span v-for="n in 10">{{ n }} </span>
</div>
<script>
var app = new Vue({
el: '#app',
})
</script>

数组更新

Vue 的核心是数据与视图的双向绑定,当我们修改数组时,Vue会检测到数据变化,所以用 v-for 渲染的视图也会立即更新。Vue 包含了一组观察数组变化的方法,使用它们改变数组也会触发视图更新:

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

使用以上方法会改变被这些方法调用的原生数组,有些方法不会改变原数组,例如:

  • filter()
  • concat()
  • slice()

它们返回的是一个新数组,下面是找出含有 Java 关键字书籍的例子,例如:

<div id="app">
<ul>
<template v-for="book in books">
<li>书名:{{ book.name }}</li>
<li>价格:{{ book.price }}</li>
</template>
</ul>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
books: [
{
name: 'Java 编程思想',
price: 100
},
{
name: 'Java 核心技术',
price: 200
},
{
name: 'JS 高级程序设计',
price: 300
}
]
}
});
app.books = app.books.filter(function (item) {
return item.name.match(/Java/);
})
</script>

Vue 在检测到数组变化时,并不是重新渲染整个列表,而是最大化地复用 DOM 元素。替换的数组中,含有相同元素的项不会被重新渲染,因此可以大胆地用新数组来替换旧数组,不用担心性能问题。

需要注意的是,以下变动的数组中,Vue 是不能检测到的,也不会触发视图更新:

  • 通过索引直接设置项、比如 app.books[3] = {...}。
  • 修改数组长度,比如 app.books.length = 1。

解决第一个问题可以用两种方法实现同样的效果,第一张是Vue内置的 set 方法:

Vue.set(app.books, 3, {
name: '<<CSS 揭秘>>',
price: 150
});

在 webpack 组件化的方式,默认是没有导入 Vue 的,这时可以使用 $set,例如:

//这里的 this 指向的是当前组件实例
this.$set(app.books, 3, {
name: '<<CSS 揭秘>>',
price: 150
});

还可以使用 app.$set(...) 的方式。

第二个问题可以使用 splice 类解决:

app.books.splice(1);

过滤与排序

当你不想改变原数组,想通过一个数组的副本来做过滤或排序的显示时,可以使用计算属性来返回过滤或排序后的数组,例如:

<div id="app">
<ul>
<template v-for="book in filterBooks">
<li>书名:{{ book.name }}</li>
<li>价格:{{ book.price }}</li>
</template>
</ul>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
books: [
{
name: 'Java 编程思想',
price: 100
},
{
name: 'Java 核心技术',
price: 200
},
{
name: 'JS 高级程序设计',
price: 300
}
]
},
computed: {
filterBooks: function () {
return this.books.filter(function (book) {
return book.name.match(/Java/);
});
}
}
});
</script>

方法与事件

基本用法

在之前我们已经了解了 Vue.js 通过 v-on 指令监听事件,v-on 指令的表达式可以是一个 JavaScript 语句还可以是一个在 Vue 实例中 methods 选项内的函数名,例如:

<div id="app">
点击次数:{{ count }}
<button @click="count++">+1</button>
<button @click="add()">+1</button>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
count: 0
},
methods: {
add: function () {
this.count++;
}
}
});
</script>

需要注意的是 @click 调用的方法名后可以不加括号 "()" ,在大部分业务场景中,如果不需要传入参数,为了简便可以不写括号。

Vue 提供了一个特殊变量 $event,用于访问原生 DOM 事件,例如下面的实例可以阻止链接打开:

<div id="app">
<a href="http://www.apple.com" @click="handleClick('禁止打开', $event)">打开链接</a>
</div>
<script>
var app = new Vue({
el: '#app',
methods: {
handleClick: function (message, event) {
event.preventDefault();
window.alert(message);
}
}
});
</script>

修饰符

在上例使用的 event.preventDefault() 也可以使用 Vue 事件的修饰符来时实现,在@绑定的事件后加小圆点 ".",再跟一个后缀使用修饰符。Vue 支持以下修饰符:

  • .stop
  • .prevent
  • .capture
  • .self
  • .once
  • .passive
<!-- 阻止单击事件继续传播 -->
<a v-on:click.stop="doThis"></a> <!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form> <!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a> <!-- 只有修饰符 -->
<form v-on:submit.prevent></form> <!-- 添加事件监听器时使用事件捕获模式 -->
<!-- 即元素自身触发的事件先在此处理,然后才交由内部元素进行处理 -->
<div v-on:click.capture="doThis">...</div> <!-- 点击事件将只会触发一次 -->
<a v-on:click.once="doThis"></a>

表单元素上监听键盘事件,还可以使用按键修饰符,例如:

<!-- 只有在 keyCode 是 13 时调用 submit() 方法 -->
<input @keyup.13="submit">

也可以自己配置具体按键:

Vue.config.keyCodes.f1 = 112;
// 全局定义后,就可以使用@keyup.f1

除了具体的某个 keyCode 外,Vue 还提供了一些快捷名称,以下是全部的别名:

  • .enter
  • .tab
  • .delete (捕获“删除”和“退格”键)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

这些修饰符也可以组合使用,或和鼠标一起配合使用:

  • .ctrl
  • .alt
  • .shift
  • .meta(Mac 下是 Command 键,在 Windows 下是窗口键)

例如:

<!-- Shift + S -->
<input @ketup.shift.83="handleSave">
<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">Do something</div>

Vue(四) 内置指令的更多相关文章

  1. VUE:内置指令与自定义指令

    VUE:内置指令与自定义指令 常用的内置指令 1)v:text 更新元素的 textContent 2)v-html 更新元素的 innerHTML 3)v-if 如果为true,当前标签才会输出到页 ...

  2. Vue源码后记-其余内置指令(2)

    -- 指令这个讲起来还有点复杂,先把html弄上来: <body> <div id='app'> <div v-if="vIfIter" v-bind ...

  3. Vue源码后记-其余内置指令(1)

    把其余的内置指令也搞完吧,来一个全家桶. 案例如下: <body> <div id='app'> <div v-if="vIfIter" v-bind ...

  4. vue内置指令详解——小白速会

    指令 (Directives) 是带有 v- 前缀的特殊属性,职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM. 内置指令 1.v-bind:响应并更新DOM特性:例如:v-bi ...

  5. Vue.js 学习笔记 第5章 内置指令

    本篇目录: 5.1 基本指令 5.2 条件渲染指令 5.3 列表渲染指令 v-for 5.4 方法与事件 5.5 实战:利用计算属性.指令等知识开发购物车 回顾一下第2.2节,我们己经介绍过指令(Di ...

  6. vue内置指令与自定义指令

    一.内置指令 1.v-bind:响应并更新DOM特性:例如:v-bind:href  v-bind:class  v-bind:title  v-bind:bb 2.v-on:用于监听DOM事件: 例 ...

  7. 2.0 vue内置指令与自定义指令

    1.1 常用内置指令 1) v:text : 更新元素的 textContent 2) v-html : 更新元素的 innerHTML 3) v-if : 如果为 true, 当前标签才会输出到页 ...

  8. Vue 2.0学习(六)内置指令

    基本指令 1.v-cloak v-cloak不需要表达式,它会在Vue实例结束编译时从绑定的HTML元素上移除,经常和CSS的display:none配合使用. <div id="ap ...

  9. Vue 内置指令 && 自定义指令

    1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8" /> 5 & ...

随机推荐

  1. 关于Mysql数据库的学习总结

    关于Mysql操作指令: 1.键盘win + R 弹出windows运行输入框,输入cmd命令,进入windows数据库;   2.在windows数据库里输入mysql(数据库) -uroot(用户 ...

  2. 探讨JS合并两个数组的方法

    我们在项目过程中,有时候会遇到需要将两个数组合并成为一个的情况. 比如: var a = [1,2,3]; var b = [4,5,6]; 有两个数组a.b,需求是将两个数组合并成一个.方法如下: ...

  3. IO流的总结(一)

    IO流的介绍: 其实在我们现实生活中有很多流,例如:水流,电流,气流  等等都是是流,但在Java中IO流是指对数据的操作的流. 按照流的分类: 1:字节流和字符流 Reader和InputStrea ...

  4. 新装Windows Server 2008 r2无法连接有线网络

    新装的Windows Server 2008 r2没有网卡驱动,所以没有网络适配器. 首先,我在相同的型号电脑上查到这个主板的网卡驱动安装的是Intel(R) Ethernet Coinnection ...

  5. JDK安装与配置(Windows 7系统)

    1.前言 安装之前需弄清JDK.JRE.JVM这几个概念,不然稀里糊涂不知道自己在装什么. (1)什么是java环境:我们知道,想听音乐就要安装音乐播放器,想看图片需要安装图片浏览器,同样道理,要运行 ...

  6. jw player 配置参数

    Loading the player … //player所在div //具体配置参数 jwplayer(“container”).setup({//通过js调用播放器并安装到指定容器(contain ...

  7. is 和 == 以及 编码和解码

    1.is  比较的是内存地址 a="name" b="snow" print(a is b) # False id()  获取内存地址 a=" == ...

  8. iOS项目之苹果审核被拒

    解读: 3.2 其他业务模式问题下方列表并非详尽清单,并且您提交的 App 可能会导致我们的政策有所更改或更新,但这里有一些额外的应做事宜和勿做事宜需要您谨记在心: 可以接受 (i)在您的 App 中 ...

  9. Docker Compose 介绍安装

    Compose介绍 Compose是一个定义和管理多容器的工具,也是一种容器编排工具,前身是Pig,使用Python语言编写.使用Compose配置文件描述多个容器应用的架构,biubiu使用什么镜像 ...

  10. win10虚拟桌面使用方法-提高工作效率

    任务栏右键 => 显示任务视图按钮 然后坐下角出现的任务视图按钮可以添加虚拟桌面 快捷键: win + ctrl + 左/右 切换桌面 win + tab 打开任务视图 win + ctrl + ...