增删改查表格(好看且有趣)

news/2024/12/4 22:41:46/

演示地址:https://codepen.io/kissbackboard/pen/oNExNKL

目前实现了增删改查、排序、趣味提示信息、回收站。

右边的猫头鹰是使用Spline3D设计工具制作,我拿官方模型库里的加工了一下

HTML:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, addial-scale=1.0"><title></title><!-- 主要的CSS --><link rel="stylesheet" href="css/main.css">
</head><body><div id="root"><!-- 用于输入新增用户信息的表单 --><transition name="modalBox" appear><div v-show="showOperate" class="operate" @click.self="showOperate = ifOwlSpeak = false"><div @keyup.enter.stop="affirm"><label>学号:</label><input type="number" ref="addCode" v-model="addCode" @input="OwlSpeakShow('若学号重复会无法提交哦')"><br><label>姓名:</label><input type="text" @keydown="banSpace" v-model="addName"><br><label>性别:</label><select class="addSex" v-model="addSex" @change="OwlSpeakShow('原来是一位' + addSex + '同学啊')"><option value="男">男</option><option value="女">女</option></select><br><label>年龄:</label><input type="number" v-model="addAge" @input="OwlSpeakShow('按回车也可以提交哦')"><br><button @click="affirm" class="affirmBtn">确定</button><button @click="showOperate = ifOwlSpeak = false" class="cancelBtn">取消</button></div></div></transition><!-- 新增、查询、回收站功能 --><button @click="add" class="addBtn" @mouseenter="OwlSpeakShow('是有新同学要来吗')" @mouseleave="OwlSpeakHide">添加学生</button><input type="text" placeholder="按姓名查询" class="inquireName" @focus="inquireAlone('name')" v-model="inquireNameValue" @input="inquireName" @mouseenter="OwlSpeakShow('输入后会自动查询')" @mouseleave="OwlSpeakHide"><input type="number" placeholder="按学号查询" class="inquireCode" @focus="inquireAlone('code')" v-model="inquireCodeValue" @input="inquireCode" @mouseenter="OwlSpeakShow('用完整学号查询最准确了')" @mouseleave="OwlSpeakHide"><button class="recycleBtn" @click="showRecycle = true" @mouseenter="OwlSpeakShow('可以查看被删除的学生')" @mouseleave="OwlSpeakHide">回收站</button><!-- 回收站表格 --><transition name="modalBox" appear><div class="recycleInfoTable" @click.self="showRecycle = false" v-show="showRecycle"><h1>回收站</h1><table cellspacing='1' cellpadding='0' class="infoTable"><thead><tr><th @click="recycleVariousSort('code')" @mouseenter="OwlSpeakShow('点击可以按学号排序')" @mouseleave="OwlSpeakHide">学号</th><th @click="recycleVariousSort('name')" @mouseenter="OwlSpeakShow('点击可以按姓名排序')" @mouseleave="OwlSpeakHide">姓名</th><th @click="recycleVariousSort('date')" @mouseenter="OwlSpeakShow('点击可以按日期排序')" @mouseleave="OwlSpeakHide">删除时间</th><th @dblclick="allEmpty" @mouseenter="OwlSpeakShow('双击清空回收站所有信息')" @mouseleave="OwlSpeakHide">操作</th></tr></thead><tbody is="transition-group" name="fade" appear><tr v-for="user in recycleInfo" v-show="user.satisfy" :key="user.id"><td>{{user.code}}</td><td>{{user.name}}</td><td>{{user.date | timeformater}}</td><!--还原和彻底删除操作 --><td><button class="saveBtn" @click="reductionInfo(user)" @mouseenter="OwlSpeakShow('点击还原 ' + user.name + ' 的信息')" @mouseleave="OwlSpeakHide">还原</button><button class="deleteBtn" @click="thoroughDeleteInfo(user)" @mouseenter="OwlSpeakShow('彻底删除 ' + user.name + ' 的信息')" @mouseleave="OwlSpeakHide">彻底删除</button></td></tr></tbody></table></div></transition><!-- 学生信息表格 --><table cellspacing='1' cellpadding='0' class="infoTable"><thead><tr><th @click="variousSort('code')" @mouseenter="OwlSpeakShow('点击可以按学号排序')" @mouseleave="OwlSpeakHide">学号</th><th @click="variousSort('name')" @mouseenter="OwlSpeakShow('点击按姓氏首字母排序')" @mouseleave="OwlSpeakHide">姓名</th><th @click="variousSort('sex')" @mouseenter="OwlSpeakShow('点击可以按性别排序')" @mouseleave="OwlSpeakHide">性别</th><th @click="variousSort('age')" @mouseenter="OwlSpeakShow('点击可以按年龄排序')" @mouseleave="OwlSpeakHide">年龄</th><th @mouseenter="OwlSpeakShow('目前一共有 ' + info.length + ' 位学生')" @mouseleave="OwlSpeakHide">操作</th></tr></thead><tbody is="transition-group" name="fade" appear><tr v-for="user in info" v-show="user.satisfy" @keyup.enter.stop="currentCodeIfRepeat(user)" :key="user.id"><td><span v-show="!user.isEdit">{{user.code}}</span><input ref="editFirst" v-show="user.isEdit" type="number" v-model="user.code" @input="OwlSpeakShow('若学号重复会无法保存哦')"></td><td><span v-show="!user.isEdit">{{user.name}}</span><input v-show="user.isEdit" type="text" v-model="user.name" @keydown="banSpace"></td><td><span v-show="!user.isEdit">{{user.sex}}</span><select v-show="user.isEdit" v-model="user.sex"><option value="男">男</option><option value="女">女</option></select></td><td><span v-show="!user.isEdit">{{user.age}}</span><input v-show="user.isEdit" type="number" v-model="user.age"></td><!-- 编辑和删除操作 --><td><button v-show="user.isEdit" @click="edit(user)" class="saveBtn" @mouseenter="OwlSpeakShow('按回车键也可以保存哦')" @mouseleave="OwlSpeakHide">保存</button><button v-show="!user.isEdit" @click="edit(user)" class="editBtn" @mouseenter="OwlSpeakShow(user.name +' 的信息有误吗')" @mouseleave="OwlSpeakHide">编辑</button><button @click="deleteInfo(user)" class="deleteBtn" @mouseenter="OwlSpeakShow('你要删除 '+ user.name +' 吗?')" @mouseleave="OwlSpeakHide">删除</button></td></tr></tbody></table><!-- 猫头鹰 webGL --><div class="owl" @mouseenter="OwlSpeakShow('应该不会有bug了吧...')" @mouseleave="OwlSpeakHide" v-show="ifOwl"><div :class="[{ cover: !owlLoadIfSucceed }, { part: owlLoadIfSucceed }]" @click="ifOwl = false" @mouseenter="OwlSpeakShow('点击后将把我隐藏')" @mouseleave="OwlSpeakHide">{{owlLoadInfo}}</div><p v-show="ifOwlSpeak">{{owlSpeak}}</p><!-- 使用Spline3D设计工具制作 --><iframe src='https://my.spline.design/copy-15a6b025c7aac1efc79c2de6c4aac93a/' frameborder='0' width='180px' height='180px' scrolling="no" @load="owlLoad"></iframe></div></div><!-- JS部分 --><script src="js/dayjs.min.js"></script><script src="js/vue.js"></script><!-- 默认的学生信息,方便测试各个功能(可删除) --><script src="js/defaultInfo.js"></script><!-- 主要的JS --><script src="js/main.js"></script>
</body></html>

