学生管理案例
本节通过学生管理案例,巩固 v-for 数据渲染、v-model 双向数据绑定以及事件修饰符等知识点,案例效果如图 1-18 所示。

需求分析:此案例可拆分为 4 个功能。
-
渲染学生列表。
-
新增学生。
-
删除学生。
-
搜索学生。
渲染学生列表
渲染学生列表之前,首先需要布局静态页面,以下代码是视图层页面布局,完整代码可在配套资源中下载。
<div id="main" v-cloak>
<table cellpadding="0" cellspacing="0">
<tr>
<td>学号</td>
<td>姓名</td>
<td>新增时间</td>
<td>操作</td>
</tr>
<tr>
<td>1</td>
<td>小明</td>
<td>2021</td>
<td><a href="#">删除</a></td>
</tr>
<tr>
<td><input type="text" placeholder="请输入学号" /></td>
<td><input type="text" placeholder="请输入姓名" /></td>
<td><input type="text" placeholder="搜索学生姓名" /></td>
<td><input type="button" value="新增" /></td>
</tr>
</table>
</div>
在 M 层模拟学生列表数据,代码如下。
<script>
var vm = new Vue({
el: '#main',
data: {
list: [
{
id: 1,
name: '小明',
time: new Date()
},
{
id: 2,
name: '小红',
time: new Date()
},
{
id: 3,
name: '小刚',
time: new Date()
}
]
}
});
</script>
模拟的学生列表数据为数组对象的形式,这也是后面项目实战中数据展现的形式,使用 v-for 指令将获取到的数据渲染到视图层,代码如下。
<div id="main" v-cloak>
<table cellpadding="0" cellspacing="0">
<tr>
<td>学号</td>
<td>姓名</td>
<td>新增时间</td>
<td>操作</td>
</tr>
<tr v-for="(item, i) in list" :key="i">
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
<td>{{ item.time }}</td>
<td><a>删除</a></td>
</tr>
</table>
</div>
运行代码,可渲染出学生列表,如图 1-19 所示。

新增学生
需求分析如下:
-
使用 v-model 获取到用户输入的学号、姓名,将时间设置为当前时间,无须用户输入。
-
新增添加学生的方法,在方法中把用户输入的数据组织成一个对象。
-
使用数组的 push 方法,把对象添加到 list 数组,代码如下。
<script>
var vm = new Vue({
el: '#main',
data: {
// 用户输入的学生学号
id: '',
// 用户输入的学生姓名
name: '',
},
methods: {
add() {
var stu = {
id: this.id,
name: this.name,
time: new Date()
}
this.list.push(stu)
this.id = this.name = ''
}
}
})
</script>
删除学生
需求分析如下:
-
给 “删除” 按钮添加单击事件并传入索引,只有传入索引才能确定要具体删除哪条数据,因为删除是 a 标签,使用事件修饰符将 a 标签的默认样式清除。
-
使用数组的 splice 方法删除选中的数据,代码如下。
视图层代码如下。
<div id="main" v-cloak>
<table cellpadding="0" cellspacing="0">
<tr>
<td>学号</td>
<td>姓名</td>
<td>新增时间</td>
<td>操作</td>
</tr>
<tr v-for="(item, i) in list" :key="i">
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
<td>{{ item.time }}</td>
<td><a @click.prevent="del(i)">删除</a></td>
</tr>
</table>
</div>
删除事件代码如下。
<script>
var vm = new Vue({
el: '#main',
data: {
list: [] // 请确保list已经初始化为一个空数组
},
methods: {
del(i) {
console.log(i);
this.list.splice(i, 1);
}
}
})
</script>
搜索学生
需求分析如下。
-
使用 v-model 获取用户输入的学生姓名。
-
新增搜索方法,传入参数,参数就是用户输入的学生姓名。
-
使用数组的 forEach 方法遍历整个数组,获取数组中的姓名包含用户传递参数的数据,并组成新的数组,代码如下。
视图层代码如下。
<div id="main" v-cloak>
<table cellpadding="0" cellspacing="0">
<tr>
<td>学号</td>
<td>姓名</td>
<td>新增时间</td>
<td>操作</td>
</tr>
<tr v-for="(item, i) in search(keywords)" :key="i">
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
<td>{{ item.time }}</td>
<td><a @click.prevent="del(i)">删除</a></td>
</tr>
<tr>
<td><input type="text" v-model="id" /></td>
<td><input type="text" v-model="name" /></td>
<td><input type="text" placeholder="搜索" v-model="keywords" /></td>
</tr>
</table>
</div>
代码解析如下。
v-for 将原先的 “in list” 修改成了 “in search(keywords)”,其中,参数 keywords 没有加引号,说明是变量,Vue 会到 data 数据中找 keywords 变量,而 data 中的 keywords 就是用户输入搜索的学生姓名。
M 层代码如下。
<script>
var vm = new Vue({
el: '#main',
data: {
keywords: '' // 用户输入搜索的学生姓名
},
methods: {
search(keywords) {
var newList = [];
this.list.forEach(item => {
if (item.name.indexOf(keywords) != -1) {
newList.push(item);
}
});
return newList;
}
}
});
</script>