学生管理系统---数据驱动版

什么是数据驱动?


        数据驱动视图是指通过数据来驱动页面的显示和行为,使得页面的展示和交互元素可以根据数据的变化而自动更新。这种开发模式通常使用前端框架或库来实现,例如Vue.js、React等。简单来说,其实就是通过操作原始数据来进行显示更新页面,通过更改原始数据重新渲染页面。而并非使用dom操作。

数据驱动应用场景

数据驱动应用场景非常广泛,比如,在管理系统、电子商务平台、社交网络等复杂应用中,页面上的数据和用户交互元素需要频繁地更新和响应,数据驱动视图的开发模式能够极大地提高开发效率,并且使得页面的维护和拓展更加容易。

数据驱动案例(学生管理系统)

下面,我们来通过学生管理系统深入了解一下数据驱动,这个项目涉及到了增删改的操作,全部用的是数据驱动。

页面总体效果

 页面结构:

页面的布局的和结构

<div class="box">
        <h1>学生管理系统</h1>
        <div class="ck">
            <div class="ck1">
                用户名:<input type="text" class="ok2 ok3"><br>
                <div class="dk1 none">请输入正确的用户名</div>
            </div>
            <div class="ck2">
                密码:<input type="text" class="ok2 ok4"><br>
                <div class="dk2 none">请输入正确的密码</div>
            </div>
            <div class="ck3">
                邮箱:<input type="text" class="ok2 ok5">
                <div class="dk3 none">请输入正确的邮箱
                </div>
            </div>
            <div class="ccc">
                <button class="btn btn1">添加</button>
                <button class="btn btn2">重置</button>
            </div>
        </div>

        <table>
            <thead>
                <tr>
                    <td class="text-c">编号</td>
                    <td>姓名</td>
                    <td>密码</td>
                    <td>邮箱</td>
                    <td>操作</td>
                </tr>
            </thead>
            <tbody id="ttt">
            </tbody>
        </table>
    </div>

页面样式:

通过CSS对页面样式进行设计和美化

* {
            margin: 0;
            padding: 0;
        }

        *::selection {
            background-color: none;
        }

        h1 {
            text-align: center;
        }

        .ck {
            text-align: center;
            margin-top: 20px;
        }

        .ck1 input {
            width: 200px;
            height: 23px;
            margin-left: 5px;
            padding-left: 10px;
            outline: none;
            border: none;
            border: 1px solid #ccc;

        }

        .ck2 input {
            width: 200px;
            height: 23px;
            margin-left: 24px;
            padding-left: 10px;
            outline: none;
            border: none;
            border: 1px solid #ccc;
        }

        .ck3 input {
            width: 200px;
            height: 23px;
            margin-left: 24px;
            padding-left: 10px;
            outline: none;
            border: none;
            border: 1px solid #ccc;
        }

        .ck1::after {
            content: "*";
            width: 20px;
            height: 20px;
            display: block;
            position: absolute;
            left: 42%;
            color: red;
            top: 0px;

        }

        .ck1 {
            box-sizing: border-box;
            position: relative;
        }

        .ck2 {
            box-sizing: border-box;
            position: relative;
        }

        .ck3 {
            box-sizing: border-box;
            position: relative;
        }

        .ck2::after {
            content: "*";
            width: 20px;
            height: 20px;
            display: block;
            position: absolute;
            left: 42%;
            color: red;
            top: 0px;
        }

        .ck3::after {
            content: "*";
            width: 20px;
            height: 20px;
            display: block;
            position: absolute;
            left: 42%;
            color: red;
            top: 0px;
        }

        .ccc {
            margin-top: 20px;
            margin-left: 9px;
        }

        .ok1 {
            height: 21px;
            margin-left: 22px;
        }

        .btn {
            width: 78px;
            color: #fff;
            height: 33px;
            border: none;
        }

        .btn1 {
            background-color: lawngreen;
        }

        .btn2 {
            background-color: skyblue;
        }

        table {
            margin: 0 auto;
            margin-top: 70px;
        }

        td {
            width: 132px;
            height: 30px;
        }

        .text-c {
            text-align: center;
        }

        table .wt {
            width: 66px;
        }

        .an {
            width: 51px;
            height: 29px;
            border: none;
            color: #fff;
        }

        .an1 {
            background-color: skyblue;
        }

        .an2 {
            background-color: #ff3040;
        }

        .none {
            display: none;
        }

        .block {
            display: '';
            color: #ff3040;
        }

