WEB前端小练习——记事本

一、登陆页面

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>记事本登录注册</title><link rel="stylesheet" href="../css/login.css">
</head><body><div id="app"><!-- 登录页面 --><div v-show="isLoginPage"><h2>登录</h2><form><input v-model="loginUsername" placeholder="用户名" /><input v-model="loginPassword" placeholder="密码" /><button type="button" @click="login">登录</button><button type="button" @click="showRegisterPage">注册</button></form></div><!-- 注册页面 --><div v-show="isRegisterPage"><h2>注册</h2><form><input v-model="registerUsername" placeholder="用户名" /><input v-model="registerPassword" placeholder="密码" type="password" /><button type="button" @click="register">注册</button><button type="button" @click="showLoginPage">返回登录</button></form></div></div><script src="https://cdn.jsdelivr.net/npm/vue@2"></script><script src="../js/login.js"></script>
</body></html>
body {font-family: Arial, sans-serif;display: flex;justify-content: center;align-items: center;min-height: 100vh;margin: 0;background-color: #f4f4f4;
}div {background-color: white;padding: 20px;border-radius: 5px;box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);text-align: center;
}h2 {text-align: center;
}input {width: 80%;padding: 10px;margin-bottom: 15px;border: 1px solid #ccc;border-radius: 3px;
}button {width: 20%;padding: 10px;background-color: #4CAF50;color: white;border: none;border-radius: 3px;cursor: pointer;margin: 30px;
}button:hover {background-color: #45a049;
}    

