Vue指令

指令简介

Vue.js 中的指令(Directives)是一种特殊的 token,它们以 “v-“ 前缀作为标识符,用于在模板中添加特定的行为或响应式功能。指令可以在模板中直接绑定到 DOM 元素上,以控制其行为和显示。

以下是一些常见的 Vue.js 指令:

  • v-bind:也简写为 :,用于绑定一个或多个属性的值到 DOM 元素。例如,<a v-bind:href="url">Link</a> 可以将 href 属性绑定到 Vue 实例的 url 数据属性。
  • v-model:用于实现双向数据绑定,将表单元素的值与 Vue 实例的数据属性双向关联。例如,<input v-model="message"> 可以将输入框的值与 message 数据属性关联起来。
  • v-for:用于遍历数组或对象,并生成列表。例如,<li v-for="item in items">{{ item }}</li> 可以遍历 items 数组中的每个元素并创建对应的列表项。
  • v-ifv-else:用于条件性地渲染元素。v-if 根据表达式的值决定是否渲染元素,而 v-else 可以与 v-if 一起使用来定义条件分支。
  • v-show:类似于 v-if,但是通过切换元素的 display 样式来显示或隐藏元素,而不是添加或删除元素。
  • v-on:也简写为 @,用于监听 DOM 事件,并在触发时执行指定的方法。例如,<button v-on:click="doSomething">Click Me</button> 将在按钮点击时调用 doSomething 方法。
  • v-pre:跳过这个元素和所有子元素的编译过程,用于性能优化。
  • v-cloak:在元素和 Vue 实例编译完成之前,保持元素及其子元素原始状态,然后在编译完成后移除。用于防止页面闪烁问题。
  • v-once:只渲染元素和组件一次,不再更新。适用于静态内容。
  • v-html:用于渲染包含 HTML 的数据。注意,要谨慎使用,以防止跨站脚本攻击(XSS)。

指令实践案例

v-model

  • v-model:用于实现双向数据绑定,将表单元素的值与 Vue 实例的数据属性双向关联。例如,<input v-model="message"> 可以将输入框的值与 message 数据属性关联起来。
  • 下面代码可以实现在输入框输入任何内容,下面的文字区域也跟着变动。这种就是双向数据绑定。
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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例 - v-model</title>
<script src="https://cdn.staticfile.org/vue/3.2.36/vue.global.min.js"></script>
</head>
<body>
<div id="app" class="demo">
<input type="text" v-model="message">
<p>{{ message }}</p>
</div>

<script>
//定义
const HelloVueApp = {
data() {
return {
message: 'Hello Vue!!'
}
}
}

Vue.createApp(HelloVueApp).mount('#app')
</script>
</body>
</html>

v-bind

v-bind:也简写为 :,用于绑定一个或多个属性的值到 DOM 元素。例如,<a v-bind:href="url">Link</a> 可以将 href 属性绑定到 Vue 实例的 url 数据属性。

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
<!DOCTYPE html>
<html>
<head>
<title>v-bind 示例</title>
<script src="https://cdn.staticfile.org/vue/3.2.36/vue.global.min.js"></script>
</head>
<body>
<div id="app">
<a v-bind:href="url">Visit Vue.js Website</a>
</div>

<script>
const app = Vue.createApp({
data() {
return {
url: 'https://vuejs.org/'
};
}
});

app.mount('#app');
</script>
</body>
</html>

v-bind与v-model区别

v-bindv-model 有不同的用途,虽然它们都可以用于操作表单元素的属性,但不能完全替代对方,因为它们解决不同的问题。

  1. v-bind:主要用于单向数据绑定,它将一个数据属性的值绑定到元素的属性上。通常用于将 Vue 实例中的数据显示到页面上,但不支持用户输入或交互。例如,你可以使用 v-bind 将数据绑定到一个元素的 hrefsrcclass 等属性上。

    1
    <a v-bind:href="url">Visit Vue.js Website</a>
  2. v-model:用于实现双向数据绑定,它不仅可以将数据属性的值绑定到元素的属性上,还可以监听用户输入,将用户输入的值同步回数据属性。这使得你可以创建具有交互性的表单元素。例如,你可以使用 v-model 来绑定一个输入框的值,并在用户输入时自动更新数据属性。

    1
    <input v-model="message">