数据渲染:

这个部分用于直接渲染页面的基本结构,基于数据驱动的思想,这里是直接封装了一个函数

function render() {
                $$('#ttt', true).innerHTML = list.map((item, index) => {
                    return `
                         <tr>
                            <td class="text-c">${item.id}</td>
                            <td>
                                <input class="user-name-input" style="display: ${item.isEdit ? '' : 'none'};" value="${item.name}" />
                                <span style="display: ${item.isEdit ? 'none' : ''};">${item.name}</span>
                            </td>
                            <td>
                                <input class="user-name-input1" style="display: ${item.isEdit ? '' : 'none'};" value="${item.password}" />
                                <span style="display: ${item.isEdit ? 'none' : ''};">${item.password}</span>
                            </td>
                            <td>
                                <input class="user-name-input2" style="display: ${item.isEdit ? '' : 'none'};" value="${item.email}" />
                                <span style="display: ${item.isEdit ? 'none' : ''};">${item.email}</span>
                            </td>
                            <td>
                                <button class="an an1" style="background: ${item.isEdit ? 'green' : 'blue'};" class="edit" data-id="${item.id}" data-type="${item.isEdit ? 'ok' : 'edit'}" data-index="${index}">${item.isEdit ? '完成' : '编辑'}</button>
                                <button class="an an2" data-id='${item.id}'>删除</button>
                            </td>
                        </tr>
                        `
                }).join('')//用于处理转换的问题
               
            }
            render()

删除部分:

这里是封装了一个函数的用于调用方便我们去调用,去实时的实现删除功能

function deletestudentInformation() {//删除的函数
                $$('.an2', false).forEach(e => {
                    e.addEventListener('click', function () {
                        // 给每个元素添加点击事件监听器,当元素被点击时执行以下操作
                        if (confirm('是否永久删除该条数据,是或否')) {
                            //判断用户点击时,为true的话进入判断,如果为false的话不进入判断
                            list = list.filter(v => v.id !== +this.dataset.id)
                            // 使用数组的 filter 方法过滤出 id 不等于当前元素的 dataset 中的 id 属性值的元素,并重新赋值给 list 变量
                            render()
                        }
                    })
                })
            }

删除部分优化:

这里的思想就是给document绑定监听事件,所以这里就可以不用封装成函数从而来调用,这样也可以省去我们一部分的空间

 // 优化后的代码
            document.addEventListener('click', function (e) { //这里给document绑定了一个监听事件,方便去监听事件委托的一个节点
                if (e.target.matches('.an2')) {//在JavaScript中,可以使用Element.matches方法(也称为Element.matchesSelector)来判断一个元素是否与指定的选择器匹配
                    const confirmDelete = confirm('是否永久删除该条数据,是或否');
                    //判断用户点击时,为true的话进入判断,如果为false的话不进入判断
                    if (confirmDelete) {
                        const clickedElementId = parseInt(e.target.dataset.id);
                        list = list.filter(item => item.id !== clickedElementId);
                        // 使用数组的 filter 方法过滤出 id 不等于当前元素的 dataset 中的 id 属性值的元素,并重新赋值给 list 变量
                        render();
                    }
                }
            });

重置按钮:

这里的实现思路的话,是用户输入文本框的文本删的麻烦,可以点击重置按钮,可以一键清空用户输入的文字

/ 4、重置
            let ok3 = $$('.ok3', true)//这里获取了三个input框的节点
            let ok4 = $$('.ok4', true)
            let ok5 = $$('.ok5', true)
            let RegExp = /[\u4E00-\u9FA5]/ //这里是做的是三个文本框的正则表达式
            let RegExp1 = /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$/
            let RegExp2 = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
            function resetting() {//这里做了清空操作
                ok3.value = ''
                ok4.value = ''
                ok5.value = ''
            }
            $$('.btn2', true).onclick = function () {//重置按钮的点击事件
                resetting()//这里做了调用函数的操作
            }