new Vue({el: '#app',data: {isLoginPage: true,isRegisterPage: false,isLoggedIn: false,loginUsername: '',loginPassword: '',registerUsername: '',registerPassword: '',registeredUsers: [], // 存储已注册用户信息的数组usernamesSet: new Set(), // 用于确保用户名唯一性的Setnotes: [],},mounted() {const storedUsers = localStorage.getItem('registeredUsers');if (storedUsers) {this.registeredUsers = JSON.parse(storedUsers);this.registeredUsers.forEach(user => {this.usernamesSet.add(user.username);});}},methods: {login() {const inputUsername = this.loginUsername;const inputPassword = this.loginPassword;const user = this.registeredUsers.find(u => u.username === inputUsername && u.password === inputPassword);if (user) {console.log('登录成功,跳转到指定页面');window.location.href = '../html/index.html';} else {alert('用户名或密码错误,请重试!');}},register() {const usernamePattern = /^[a-zA-Z0-9]+$/;const passwordPattern = /.{6,}/;if (!this.registerUsername.match(usernamePattern)) {alert('用户名只能包含字母和数字');return;}if (!this.registerPassword.match(passwordPattern)) {alert('密码长度至少为6位');return;}if (this.usernamesSet.has(this.registerUsername)) {alert('该用户名已注册,请更换用户名');return;}const userId = Date.now(); // 使用时间戳作为唯一IDconst newUser = {id: userId,username: this.registerUsername,password: this.registerPassword};this.registeredUsers.push(newUser);this.usernamesSet.add(this.registerUsername);localStorage.setItem('registeredUsers', JSON.stringify(this.registeredUsers));alert('注册成功');console.log('已注册用户数组:', this.registeredUsers);this.isRegisterPage = false;this.isLoginPage = true;},showRegisterPage() {this.isLoginPage = false;this.isRegisterPage = true;},showLoginPage() {this.isRegisterPage = false;this.isLoginPage = true;}}
});

二、记事本页面

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>记事本</title><!-- 引入重置样式表 --><link href="../css/normalize.css" /><link href="../css/reset.css" /><link href="../css/index.css" rel="stylesheet" />
</head><body><!-- 引入 Vue --><script src="https://cdn.jsdelivr.net/npm/vue@2"></script><div id="contain"><div id="box"><div id="header"><span>记事本</span></div><div id="main"><div id="mainTop"><!-- 输入框绑定 message 数据,按下回车键或点击按钮触发 add 方法 --><input id="text" v-model="message" placeholder="just to do it!" @keyup.enter="add" /><button id="add" v-on:click="add">新增笔记</button><!-- 输入框绑定 message 数据,按下回车键或点击按钮触发 add 方法 --><br /><input id="search" v-model="searchKeyword" placeholder="搜索笔记" /><button id="check" v-on:click="select">查询笔记</button></div><div id="mainBottom"><!-- 使用 ul 和 v-for 渲染笔记列表 --><ul><li v-for="(item, index) in searchResult.length > 0? searchResult : filteredNotesList" :key="index"><!-- 笔记内容展示部分 --><!-- 根据 delMuch 状态显示复选框,并绑定 checked 属性 --><input type="checkbox" v-if="delMuch" v-model="item.checked"><span id="order">{{index + 1}}&nbsp;&nbsp;&nbsp;&nbsp;<!-- 根据 isEditing 状态显示文本或输入框 --><!--根据 item.isEditing 的状态来决定显示笔记文本还是输入框。当 isEditing 为 false 时显示笔记文本,为 true 时显示输入框,并且输入框通过 v-model 绑定 tempEditValue,用于编辑笔记内容。--><label v-if="!item.isEditing" id="content">{{item.text}}</label><input id="newMessage" v-else v-model="tempEditValue" type="text"></span><span id="right"><!-- 根据 isEditing 状态显示不同按钮 --><button v-if="!item.isEditing" id="edit" @click="edit(index)">编辑</button><!--现在根据 item.isEditing 的状态切换显示不同按钮。当处于非编辑状态时显示 “编辑” 按钮,点击后进入编辑状态;进入编辑状态后显示 “确定” 和 “取消” 按钮,分别用于确认修改和取消修改。--><button v-else id="confirm" @click="confirmEdit(index)">确定</button><button v-else id="cancel" @click="cancelEdit(index)">取消</button><button id="del" @click="del(index)">删除</button></span></span></li></ul></div></div><div id="footer" v-show="NotesList.length > 0"><!-- 显示笔记数量 --><span id="count">共有{{count}}条笔记</span><!-- 点击按钮触发批量删除和清空操作 --><button id="delMany" v-on:click="delMany" class="delS">批量删除</button><button id="clear" v-on:click="clear">清空记事本</button></div></div></div><!-- 引入优化后的 JS 文件 --><script src="../js/index.js"></script>
</body></html>
/* 全局设置,将 box-sizing 设置为 border-box,避免尺寸计算问题 */
* {box-sizing: border-box;
}body {background-image: url(../src/img/image.png);background-size: cover;background-repeat: no-repeat;
}#box {position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);
}#header {background-color: rgb(177, 223, 79, .8);width: 830px;height: 80px;border: 1px solid black;font-size: 25px;text-align: center;line-height: 80px;
}#main {width: 830px;height: 360px;border-left: 1px solid black;border-right: 1px solid black;background-color: rgb(255, 255, 255, .8);overflow: hidden;
}#mainTop {height: 60px;border: 1px solid black;display: flex;align-items: center;
}#text,
#search {width: 60%;height: 60px;box-sizing: border-box;font-size: 20px;float: left;
}#add,
#check {width: 15%;height: 60px;font-size: 17px;box-sizing: border-box;float: left;
}#mainBottom {height: 300px;overflow: auto;border: 1px solid black;position: relative;
}#newMessage,
#content {display: inline-block;height: 40px;line-height: 40px;width: 620px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;font-size: 20px;position: relative;vertical-align: middle;
}#footer {width: 830px;height: 70px;border: 1px solid black;background-color: rgba(177, 223, 79, .8);text-align: center;line-height: 70px;display: flex;align-items: center;position: relative;
}#text::placeholder {font-size: 22px;color: rgba(177, 220, 100, 1);padding-left: 30px;
}#search::placeholder {padding-left: 30px;
}#count {position: absolute;left: 10px;
}ul {padding: 0;margin: 0;
}li {height: 40px;box-sizing: border-box;display: flex;align-items: center;line-height: 40px;
}li:nth-child(2n + 1) {background-color: rgba(128, 128, 150, .3);
}#delMany {background-color: white;height: 40px;position: absolute;width: 90px;right: 120px;
}#clear {background-color: white;height: 40px;position: absolute;width: 90px;right: 10px;
}#right {right: 15px;position: absolute;font-size: 18px;
}#confirm,
#edit {margin-right: 8px;width: 45px;height: 30px;
}#del {width: 45px;height: 30px;
}#order {padding-left: 20px;
}
var app = new Vue({el: "#contain",data: {NotesList: [],count: 0,message: "",delMuch: false,tempEditValue: '',selectedCategory: '',searchKeyword: '',priorities: ['高', '中', '低'],selectedPriority: '',searchResult: [],searchResultCount: 0},computed: {filteredNotesList() {let filtered = this.NotesList;if (this.selectedCategory) {filtered = filtered.filter(item => item.category === this.selectedCategory);}if (this.searchKeyword) {const keyword = this.searchKeyword.toLowerCase();filtered = filtered.filter(item => item.text.toLowerCase().includes(keyword));}if (this.selectedPriority) {filtered = filtered.filter(item => item.priority === this.selectedPriority);}return filtered;},highlightedSearchResult() {return this.searchResult.map(item => {const keyword = this.searchKeyword;if (keyword) {const regex = new RegExp(keyword, 'gi');item.highlightedText = item.text.replace(regex, '<mark>$&</mark>');} else {item.highlightedText = item.text;}return item;});}},watch: {searchKeyword: function (newKeyword) {this.select();}},methods: {clear: function () {const confirmation = confirm('你确定要清空记事本吗');if (confirmation) {this.NotesList = [];this.count = 0;this.saveNotesToLocalStorage();alert('操作已执行!');} else {alert('操作已取消。');}},add: function () {const input = this.message.trim();if (input) {this.NotesList.unshift({text: input,isEditing: false,checked: false,category: '工作',priority: '中'});this.count++;this.message = "";if (this.searchKeyword) {this.select();}this.saveNotesToLocalStorage();} else {alert("请输入有效内容");}},edit: function (index) {if (this.filteredNotesList[index]) {const realIndex = this.NotesList.indexOf(this.filteredNotesList[index]);this.NotesList[realIndex].isEditing = true;this.tempEditValue = this.NotesList[realIndex].text;}},confirmEdit: function (index) {const newText = this.tempEditValue.trim();if (newText && this.filteredNotesList[index]) {const realIndex = this.NotesList.indexOf(this.filteredNotesList[index]);this.NotesList[realIndex].text = newText;}if (this.filteredNotesList[index]) {const realIndex = this.NotesList.indexOf(this.filteredNotesList[index]);this.NotesList[realIndex].isEditing = false;}if (this.searchKeyword) {this.select();}this.saveNotesToLocalStorage();},cancelEdit: function (index) {if (this.filteredNotesList[index]) {const realIndex = this.NotesList.indexOf(this.filteredNotesList[index]);this.NotesList[realIndex].isEditing = false;this.tempEditValue = this.NotesList[realIndex].text;}},del: function (index) {if (this.filteredNotesList.length > 0 && index >= 0 && index < this.filteredNotesList.length) {const realIndex = this.NotesList.indexOf(this.filteredNotesList[index]);this.NotesList.splice(realIndex, 1);this.count--;if (this.searchKeyword) {this.select();}this.saveNotesToLocalStorage();}},delMany: function () {this.delMuch = true;const originalLength = this.NotesList.length;this.NotesList = this.NotesList.filter(item => !item.checked);const deletedCount = originalLength - this.NotesList.length;if (deletedCount > 0) {this.count = this.NotesList.length;this.delMuch = false;const isConfirmed = confirm('你确定要删除选中的笔记吗?');if (isConfirmed) {alert(`已成功删除 ${deletedCount} 条笔记`);}}if (this.searchKeyword) {this.select();}this.saveNotesToLocalStorage();},select: function () {const keyword = this.searchKeyword.trim().toLowerCase();if (keyword) {this.searchResult = this.NotesList.filter(item => item.text.toLowerCase().includes(keyword));this.searchResultCount = this.searchResult.length;if (this.searchResultCount === 0) {alert('没有查询到相关笔记');} else {alert(`查询到 ${this.searchResultCount} 条相关笔记`);}} else {this.searchResult = [];this.searchResultCount = 0;}},addOrSearch: function (event) {if (event.key === 'Enter') {if (event.ctrlKey) {this.select();} else {this.add();}}},saveNotesToLocalStorage() {localStorage.setItem('notes', JSON.stringify(this.NotesList));},loadNotesFromLocalStorage() {const notes = localStorage.getItem('notes');if (notes) {this.NotesList = JSON.parse(notes);this.count = this.NotesList.length;}}},mounted() {this.loadNotesFromLocalStorage();}
});

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/79603.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[ACTF2020 新生赛]Include [ACTF2020 新生赛]Exec

