学生管理案例

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

image 2025 02 10 18 38 37 553
Figure 1. 图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 所示。

image 2025 02 10 19 06 11 650
Figure 2. 图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>