所以,v-bindv-model 都有各自的用途:

  • 使用 v-bind 时,你是在单向地将数据从 Vue 实例绑定到元素,通常用于展示数据。

  • 使用 v-model 时,你可以实现双向数据绑定,将数据绑定到元素,并且能够监听用户的输入,将用户输入的数据自动同步回 Vue 实例中的数据属性。这在创建交互性表单时非常有用。

v-if

v-else是一个条件渲染指令,通常与v-ifv-else-if一起使用,用于在满足特定条件时渲染内容。
v-else指令必须紧随在一个带有v-ifv-else-if的元素之后,并且它指示该元素只在前面的条件不满足时才会被渲染。
以下是一个示例,演示了v-ifv-else的用法:

1
2
3
4
5
6
7
8
<div v-if="condition">
<!-- 这个元素将在条件满足时渲染 -->
条件满足时显示的内容
</div>
<div v-else>
<!-- 这个元素将在条件不满足时渲染 -->
条件不满足时显示的内容
</div>

在上面的示例中,如果condition为真,第一个div将被渲染,显示”条件满足时显示的内容”。如果condition为假,第一个div不会被渲染,而是第二个div会被渲染,显示”条件不满足时显示的内容”。

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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例 -v-if</title>
<script src="https://cdn.staticfile.org/vue/3.2.36/vue.global.min.js"></script>
</head>
<body>
<div id="app" class="demo">
<p v-if="showMessage">Hello Vue!</p>
<p v-else>Goodbye Vue!</p>
</div>

<script>
const HelloVueApp = {
data() {
return {
showMessage: true
}
}
}

Vue.createApp(HelloVueApp).mount('#app')
</script>
</body>
</html>
  • 输出结果 Hello Vue! 如果showMessage: false 则输出结果为Goodbye Vue!
  • 另外还有一个指令 v-else-ifv-if之后
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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例 - 条件语句</title>
<script src="https://cdn.staticfile.org/vue/3.2.36/vue.global.min.js"></script>
</head>
<body>
<div id="app">
<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>
</div>

<script>
const app = {
data() {
return {
type: "C"
}
}
}

Vue.createApp(app).mount('#app')
</script>
</body>
</html>

v-for

v-for是Vue.js中的一个循环渲染指令,用于在模板中迭代数组或对象的元素,以便动态地生成重复的HTML元素。以下是v-for的基本用法示例:

基本用法

1
2
3
<div v-for="item in items" :key="item.id">
{{ item.text }}
</div>

在这个示例中,v-for指令用于遍历名为items的数组,并为数组中的每个元素创建一个<div>元素,同时在每个<div>中显示item.text的内容。item是一个占位符,代表当前迭代的元素,你可以在{{ }}插值表达式中使用它来显示元素的内容。:key="item.id"是为了提高Vue.js的性能,它用来标识每个循环生成的元素,通常使用唯一的标识符,比如id

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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例 - v-for</title>
<script src="https://cdn.staticfile.org/vue/3.2.36/vue.global.min.js"></script>
</head>
<body>
<div id="app" class="demo">
<ul>
<li v-for="item in items" :key=item.id>
{{ item.text }}
</li>
</ul>
</div>

<script>
const HelloVueApp = {
data() {
return {
items: [
{ id: 1, text: 'Item 1' },
{ id: 2, text: 'Item 2' },
{ id: 3, text: 'Item 3' }
]
}
}
}

Vue.createApp(HelloVueApp).mount('#app')
</script>
</body>
</html>

输出结果

1
2
3
Item 1
Item 2
Item 3

for循环参数

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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例 -for循环</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app">
<ul>
<li v-for="(value, key,index) in object">
{{index}}- {{ key }} : {{ value }}
</li>
</ul>
</div>

<script>
const app = {
data() {
return {
object: {
name: 'sutune',
url: 'http://stune.me',
slogan: '静心成大器,稳定动乾坤!'
}
}
}
}

Vue.createApp(app).mount('#app')
</script>
</body>
</html>

输出结果

1
2
3
0- name : sutune
1- url : http://stune.me
2- slogan : 静心成大器,稳定动乾坤!