[ACTF2020 新生赛]Include 因为前端过滤的太多了 所以直接使用 日志包含 搞 包含这个 /var/log/nginx/access.log [ACTF2020 新生赛]Include蚁剑连接 翻看 flag{1ce7a81e-0339-44ef-a398-a7784d3efe37} [ACTF2020 新生赛]Exec [ACTF2020 新生赛]Exec 127.0.0.1 |echo <?…

VFS Global 携手 SAP 推动数字化转型

2025年5月2日&#xff0c;SAP 公司宣布&#xff0c;全球领先的签证、领事和技术服务提供商 VFS Global 将采用 SAP 的多项核心软件解决方案&#xff0c;推动其全球政务服务和跨境流动解决方案迈向全面数字化和智能化。此次合作标志着 VFS Global 在 AI 赋能的政府科技&#xff…

GTC2025全球流量大会:领驭科技以AI云端之力,助力中国企业出海破浪前行

在全球化与数字化浪潮下&#xff0c;AI技术正成为中国企业出海的重要驱动力。一方面&#xff0c;AI通过语言处理、数据分析等能力显著提升出海企业的运营效率与市场适应性&#xff0c;尤其在东南亚等新兴市场展现出"高性价比场景适配"的竞争优势&#xff1b;另一方面…

安全漏洞扫描费用受哪些因素影响?市场价格区间是多少?