CSS:

* {margin: 0;padding: 0;box-sizing: border-box;
}body {display: flex;justify-content: center;
}#root {padding-top: 30px;position: relative;
}button {cursor: pointer;user-select: none;
}.infoTable {margin-top: 20px;background-color: rgb(255, 255, 255);border-radius: 5px;overflow: hidden;
}.infoTable td,
.infoTable th {padding: 6px;min-width: 180px;max-width: 25vw;height: 50px;overflow: auto;text-align: center;background-color: #3d559d;color: white;
}.infoTable th {height: 40px;background-color: #6472b8;cursor: pointer;user-select: none;
}.infoTable tr td:last-child button {width: 40%;height: 30px;background-color: white;border: none;border-radius: 2px;
}.infoTable tbody tr td .editBtn {color: #032ebc;
}.infoTable tbody tr td .saveBtn {color: #032ebc;font-weight: 900;
}.infoTable tbody tr td .deleteBtn {color: rgb(255, 57, 57);
}.infoTable tbody tr:hover {opacity: 0.85;
}.recycleInfoTable {width: 100vw;height: 100vh;position: fixed;z-index: 2;top: 0px;left: 0px;background-color: #ffffffaf;display: flex;justify-content: center;padding-top: 60px;
}.recycleInfoTable table {height: 1px;
}.recycleInfoTable td:nth-child(3),
.recycleInfoTable th:nth-child(3) {padding: 6px;width: 360px;height: 30px;
}.recycleInfoTable h1 {position: absolute;top: 10px;color: rgb(255, 57, 57);
}.operate {display: grid;place-content: center;width: 100vw;height: 100vh;background-color: #3d559d41;position: fixed;z-index: 9;top: 0px;left: 0px;
}.operate div {width: 500px;height: 280px;background-color: #ffffff;text-align: center;padding-top: 20px;box-shadow: 1px 6px 15px 1px rgba(0, 0, 0, 0.4);border-radius: 5px;
}.operate div input,
.addSex {width: 50%;height: 30px;margin-top: 15px;padding-left: 5px;
}.operate div input:focus {outline-color: #3d6bff;
}.operate div button {margin-top: 20px;margin-left: 30px;margin-right: 30px;width: 22%;height: 15%;background-color: #6776ff;border: none;color: white;font-size: 16px;border-radius: 3px;
}.operate div label {font-weight: 900;letter-spacing: 5px;
}/* 学生信息表格中的表单 */
.infoTable tbody tr td input,
.infoTable tbody tr td select {text-align: center;width: 150px;height: 33px;font-size: 15px;
}.infoTable tbody tr td input:focus {outline-color: #2e5eff;
}.addBtn {width: 120px;height: 40px;background-color: #4d5ffd;border: none;color: white;font-size: 16px;border-radius: 3px;/* word-spacing: 1px; */
}.recycleBtn {width: 120px;height: 40px;background-color: #fd4b37;border: none;color: white;font-size: 16px;border-radius: 3px;position: fixed;right: 10px;bottom: 10px;
}/* 用于查询的表单 */
.inquireCode,
.inquireName {width: 150px;height: 37px;position: absolute;z-index: 99;right: 0px;top: 30px;text-align: center;border: 1px solid #5b84ff;border-radius: 2px;
}.inquireCode:focus,
.inquireName:focus {outline-color: #5b84ff;
}.inquireName {right: 160px;
}.owl {position: fixed;z-index: 99;top: 100px;right: 0px;color: #4364c7;/* background-color: #032ebc; */
}.owl .cover {width: 100%;height: 100%;background-color: transparent;position: absolute;right: 30px;bottom: -30px;font-size: 22px;font-weight: 900;-webkit-text-stroke: .3px rgb(255, 255, 255);
}.owl .part {width: 33px;height: 33px;background-color: white;border-radius: 100%;position: absolute;right: 15px;bottom: 19px;cursor: pointer;font-size: 6px;text-align: center;line-height: 33px;transition: all .1s;
}.owl .part:hover {background-color: #1f46c5;color: white;
}.owl p {width: auto;height: auto;text-align: center;position: absolute;z-index: 2;bottom: 190px;left: -45px;user-select: none;background-color: #476cff;color: white;padding: 10px;border-radius: 5px;
}.owl p::before {content: '';width: 30px;height: 30px;background-color: #476cff;position: absolute;z-index: -1;bottom: -25px;right: 55px;clip-path: polygon(0 0, 50% 50%, 100% 0);
}.fade-enter-active {animation: fadeAnimate 0.3s ease-in-out;
}.fade-leave-active {animation: fadeAnimate 0.3s ease-in-out reverse;
}@keyframes fadeAnimate {from {opacity: 0;transform: translateY(-50%);}to {transform: translateY(0%);opacity: 1;}
}.modalBox-enter-active {animation: modalBox 0.3s ease-in-out;
}.modalBox-leave-active {animation: modalBox 0.3s ease-in-out reverse;
}@keyframes modalBox {0% {transform: translateY(-100px) scale(2);opacity: 0;}100% {transform: translateY(0px) scale(1);opacity: 1;}
}

