Vue-基础语法(二)
1. 前言
具体细节参考
Vue官方文档 ,这一章的内容非常重要,我们开发完成之后会通过一个案例将这些知识点全部串起来。
本文主要将讲解 Vue 的基础语法,包括如下内容:
- 条件渲染( v-if 、v-else、v-else-if、v-show)
- 列表渲染( v-for )
- 属性绑定( v-bind、v-model )
- 事件处理( v-on )
- 计算属性( computed )
- 监听器( watch )
- Class 与 Style 绑定
- 任务清单-案例
2. 条件渲染
如下四个条件渲染指令在开发中使用频率非常高,类似于java中的
if、else、else-if。例如,任务状态信息等需求。
v-ifv-elsev-else-ifv-show
2.1. v-if
v-if:用于条件判断指令,一般用于界面内容的渲染,该指令会走表达式为true的分支。
2.2. v-else
v-else: 一般结合v-if使用,该指令走与v-if相反的分支。
2.3. v-else-if
v-else-if:提供的是相应于v-if的,它可以连续多次重复使用。
v-else和v-else-if必须紧跟在v-if或v-else-if的后面,并且它们只能与相同父元素的v-if或v-else-if一起使用。
具体信息如下图

假设,根据 type 类型展示不同的字母。
HTML模板
1 | <body> |
Vue实例和数据
1 | <script> |
- 结果信息

2.4. v-show
v-show:也是条件渲染指令,控制元素显示或者隐藏。 用法与v-if一致,但不能和v-else和v-else-if一起使用。
假设,根据 type 类型展示不同的字母。
HTML模板
1 | <body> |
Vue的实例和数据
1 | <script> |
- 结果信息