安全漏洞扫描费用是个复杂且关键的话题。它涉及多种影响因素。合理的费用可让企业有效防范安全风险。下面我们深入探讨一番。 市场价格区间 安全漏洞扫描的费用在市场上差别很大。小型企业进行简单扫描&#xff0c;可能只要几千元。大型企业做全面的深度扫描&#xff0c;费用…

n8n工作流自动化平台的实操:解决中文乱码

解决问题&#xff1a; 通过ftp读取中文内容的文件&#xff0c;会存在乱码&#xff0c;如下图&#xff1a; 解决方案 1.详见《安装 iconv-lite》 2.在code节点&#xff0c;写如下代码&#xff1a; const iconv require(iconv-lite);const items $input.all(); items.forEa…

豪越科技消防立库方案:实现应急物资高效管理

在消防救援工作中&#xff0c;应急物资管理是至关重要的一环。然而&#xff0c;当前应急物资管理的现状却令人担忧。传统的应急物资管理方式存在诸多弊端&#xff0c;严重影响了消防救援的效率和效果。 走进一些传统的消防仓库&#xff0c;映入眼帘的往往是杂乱无章的存储场景。…

zabbix 重置登录密码

概述 本节介绍在 Zabbix 中重置用户密码的步骤。 步骤 如果您忘记了 Zabbix 密码并且无法登录&#xff0c;请联系您的 Zabbix 管理员。 超级管理员用户可以更改用户 配置表单 中所有用户的密码。 如果超级管理员忘记了密码并且无法登录&#xff0c;则必须运行以下 SQL 查询…

生成树、Prime、Kruskal

1、任何一个带权无向连通图的最小生成树——可能是不唯一的。 2、给定有权无向图的邻接矩阵如下&#xff0c;其最小生成树的总权重是&#xff1a;14 3、给定有权无向图如下。关于其最小生成树&#xff0c;最小生成树不唯一&#xff0c;其总权重为23。 4、给出如下图所示的具有…

用Suno V4.5试了一下1850字的歌词进行创作出来了6分钟的歌曲

我的宝贝V1,未来AI视界,5分钟 之前的Suno 3和Suno 4的版本&#xff0c;创作的音乐最长是4分钟&#xff0c;这里最大的问题就是&#xff0c;唱到4分钟歌曲就突然断了&#xff0c;那么只能使用续写的方式进行创作。对于续写的问题&#xff0c;其一增加用户的使用和理解成本&…

机器人编程基础---C语言中的表达式和求值

C语言中的表达式和求值 C语言中的表达式和求值表达式示例代码示例说明C语言中的表达式和求值 表达式是运算符和操作数(变量、常量、表达式等)的组合,它们可以产生一个值。 表达式示例 int x = 10, y = 20; int z = x + y * 2; // 根据运算符优先级,先计算y*2,然后计算x…