JS:

// 实例化Vue
const vm = new Vue({el: '#root',data: {info: JSON.parse(localStorage.getItem("persistence_user_info")) || [],recycleInfo: JSON.parse(localStorage.getItem("recycle_user_info")) || [],showOperate: false,addCode: '',addName: '',addSex: '',addAge: '',inquireCodeValue: '',inquireNameValue: '',ifOwl: true,ifOwlSpeak: true,owlSpeak: '可以持久化存储信息哦',owlLoadIfSucceed: false,owlLoadInfo: 'canvas加载中...',ascOrDesc: 'asc',// 猫头鹰随机说的句子owlRandomSpeak: ['可以持久化存储信息哦','JavaScript是最好的语言','没有对象? new一个','本人面向百度、CSDN编程','我以后在给代码加注释','见鬼了,昨天还好好的','启动! Ctrl+C大法','它在我电脑上能运行',],showRecycle: false},methods: {add() {// 使所有用于增加操作的表单值为空this.addCode = this.addName = this.addSex = this.addAge = '';this.showOperate = true;// 下一次DOM更新结束后执行指定的回调函数this.$nextTick(function () {this.$refs.addCode.focus();});},affirm() {let code = this.addCode;let name = this.addName;let sex = this.addSex;let age = this.addAge;// 判断所有用于输入新增用户信息的表单 值是否为空if (code == '' || name == '' || sex == '' || age == '') return alert('信息不完整');// 判断是否有学号重复for (let i = 0; i < this.info.length; i++) {if (this.info[i].code == this.addCode) return alert('学号重复!');}// 新建一个学生对象let obj = {id: Math.random(),code,name,sex,age,satisfy: true,isEdit: false}// 把这个学生对象添加到infothis.info.push(obj);this.showOperate = false;this.OwlSpeakShow('欢迎新同学:' + name);},deleteInfo(user) {// 添加到回收站let obj = {id: user.id,code: user.code,name: user.name,sex: user.sex,age: user.age,satisfy: user.satisfy,isEdit: user.isEdit,date: +new Date(),};this.recycleInfo.unshift(obj);// 删除一个学生对象this.info = this.info.filter(item => item.id != user.id);this.OwlSpeakShow(user.name + ' 的信息删除成功');},edit(user) {// 判断是否为编辑状态if (user.isEdit) {// 非编辑状态// 判断当前行的学号是否与其他学号重复this.currentCodeIfRepeat(user);} else {// 编辑状态user.isEdit = true;// 下一次DOM更新结束后执行指定的回调函数this.$nextTick(function () {// 点击编辑后使第一个文本框赋值this.$refs.editFirst.forEach(item => {if (item.value == user.code) return item.focus();});});}},// 按学号查询inquireCode() {let meetsNum = 0;let inquireInfo;// 判断是查询回收站的表格还是学生信息的表格this.showRecycle ? inquireInfo = this.recycleInfo : inquireInfo = this.info;inquireInfo.forEach(element => {element.code.toString().indexOf(this.inquireCodeValue) != -1 ? element.satisfy = true : element.satisfy = false;element.satisfy && meetsNum++;});this.inquireCodeValue ? this.OwlSpeakShow('有 ' + meetsNum + ' 位同学符合查询条件') : this.OwlSpeakShow('输入后会自动查询');},// 按姓名查询inquireName() {this.banSpace();let meetsNum = 0;let inquireInfo;// 判断是查询回收站的表格还是学生信息的表格this.showRecycle ? inquireInfo = this.recycleInfo : inquireInfo = this.info;inquireInfo.forEach(element => {element.name.indexOf(this.inquireNameValue) != -1 ? element.satisfy = true : element.satisfy = false;element.satisfy && meetsNum++;});this.inquireNameValue ? this.OwlSpeakShow('有 ' + meetsNum + ' 位同学符合查询条件') : this.OwlSpeakShow('输入后会自动查询');},inquireAlone(mark) {if (mark == 'code') {this.inquireCode();this.inquireNameValue = '';} else if (mark == 'name') {this.inquireName();this.inquireCodeValue = '';}},// 禁止输入空格banSpace() {window.event.target.value = window.event.target.value.replace(/\s+/g, ''); //适用于keyup事件if (window.event.keyCode == 32 || window.event.code == 'Space' || window.event.key == ' ') return window.event.returnValue = false; //适用于keydown事件},// 判断所有学号是否重复,并把重复学号所在的行设为编辑状态allCodeIfRepeat() {let flag = false;for (let i = 0; i < this.info.length; i++) {let frequency = 0;let element = this.info[i];for (let j = 0; j < this.info.length; j++) {let elements = this.info[j];if (element.code == elements.code) {frequency++;if (frequency > 1) {element.isEdit = true;flag = true;}}}}flag && alert('学号重复!');return flag;},// 判断当前行的学号是否与其他学号重复currentCodeIfRepeat(user) {let frequency = 0;for (let i = 0; i < this.info.length; i++) {if (this.info[i].code == user.code) {frequency++;if (frequency > 1) {alert('学号重复!');return true;}}}user.isEdit = false;return false;},OwlSpeakShow(speak) {this.ifOwlSpeak = true;this.owlSpeak = speak;},OwlSpeakHide() {this.ifOwlSpeak = false;},// 学生信息表格排序variousSort(mark) {// 根据学号排序if (mark == 'code') {this.ascOrDesc == 'asc' ? this.info.sort((a, b) => a.code - b.code) : this.info.sort((a, b) => b.code - a.code);}// 根据姓名排序else if (mark == 'name') {this.ascOrDesc == 'asc' ? this.info.sort((a, b) => a.name.localeCompare(b.name)) : this.info.sort((a, b) => b.name.localeCompare(a.name));}// 根据性别排序else if (mark == 'sex') {this.ascOrDesc == 'asc' ? this.info.sort((a, b) => a.sex.localeCompare(b.sex)) : this.info.sort((a, b) => b.sex.localeCompare(a.sex));}// 根据年龄排序else if (mark == 'age') {this.ascOrDesc == 'asc' ? this.info.sort((a, b) => a.age - b.age) : this.info.sort((a, b) => b.age - a.age);}this.ascOrDesc == 'asc' ? this.ascOrDesc = 'desc' : this.ascOrDesc = 'asc';},// 回收站表格排序recycleVariousSort(mark) {if (mark == 'code') {this.ascOrDesc == 'asc' ? this.recycleInfo.sort((a, b) => a.code - b.code) : this.recycleInfo.sort((a, b) => b.code - a.code);}// 根据姓名排序else if (mark == 'name') {this.ascOrDesc == 'asc' ? this.recycleInfo.sort((a, b) => a.name.localeCompare(b.name)) : this.recycleInfo.sort((a, b) => b.name.localeCompare(a.name));}// 根据日期排序else if (mark == 'date') {this.ascOrDesc == 'asc' ? this.recycleInfo.sort((a, b) => a.date - b.date) : this.recycleInfo.sort((a, b) => b.date - a.date);}this.ascOrDesc == 'asc' ? this.ascOrDesc = 'desc' : this.ascOrDesc = 'asc';},// 对于iframe加载成功的处理owlLoad() {this.owlLoadIfSucceed = true;this.owlLoadInfo = '隐藏';},// 在回收站彻底删除thoroughDeleteInfo(user) {// 彻底删除一个学生对象this.recycleInfo = this.recycleInfo.filter(item => item.id != user.id);},// 在回收站还原一个学生reductionInfo(user) {let repeat = false;for (let i = 0; i < this.info.length; i++) {if (this.info[i].code == user.code) {alert('学号重复!');repeat = true;this.info[i].isEdit = repeat;user.isEdit = repeat;} }// 添加到学生信息表let obj = {id: user.id,code: user.code,name: user.name,sex: user.sex,age: user.age,satisfy: user.satisfy,isEdit: repeat};this.info.unshift(obj);this.thoroughDeleteInfo(user);},allEmpty() {this.recycleInfo = [];}},filters: {timeformater(value, str = 'YYYY年MM月DD日 HH:mm:ss') {return dayjs(value).format(str);},},watch: {// 深度监视infoinfo: {deep: true,handler(value) {localStorage.setItem("persistence_user_info", JSON.stringify(value));},},// 深度监视recycleInforecycleInfo: {deep: true,handler(value) {localStorage.setItem("recycle_user_info", JSON.stringify(value));},},},created() {// 恢复各个属性的默认值(防止刷新网页后还处于编辑、查询等状态)this.info.forEach(element => {element.isEdit = false;element.satisfy = true;});// 对于(在编辑状态并且有学号重复的情况下刷新网页)的措施// 判断所有学号是否重复,并把重复学号所在的行设为编辑状态this.allCodeIfRepeat();// 让猫头鹰随机说话setInterval(() => {!this.ifOwlSpeak && this.OwlSpeakShow(this.owlRandomSpeak[Math.floor(Math.random() * this.owlRandomSpeak.length)]);}, 6000);}
});

记得引入vue哦


http://www.ppmy.cn/news/429793.html

相关文章

易语言excel内容查找助手

易语言excel内容查找助手 工具介绍 由于同事需要&#xff0c;公司要求需要我开发一个小excel搜索小工具并且具有能导出另存为excel的功能&#xff0c;然后就有了这个工具。 软件使用说明&#xff1a; 本软件主要把xls得excel文件导入到软件列表&#xff0c;通过列表搜索结果…

超级表格编辑功能详细介绍

超级表格编辑功能详细介绍 今天我们来详细的介绍一下超级表格的编辑功能。 超级表格如何进行复制&#xff0c;黏贴&#xff1f; 部分品牌的电脑有单独的复制快捷键&#xff0c;请您以实际为准&#xff1a; 1. 在超级表格中&#xff0c;如果您想复制一个单元格中的内容到另外一个…

Excel文字排版

真是没有对比就没有伤害&#xff0c;来看看Excel表格中排版前后的惨烈对比&#xff1a; 排版前&#xff1a; 排版后&#xff1a; 一、文字段落排版 Excel单元格中输入文字段落时&#xff0c;位置、行间距等设置非常不方便。而文字框&#xff08;插入 - 文本框&#xff09;则更…

简易电子表格的设计

简易电子表格的设计 问题描述 设计一个支持基本计算统计功能和其它一些表格管理/处理功能的软件&#xff0c;使用户可在该软件的支持下&#xff0c;用交互方式进行表格建立、数据输入、数据编辑及其它一些表格操作。即类似于简易Execel表格处理软件。 基本要求 (1)建立表格…

[易飞]如何制作自定义报表

如何制作自定义报表 要做好报表首先需要掌握以下的技能 1、能够准确的找到信息所在的数据表,以及要显示的字段编号是多少

vxe-table 如何实现全表都可以编辑,所有列可编辑

vxe-table 如何实现全表都可以编辑&#xff0c;所有列可编辑 自定义实现&#xff0c;无法使用内置的CRUD管理 <vxe-table bordershow-overflowref"xTable"height"500":data"tableData":edit-config"{trigger: click, mode: row}"…

实时编辑表格,可以编辑的表格

本站已经有《jquery表格可编辑修改表格里面的值,点击td变input无刷新更新表格》这个案例是一个非常完整的案例&#xff0c;带数据库更新部分 本例没有更新数据库的部分&#xff0c;但是有传递的过程 演示 PHP Code <table id"editTable"> <the…

easyExcel工具

注解格式 通过注解定义格式是 EasyExcel 封装的高级功能&#xff0c;可以让我们很方便的定义格式。 格式化内容 先定义一个使用注解格式化内容的实体类&#xff1a; Data public class FormatContentItem { ExcelProperty(value "字符串标题", converter Ti…