# Vue2教程 - 4 指令

指令其实就是 Vue 中的定义的特有属性,通过这些属性,可以让模板中的数据 Vue 中的数据进行绑定,前面也简单的使用了,下面详细介绍一下。

# 4.1 v-text和v-html

前面在显示文本的时候,使用的是插值表达式,还可以使用 v-textv-html 指令。

举个栗子:

<!-- 结构 -->
<template>
  <div id="root">
    <!-- v-text会按普通字符串显示 -->
    <div v-text="msg"></div>

    <!-- v-html则会按照html来渲染显示 -->
    <div v-html="msg"></div>

    <!-- 使用差值表达式 -->
    <div>{{ msg }}</div>
  </div>
</template>

<!-- 脚本 -->
<script>
export default {
  name: 'App',
  data() {
    return {
      msg: '<h1>Hello Vue</h1>'
    }
  },
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
  • 差值表达式和 v-text 会按普通字符串显示文本,在实际的开发中,使用插值表达式更方便一些。
  • v-html 则会按照html来渲染显示,所以要确保内容是安全的,自己控制的,否则可能会跨站脚本攻击(XSS)。

# 4.2 v-bind属性绑定

v-bind 是Vue提供的属性绑定机制。我们想在普通的 html 标签中使用 Vue 中数据,则需要使用 v-bind 属性,将Vue中定义的属性绑定到 DOM 元素上,当数据发生变化,DOM 元素会重新渲染。

举个栗子:

<!-- 结构 -->
<template>
  <div id="root">
    <!-- v-bind是Vue中,提供的用于绑定属性的指令 -->
    <input type="button" value="按钮1" v-bind:title="myTitle" />
    <br />

    <!-- v-bind指令可以被简写为 :要绑定的属性 -->
    <input type="button" value="按钮2" :title="myTitle" />
    <br />

    <!-- v-bind中,可以写合法的JS表达式 -->
    <input type="button" value="按钮3" :title="myTitle + 123" />
  </div>
</template>

<!-- 脚本 -->
<script>
export default {
  name: 'App',
  data() {
    return {
      myTitle: "Hello Doubi"
    }
  },
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

在元素上使用 v-bind:属性,就可以在普通的 html 属性中使用 Vue 定义的数据。

上面为三个按钮定义了 title 属性,当鼠标放在按钮上面,会有提示信息

v-bind:属性 可以简写成 :属性 ,例如 :titlev-bind 中也可以写 JS 表达式。

# 4.3 v-on事件绑定

v-on: 指令是 Vue 提供的事件绑定机制,用于事件绑定。

使用时候要注意,只能绑定 Vue 中提供的方法,下面的代码就有问题:

<input type="button" value="按钮" v-on:click="alert('hello')">
1

像上面这样直接写 alert ,是无法在点击按钮的时候弹出的, 因为无法在 Vue 中找到 alert 方法。

可以在 Vue 对象中添加一个 methods 选项,在选项中定义一个方法,然后在 html 元素上绑定事件上调用这个方法,在方法中 alert

举个栗子:

<!-- 结构 -->
<template>
  <div id="root">
    <!-- 定义按钮 -->
    <input type="button" value="按钮" v-on:click="show('hello world')">
  </div>
</template>

<!-- 脚本 -->
<script>
export default {
  name: 'App',
  data() {  // 定义数据
    return {
      myTitle: "Hello Doubi"
    }
  },
  methods: {  // // 这个methods属性中定义了当前Vue实例所有可用的方法
    show: function (str) {
      alert(str)
    }
  },
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

在上面点击按钮,会调用 show 方法,在 show 方法中 alert

v-on: 可以缩写成 @,例如 @click。通过 v-on:click 指定处理方法的时候,如果没有参数,可以不写方法后面的 ()v-on:click="show",如果写了 () 可以传递参数。

同样还可以绑定其他一些事件,例如 mouseover 等事件:v-on:mouseover

需要注意,如果在方法中访问 data 中的数据,需要使用 this 来访问。

举个栗子:

<!-- 结构 -->
<template>
  <div id="root">
    <!-- 定义按钮 -->
    <input type="button" value="按钮" v-on:click="show">
  </div>
</template>

<!-- 脚本 -->
<script>
export default {
  name: 'App',
  data() {  // 定义数据
    return {
      msg: "Hello Doubi!"
    }
  },
  methods: {  // // 这个methods属性中定义了当前Vue实例所有可用的方法
    show: function () {
      alert(this.msg)
    }
  },
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

点击按钮的时候,调用 show 方法,在方法中访问 msg,需要使用 this.msg

# 4.4 v-model双向数据绑定

v-bind 只能实现数据的单向绑定,将数据绑定到 DOM 元素上,修改数据,DOM自动渲染。但是修改DOM中的值,Vue 中的数据无法同步修改。

v-model 是实现双向数据绑定,双向数据绑定是修改了 Vue 的数据,DOM 元素会重新渲染,修改了 DOM 元素中的值,Vue 中的数据也会发生变化。但是 v-model 只能运用在表单元素中,例如 input、select 等,不能运用在 div、span 中。

举个栗子:

<!-- 结构 -->
<template>
  <div id="root">
    <h4>{{ msg }}</h4>

    <!-- 使用v-model指令,可以实现 表单元素和数据的双向数据绑定 -->
    <input type="text" v-model="msg">
  </div>
</template>

<!-- 脚本 -->
<script>
export default {
  name: 'App',
  data() {  // 定义数据
    return {
      msg: "Hello Doubi"
    }
  },
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

上面的代码,使用了 v-modelinput 上绑定了 msg 的值,这样在修改文本中的数据的时候,msg 的值就会发生变化,则 <h4> 中的内容就会同步更新。修改 msg 的值,input 中的值也会发送变化。如果使用 v-bind 指令是不可以的。

注意:v-model 只能运用在表单元素中。

# 4.5 v-for遍历

使用v-for指令可以遍历数组、对象等。

下面列举了几种遍历的使用场景:

<!-- 结构 -->
<template>
  <div id="root">
    <div>
      <!-- 1、遍历数组,第二个参数i如果不用可以省略 -->
      <p v-for="(item, i) in list" :key="item">索引值:{{ i }} --- 每一项:{{ item }}</p>
    </div>

    <div>
      <!-- 2、遍历对象数组 -->
      <p v-for="(user, i) in userList" :key="user.id">Id:{{ user.id }} --- 名字:{{ user.name }} --- 索引:{{ i }}</p>
    </div>

    <div>
      <!-- 3、循环遍历对象身上的属性 -->
      <!-- 注意:在遍历对象身上的键值对的时候, 除了有val、key,在第三个位置还有一个索引-->
      <p v-for="(value, key, i) in user" :key="key">key: {{ key }} --- value: {{ value }} --- 索引值: {{ i }}</p>
    </div>

    <div>
      <!-- 4、遍历数字,in还可以放数字 -->
      <!-- 注意:如果使用 v-for 迭代数字的话,前面的 count 值从 1 开始 -->
      <p v-for="count in 5" :key="count">这是第 {{ count }} 次循环</p>
    </div>
  </div>
</template>

<!-- 脚本 -->
<script>
export default {
  name: 'App',
  data() {  // 定义数据
    return {
      list: [1, 2, 3, 4],
      userList: [
        { id: 1, name: '逗比' },
        { id: 2, name: '牛比' },
        { id: 3, name: '二比' }
      ],
      user: {
        id: 1,
        name: '逗比',
        gender: '男'
      }
    }
  },
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

使用时需要注意,需要为每一个选项使用 :key 来指定唯一的 key 值。因为当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用 “就地复用” 策略。如果数据项的顺序被改变,Vue将不是移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。

所以使用 v-for 来遍历组件的时候,需要添加 key,否则当数据发生变化重新渲染组件的时候,例如 list 发生变化,重新渲染遍历checkbox,可能会导致选中checkbox错位的问题。

显示效果:

如果要修改列表显示,只需要修改数据就可以了:

<!-- 结构 -->
<template>
  <div id="root">
    <!-- 遍历对象数组 -->
    <p v-for="(user, i) in userList" :key="user.id">Id:{{ user.id }} --- 名字:{{ user.name }} --- 索引:{{ i }}</p>

    <button @click="changeData">改变数据</button>
  </div>
</template>

<!-- 脚本 -->
<script>
export default {
  name: 'App',
  data() {  // 定义数据
    return {
      userList: [
        { id: 1, name: '逗比' },
        { id: 2, name: '牛比' },
        { id: 3, name: '二比' }
      ]
    }
  },
  methods: {
    changeData: function() {  // 改变数据
      this.userList[2].name = "菜比"
    }
  },
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

通过改变响应式数据,页面会自动渲染,不需要操作 DOM,非常的方便。

# 4.6 v-if和v-show判断显示

v-ifv-show 指令都是用来控制组件的显示和隐藏的。

有如下代码:

下面的代码实现的效果是:当点击按钮时候,调用方法修改了 flag 的值,两个 h3 使用 v-if 和 v-show 指令通过flag来控制元素的显示和隐藏。

<!-- 结构 -->
<template>
  <div id="root">
    <input type="button" value="toggle" @click="toggle">

    <h3 v-if="flag">这是用v-if控制的元素</h3>

    <h3 v-show="flag">这是用v-show控制的元素</h3>
  </div>
</template>

<!-- 脚本 -->
<script>
export default {
  name: 'App',
  data() {  // 定义数据
    return {
      flag: false
    }
  },
  methods: {  // // 这个methods属性中定义了当前Vue实例所有可用的方法
    toggle: function toggle() {
      this.flag = !this.flag
    }
  },
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

那么v-if和v-show有什么区别?

  • v-if 的特点:每次都会重新删除或创建元素;

  • v-show 的特点: 每次不会重新进行DOM的删除和创建操作,只是切换了元素的 display:none 样式。

  • v-if 有较高的切换性能消耗,如果元素涉及到频繁的切换,最好不要使用 v-if, 而是推荐使用 v-show

  • v-show 有较高的初始渲染消耗,如果元素可能永远也不会被显示出来被用户看到,则推荐使用 v-if

# 4.7 v-if和v-else

什么是条件判断语句,就不需要我说明了吧,以下两个属性!

  • v-if
  • v-else

举个栗子:

<!-- 结构 -->
<template>
  <div id="root">
    <h1 v-if="type">Yes</h1>
    <h1 v-else>No</h1>

    <button @click="switchShow">切换</button>
  </div>
</template>

<!-- 脚本 -->
<script>
export default {
  name: 'App',
  data() {  // 定义数据
    return {
      type: false
    }
  },
  methods: {  // // 这个methods属性中定义了当前Vue实例所有可用的方法
    switchShow: function toggle() {
      this.type = !this.type
    }
  },
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

在上面的代码中,通过 type 的值来控制两个 <h1> 的切换显示,并通过改变 type 的值来实现切换。

注意:两个带 v-ifv-else 的元素需要相邻

除了 v-ifv-else , 还有 v-else-if 可以使用。

举个栗子:

<!-- 结构 -->
<template>
  <div id="root">
    <h1 v-if="type == 0">A</h1>
    <h1 v-else-if="type == 1">B</h1>
    <h1 v-else-if="type == 2">C</h1>
    <h1 v-else>D</h1>

    <button @click="switchShow">切换</button>
  </div>
</template>

<!-- 脚本 -->
<script>
export default {
  name: 'App',
  data() {  // 定义数据
    return {
      type: false
    }
  },
  methods: {  // // 这个methods属性中定义了当前Vue实例所有可用的方法
    switchShow: function toggle() {
      this.type++
      if (this.type > 3) {
        this.type = 0
      }
    }
  },
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

上面使用 type 控制多个 <h1> 的切换显示,实现A、B、C、D的切换。