[UVM]在SoC中用寄存器模型backdoor访问寄存器的案例

在SoC中用寄存器模型backdoor访问寄存器的案例 摘要:在 UVM (Universal Verification Methodology) 验证环境中,寄存器模型是验证 DUT (Design Under Test) 寄存器行为的重要工具。特别是对于层次化的验证环境(如 IP 到 Sub-system 再到 SoC 的集成),使用 UVM 寄存…

NV203NV207SSD固态闪存NV208NV213

NV203NV207SSD固态闪存NV208NV213 美光SSD全解析&#xff1a;NV203/NV207/NV208/NV213技术矩阵 一、产品定位与技术脉络 在存储技术迭代浪潮中&#xff0c;美光NV系列产品构建起多层次的技术矩阵。NV203作为入门级SATA SSD&#xff0c;主打成本控制与基础性能平衡&#xff0c…

迭代器的思想和实现细节

1. 迭代器的本质 迭代器是一种行为类似指针的对象&#xff0c;它可能是指针&#xff08;如 std::vector 的迭代器&#xff09;&#xff0c;也可能是封装了指针的类&#xff08;如 std::list 的迭代器&#xff09;。如果是指针那天然就可以用下面的运算&#xff0c;如果是类&am…

工业传动核心部件深度剖析:丝杆升降机与气缸的技术特性及选型指南

在工业自动化技术飞速发展的当下&#xff0c;丝杆升降机与气缸作为关键的直线传动部件&#xff0c;广泛应用于各类机械设备中。对于工程师而言&#xff0c;深入了解它们的技术特性、优缺点及适用场景&#xff0c;是实现高效、精准设备设计的重要前提。本文将从技术原理出发&…

HarmonyOS NEXT——DevEco Studio的使用(还没写完)

一、IDE环境的搭建 Windows环境 运行环境要求 为保证DevEco Studio正常运行&#xff0c;建议电脑配置满足如下要求&#xff1a; 操作系统&#xff1a;Windows10 64位、Windows11 64位 内存&#xff1a;16GB及以上 硬盘&#xff1a;100GB及以上 分辨率&#xff1a;1280*8…

Modbus 通讯协议(超详细,简单易懂)

目录 一、协议中的寄存器定义 二、协议概述 三、使用串口的Modbus 报文帧 ​编辑 3.1、Modbus ASCII 模式 3.2、Modbus RTU 模式 3.3、功能码概要 3.4、Modbus 报文分析 四、什么是RS-485 RS-232&#xff1f; 一、协议中的寄存器定义 阅读 Modbus 协议时会发现它的概念别扭…

计算机总线系统入门:理解数据传输的核心

一、总线系统简介&#xff1a;计算机内部的交通网络 在计算机系统中&#xff0c;总线是指连接各个组件的一组共享信号线或传输通道&#xff0c;用于在系统内不同的硬件模块之间传递数据、地址、控制信号等信息。它类似于交通系统中的道路&#xff0c;帮助计算机各个部件&#…

《应用开发突围指南:敏捷开发的实战精髓》

如何在应用开发中精准且深入地应用敏捷开发方法呢&#xff1f;让我们一同深入探索。 敏捷开发&#xff0c;绝非仅仅是一种开发流程&#xff0c;更是一种蕴含深刻智慧的理念与思维方式。它与传统开发模式有着本质的区别&#xff0c;传统开发模式如同严谨的线性旅程&#xff0c;…

《高性能MySQL》第1讲:MySQL架构

MySQL是一个非常流行的关系型数据库管理系统,它的设计非常灵活,能够适应多种不同的应用场景。无论是Web应用、数据仓库,还是高可用性系统,MySQL都能胜任。为了更好地理解MySQL的工作原理,我们需要从它的架构入手。 1.1 MySQL逻辑架构 首先,我们来看一下MySQL的逻辑架构…

数据赋能(212)——质量管理——统一性原则

概述 数据统一性原则在数据管理的各个环节中都具有不可忽视的重要性。它确保了数据在不同部门、系统和时间点上的一致性和可比性&#xff0c;为企业的决策制定、业务分析、风险管理等提供了准确、可靠的数据支持。 原则定义 数据统一性原则&#xff1a;在数据的收集、处理、…