2.5. v-if 和 v-show 区别
渲染方式
v-if:当条件为false时,元素中不会在DOM中存在,它会被完全移除。v-show:当条件为false时,元素仍然在DOM中存在,但是通过CSS样式将其隐藏(display)。
性能开销
v-if:当条件为true时,Vue会重新创建元素并渲染。当条件为false时,元素不会被渲染。这也就是说只要切换条件,元素都需要被创新创建和销毁,如果切换频繁这需要的性能开销就比较大了。v-show:当条件不管是true或者false元素都已经被渲染完成了,所以就不存在切换时的性能开销。
如何选择
v-if:当条件为false时,我们也希望减少相关的DOM数量,那我们使用v-if就是合适的。例如如下代码中,我希望展示列表页时,删除详情页的页面信息减少请求次数,就可以使用
v-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<template>
<div class="class-style">
<!-- 根据状态渲染不同组件 -->
<!-- 当状态为 'list' 时,显示列表页 -->
<list-page v-if="status === 'list'"></list-page>
<!-- 当状态为 'detail' 时,显示详情页 -->
<detail-page v-else-if="status === 'detail'"></detail-page>
</div>
</template>
<script>
import ListPage from './ListPage.vue'; // 导入列表页组件
import DetailPage from './DetailPage.vue'; // 导入详情页组件
export default {
components: {
ListPage,
DetailPage
},
data() {
return {
status: 'list', // 默认状态为 'list'
};
}
};
</script>v-show:如果需要频繁切换时,而不产生较大的性能开销时,我们就可以使用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<template>
<div id="app">
<h3>{{ article.title }}</h3>
<button @click="toggleContent(article)">Toggle Content</button>
<div v-show="article.showContent">
{{ article.content }}
</div>
</div>
</template>
<script>
export default {
el: '#app',
data: {
article: { title: 'Article', content: 'Content of Article', showContent: false }
},
methods: {
toggleContent(article) {
article.showContent = !article.showContent;
}
}
};
</script>
3. 列表渲染
列表渲染(
v-for)是非常非常非常常用的一个指令,在开发中 100% 会使用到的一个指令,类似于java中的for循环。
3.1. v-for
v-for:基于一个数组进行列表的渲染。例如,我们的form表单就一定会使用到。
- 语法
1 | <li v-for="{ message } in items"> |
假设我们有一个数组,需要将数组里面的元素全部遍历出来,使用 v-for 实现。
HTML模板1
2
3
4
5
6
7<body>
<div id="app">
<ul v-for="item in items" :key="item.message">
<li>{{ item.message }}</li>
</ul>
</div>
</body>Vue实例和数据1
2
3
4
5
6
7
8
9
10
11<script>
new Vue({
el: "#app",
data: {
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
})
</script>结果

4. 属性绑定
属性绑定:在前端页面中如果需要将数据绑定在
HTML元素或者表单的属性上时,我们需要这些属性绑定的值可以随着数据的变化而进行更新。在属性绑定中,常用的指令有如下两种:
v-bindv-model
4.1. v-bind
v-bind:用于将数据绑定到HTML元素 上,使属性值可以动态的随数据的变化而变化。如果绑定的值是
null或者undefined,那么该 attribute 将会从渲染的元素上移除。
- 语法
1 | <div v-bind:id="dynamicId"></div> |
- 其中
v-bind可以省略不写,直接简化为:
1 | <div :id="dynamicId"></div> |
其中针对 v-bind 的典型用法应该时分页条,如下是 Element-ui 分页条 的用法。

1 | <template> |
4.2. v-model
v-model:用于将数据绑定在 表单元素(文本输入框、复选框、单选按钮等等) 上创建双向绑定数据,可以实现用户的输入与数据之间的同步。
- 语法
1 | <input v-model="message" placeholder="edit me" /> |
假设我们将多个复选框绑定到同一个数组
HTML模板
1 | <body> |
Vue实例和数据
1 | <script> |
- 结果

5. 事件处理
事件处理:在前端开发中我们有时需要监听
DOM事件,并在触发时执行相应的JavaScript代码,控制数据的变化或执行特定的操作。事件处理的值可以是如下两种:
- 内联事件处理器
- 方法事件处理器
- 自定义事件处理器(后面在组建通信时讲解)
- 按钮修饰符
Vue语法
1 | <button v-on:click="handler"> Click Me </button> |
- 简写:省略
v-on:修改为@
1 | <button @click="handler"> Click Me </button> |
5.1. 内联事件处理器
内联事件处理器:指的是在
HTML元素中指定事件监听函数,类似于JavaScript的onclick事件。
假设我们现在通过 内联事件处理器 实现点击按钮数字+1
HTML模板
1 | <body> |
Vue实例和数据
1 | <script> |
- 结果

5.2. 方法事件处理器
方法事件处理器:如果简单的案例可以通过
内联事件处理器进行解决,但业务一旦复杂,那么内联事件处理器的劣势(不够灵活)就出来了。这个时候我们将点击事件的处理逻辑提出来抽成一个方法,就形成了方法事件处理器。
假设我们现在通过 方法事件处理器 实现点击按钮数字+1。如下的案例虽然很简单,但是后续我们
HTML模板
1 | <body> |
Vue实例和数据
1 | <script> |
- 结果

6. 计算属性
计算属性:我们在开发中,无法避免两个属性发生计算的,一旦某个属性的值发生变化,那么他们计算出来的结果也一定会发生变化,这个时候就需要使用到属性计算了。
6.1. computed
computed:当其依赖的属性的值发生变化的时,计算属性会重新计算。
- 语法
1 | export default { |
假设我们需要判断当前数组的数量是否显示元素,不使用 计算属性 computed
HTML模板
1 | <body> |
Vue实例和数据
1 | <script> |
- 结果

假设我们需要判断当前数组的数量是否显示元素,使用 计算属性 computed
计算属性带来的优点
- 复用性高:如果在后期我们使用组件开发,那将会导致大量的冗余代码。如果使用
computed把复杂的逻辑封装为一个属性,使模板中的代码更简洁、易读。 - 性能提高: 计算属性具有自动缓存机制,只有当其依赖的响应式数据发生变化时,才会重新计算。
使用 computed 修改之后的代码如下
HTML模板
1 | <body> |
Vue实例和数据
1 | <script> |
7. 监听器
监听器:监听观察某个事件(程序)发生变化时,事件发生者(事件源) 就会给注册该事件的监听者(监听器)发送消息,告诉监听者某些信息已经发生变化了。
7.1. watch
watch:在
Vue中,监听器通常指的是watch去监听属性来响应数据的变化。
- 浅层监听器语法
1 | export default { |
- 深层监听器语法
1 | export default { |
❔监听器和计算属性有什么区别呢
异步操作:如果说我们需要的数据发生变化需要调用外部
API时,使用计算属性是不行的,因为计算属性采用的是同步,而监听器采用的异步。监控多个数据变化:如果说我们需要监听多个数据源发生变化,并且只要其中一个数据发生变化时就执行操作。那么监听器是更加合适的。
假设我们使用监听器实现登录功能,需求如下:
- 用户名长度必须大于5
- 密码长度必须大于8
- 登录按钮必须满足以上两个条件才可以登录
HTML模板
1 | <body> |
Vue实例和数据
1 |
|
- 结果

8. Class 与 Style 绑定
Class 与 Style 绑定:指的是将
HTML元素的样式与CSS类进行联动的过程。
8.1. Class 绑定
通过为 HTML 元素添加一个或多个类名,你可以将元素与预定义的
CSS样式规则关联起来。
HTML模板
1 | <div class="box red-border"></div> |
CSS样式
1 | .box { |
8.2. Style 绑定
内联样式是直接在 HTML 元素中使用
style属性来定义样式。
HTML模板
1 | <div style="width: 100px; height: 100px; background-color: lightgray;"></div> |
内联样式虽然灵活,但通常不推荐在大规模项目中频繁使用,因为它容易导致代码混乱,难以维护。
8.3. Vue 绑定 class
属性绑定的一个常见需求场景是操纵元素的
CSS class列表和内联样式,这个需求是非常常见的。例如我们需要通过按钮控制表单是需要编辑还是保存。
- 语法
1 | <div :class="{ active: isActive }"></div> |
假设我们通过按钮控制字体的样式
HTML模板
1 | <body> |
Vue实例和数据
1 | <script> |
css样式
1 | <style> |
- 结果

如下代码还可以改写为如下样式
1 | <body> |
9. 任务清单-案例
需求如下
- 通过输入框输入任务点,添加到任务列表中;
- 在添加的任务点通过按钮实现任务是否完成以及删除任务点;
- 统计已经完成的任务数量
- 需要将任务列表添加进缓存,实现关闭浏览器也可以展示任务清单列表
效果图如下:

实现前端页面
HTML前端页面
1
2
3
4
5
6
7
8
9
10
11
12
13
14<body>
<div id="app">
<h3>Todo 任务清单</h3>
<input type="text" placeholder="回车添加任务清单" />
<ul>
<li>
<span> 任务点 </span>
<button> 是否完成 </button>
<button> 删除任务 </button>
</li>
</ul>
<p>已经完成的任务数量:0</p>
</div>
</body>通过输入框输入任务点,添加到任务列表中
HTML前端页面
1
2
3
4
5
6
7
8
9
10
11
12
13
14<body>
<div id="app">
<h3>Todo 任务清单</h3>
<input type="text" @keyup.enter="addTask" v-model="newTask" placeholder="回车添加任务清单" />
<ul v-for="(task , index) in taskList" :key="index">
<li>
<span> {{ task.task }} </span>
<button> 是否完成 </button>
<button> 删除任务 </button>
</li>
</ul>
<p>已经完成的任务数量:0</p>
</div>
</body>Vue实例和数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20<script>
new Vue({
el: "#app",
data() {
return {
newTask: '',
taskList: []
}
},
methods: {
// 添加任务点
addTask() {
if(this.newTask.trim() !== ''){
this.taskList.push({task: this.newTask});
this.newTask = ''
}
}
}
})
</script>- 结果

在添加的任务点通过按钮实现任务 是否完成 以及 删除任务
HTML前端页面
1
2
3
4
5
6
7
8
9
10
11
12
13
14<body>
<div id="app">
<h3>Todo 任务清单</h3>
<input type="text" @keyup.enter="addTask" v-model="newTask" placeholder="回车添加任务清单" />
<ul v-for="(task , index) in taskList" :key="index">
<li>
<span :class="{ active: task.isActive }"> {{ task.task }} </span>
<button @click="completedTask(task)">是否完成</button>
<button @click="removeTask(index)">删除任务</button>
</li>
</ul>
<p>已经完成的任务数量:0</p>
</div>
</body>CSS样式
1
2
3
4
5
6
7<style>
.active{
color: green;
text-decoration: line-through;
}
</style>Vue实例和数据
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<script>
new Vue({
el: "#app",
data() {
return {
newTask: '',
taskList: []
}
},
methods: {
// 添加任务点
addTask() {
if(this.newTask.trim() !== ''){
this.taskList.push({task: this.newTask, isActive: false});
this.newTask = ''
}
},
// 是否完成
completedTask(task) {
task.isActive = !task.isActive
},
// 删除任务
removeTask(index) {
this.taskList.splice(index, 1);
}
}
})
</script>结果

统计已经完成的任务数量
HTML模板
1
2
3
4
5
6
7
8
9
10
11
12
13
14<body>
<div id="app">
<h3>Todo 任务清单</h3>
<input type="text" @keyup.enter="addTask" v-model="newTask" placeholder="回车添加任务清单" />
<ul v-for="(task , index) in taskList" :key="index">
<li>
<span :class="{ active: task.isActive }"> {{ task.task }} </span>
<button @click="completedTask(task)">是否完成</button>
<button @click="removeTask(index)">删除任务</button>
</li>
</ul>
<p>已经完成的任务数量:{{ finishedTotal }}</p>
</div>
</body>Vue实例和数据
1
2
3
4
5
6
7
8
9
10
11<script>
new Vue({
el: "#app",
// 属性计算
computed: {
finishedTotal() {
return this.taskList.filter(item => item.isActive).length;
}
}
})
</script>- 结果

需要将任务列表添加进缓存,实现关闭浏览器也可以展示任务清单列表
Vue实例和数据
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<script>
new Vue({
el: "#app",
data() {
return {
newTask: '',
taskList: []
}
},
// 监听数组
watch: {
taskList: {
handler(newTaskList, oldTaskList) {
localStorage.setItem('taskList', JSON.stringify(newTaskList));
},
deep: true
}
},
// 在生命周期中会讲到 created
created() {
const storedTasks = JSON.parse(localStorage.getItem("taskList"));
if (storedTasks) {
this.taskList = storedTasks;
}
}
})
</script>- 结果