代码解析

  • v-for 指令用于遍历数组或对象的元素,可以使用 (value, key)(value, key, index) 这样的语法,其中 value 通常表示当前元素的值,key 表示当前元素的键(适用于对象),index 表示当前元素的索引(适用于数组)。

  • value 参数放在前面是因为在绝大多数情况下,我们更关心遍历的元素的值,而键或索引是可选的,可能不会用到。因此,Vue.js 设计了这个语法的默认顺序,以便更方便地使用。

  • 例如,遍历数组时,通常我们会这样使用:

1
<li v-for="item in items">{{ item }}</li>
  • 在这里,我们只关心数组中的每个元素的值 item,所以 item 放在前面。
    如果需要访问键(适用于对象)或索引(适用于数组),可以按照 (value, key)(value, key, index) 的方式来使用,但在大多数情况下,只使用 value 是足够的。

v-on

以下是使用Vue.js 3.x版本实现的计数器示例:

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
<!DOCTYPE html>
<html>
<head>
<title>Vue 3 计数器示例</title>
<script src="https://cdn.jsdelivr.net/npm/vue@3.0.0/dist/vue.global.prod.js"></script>
</head>
<body>
<div id="app">
<p>点击按钮增加计数:</p>
<p>{{ count }}</p>
<button @click="incrementCount">增加</button>
</div>

<script>
const app = Vue.createApp({
data() {
return {
count: 0
};
},
methods: {
incrementCount() {
this.count++;
}
}
});

const vm = app.mount('#app');
</script>
</body>
</html>
  • 在这个示例中,首先,我们导入Vue.js 3.x的库,然后创建一个Vue应用实例通过Vue.createApp方法。在data属性中,我们定义了一个count属性,该属性用于存储计数值。

  • 接着,我们在methods属性中定义了一个incrementCount方法,该方法在按钮点击时将count属性增加1。

  • 最后,我们通过app.mount('#app')将Vue实例挂载到了一个具有idapp的DOM元素上,这样Vue实例就能够控制这个DOM元素的内容。当按钮被点击时,count的值会增加,并且视图会自动更新以反映新的计数值。

v-once

如果不想改变标签的内容,可以通过使用 v-once 指令执行一次性地插值,当数据改变时,插值处的内容不会更新。

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
<!DOCTYPE html>
<html>
<head>
<title>Vue 3 计数器示例</title>
<script src="https://cdn.jsdelivr.net/npm/vue@3.0.0/dist/vue.global.prod.js"></script>
</head>
<body>
<div id="app">
<p>点击按钮增加计数:</p>
<p v-once>{{ count }}</p>
<button @click="incrementCount">增加</button>
</div>

<script>
const app = Vue.createApp({
data() {
return {
count: 0
};
},
methods: {
incrementCount() {
this.count++;
}
}
});

const vm = app.mount('#app');
</script>
</body>
</html>

v-html

  • v-html 是Vue.js的一个指令,用于将HTML内容动态地渲染到元素中,而不会将其转义为纯文本。它允许您在模板中插入包含HTML标记的字符串,以便以HTML格式呈现内容。
  • 使用 v-html 指令非常简单,只需将其添加到希望动态渲染HTML内容的元素上,然后将需要渲染的HTML字符串绑定到该元素上。示例如下:
  • 需要注意的是,使用 v-html 指令时需要谨慎,确保您只从受信任的源获取HTML内容,以防止潜在的安全风险,例如跨站脚本攻击(XSS)。只要确保插入的HTML内容是可信任的,v-html 可以用于渲染富文本内容。
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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例 - v-html</title>
<script src="https://cdn.staticfile.org/vue/3.2.36/vue.global.min.js"></script>
</head>
<body>
<div id="example1" class="demo">
<p>使用双大括号的文本插值: {{ rawHtml }}</p>
<p>使用 v-html 指令: <span v-html="rawHtml"></span></p>
</div>

<script>
const RenderHtmlApp = {
data() {
return {
rawHtml: '<span style="color: red">这里会显示红色!</span>'
}
}
}

Vue.createApp(RenderHtmlApp).mount('#example1')
</script>
</body>
</html>

v-show

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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例 - v-show</title>
<script src="https://cdn.staticfile.org/vue/3.2.36/vue.global.min.js"></script>
</head>
<body>
<div id="app">
<h1 v-show="ok">Hello!</h1>
</div>

<script>
const app = {
data() {
return {
ok: true
}
}
}

Vue.createApp(app).mount('#app')
</script>
</body>
</html>

参考资料