添加部分:

这里实现用户输入的数据可以添加在页面上,以及给该文本框实现一个正则验证,下面是实现思路

 // 5、添加
            $$('.btn1', true).onclick = function () {
                const dk1 = $$('.dk1', true)
                const dk2 = $$('.dk2', true)
                const dk3 = $$('.dk3', true)
                flag = true
                if (!ok3.value || !RegExp.test(ok3.value)) {//这里是做了一个用户名的正则验证
                    dk1.classList.remove('none')
                    dk1.classList.add('block')
                    flag = false
                } else {
                    dk1.classList.remove('block')
                    dk1.classList.add('none')
                }
                if (!ok4.value || !RegExp1.test(ok4.value)) {//这里是做了一个密码正则的验证
                    dk2.classList.remove('none')
                    dk2.classList.add('block')
                    flag = false
                } else {
                    dk2.classList.remove('block')
                    dk2.classList.add('none')
                }
                if (!ok5.value || !RegExp2.test(ok5.value)) {//这里是做了一个邮箱正则的验证
                    dk3.classList.remove('none')
                    dk3.classList.add('block')
                    flag = false
                } else {
                    dk3.classList.remove('block')
                    dk3.classList.add('none')
                }
                if (!flag) {
                    return false//这里校验不通过的话,就直接退出
                }
                list = [...list, {
                    id: list.length + 1,
                    name: ok3.value,
                    password: ok4.value,
                    email: ok4.value,
                }]
                resetting()
                render()
            }

本地存储:

实现刷新不会使用户输入的数据丢失,所以这块我们就用到了本地存储

function handleSetStorage(key, value) {
                window.localStorage.setItem(key, JSON.stringify(value))//这里是设置了本地存储
            }

            function handleGetStorage(key) {
                return JSON.parse(window.localStorage.getItem(key)) || []//这里是拿取了本地存储
            }

 编辑功能:

我们为了实现用户想改输入的数据时,设置了修改的按钮,这样可以提升用户的体验

 function edit() {//编辑按钮的函数
                $$('.an1', false).forEach(el => {
                    el.addEventListener('click', function () {
                        const id = this.dataset.id
                        const type = this.dataset.type
                        const index = this.dataset.index
                        list.forEach(item => {
                            if (+id === item.id) {//找到点击编辑按钮的那行数据
                                item.isEdit = type !== 'ok'
                                type === 'ok' && (item.name = $$('.user-name-input', false)[index].value)//这里
                                type === 'ok' && (item.password = $$('.user-name-input1', false)[index].value)
                                type === 'ok' && (item.email = $$('.user-name-input2', false)[index].value)
                            }
                        })
                        render()//这里调用渲染函数从新渲染视图
                    })
                })
            }

总结与感悟:

通过这个项目,我获得了许多宝贵的经验与知识,我对数据驱动的思想有了更深刻的理解.,我掌握了实现响应式页面更新的技巧,当数据发生变化时,数据能够自动更新,提升了用户体验。并且我了解了本地存储技术,通过它实现了数据永久存储,避免了因页面刷新而导致数据丢失的问题,增强用户体验。这些收获让我更专注于业务逻辑处理,避免使用dom操作,提高开发效率。
我获得了宝贵的经验和知识。我学会了如何构建清晰的前端架构,将业务逻辑与界面表现分离,使得前端代码更易于组织和维护。我掌握了实现响应式页面更新的技巧,当数据发生变化时,页面元素能够自动更新,极大地提升了用户体验。我深入了解了本地存储技术,通过它实现了数据的持久化存储,避免了因页面刷新而导致数据丢失的问题,从而增强了用户体验。在采用数据驱动视图的开发模式中,我们通过单元测试与集成测试进一步提高了代码质量和可靠性。这些收获让我们更专注于业务逻辑处理,降低了对DOM操作的关注,提高了开发效率。总结来说,数据驱动视图的开发模式在现代Web开发中具有显著优势,能够提高开发效率、加强页面交互体验,并且使得前端代码更加清晰、易于维护。
 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值