vue学习-07todoList案例与浏览器本地存储
TodoList
Todo List(任务列表)是一个简单的Web应用程序示例,用于管理任务、代办事项或清单。Vue.js 是一个非常适合构建这种类型应用程序的框架,因为它提供了数据绑定、组件化、响应式和轻松管理用户界面的能力。
以下是一个基本的Vue.js Todo List的示例:
- 任务列表显示:在Vue.js中,你可以使用数据绑定来动态渲染任务列表。任务列表通常以一个数组的形式存在,Vue.js会帮助你将这个数组与界面上的任务列表元素绑定起来。
- 添加任务:用户可以通过输入框输入新任务,并点击“添加”按钮或按下回车键来将任务添加到列表中。Vue.js的事件绑定功能可以帮助你监听用户的操作。
- 标记任务完成:通常,每个任务都有一个复选框或其他方式来标记是否完成。Vue.js可以帮助你实现这一功能,并在任务状态发生变化时更新界面。
- 删除任务:用户可以通过点击删除按钮来删除任务。Vue.js的事件处理程序可以监听点击事件,并在任务被删除时更新任务列表。
- 过滤任务:有时用户希望能够按状态(已完成、未完成)或其他条件过滤任务列表。Vue.js可以帮助你实现这一功能,通过过滤和排序任务数组来呈现不同的视图。
- 本地存储:为了确保用户的任务在页面刷新后不会丢失,你可以使用浏览器本地存储技术(如localStorage)来将任务数据存储在用户的浏览器中。
App.vue
<template><div id="root"><div class="todo-container"><div class="todo-wrap"><!-- 编写组件标签,头部组件 --><MyHeader :addTodo="addTodo"></MyHeader><!-- 内容列表组件 --><MyList :todos="todos" :checkTodo="checkTodo":todoDelete="todoDelete"></MyList><!-- 下脚组件 --><MyFooter :todos="todos":checkAllTodo="checkAllTodo":clearAllTodo="clearAllTodo"></MyFooter></div></div></div>
</template><script>//引入组件import MyHeader from './components/MyHeader.vue';import MyFooter from './components/MyFooter.vue';import MyList from './components/MyList.vue';export default {name:'App',components:{MyHeader,MyFooter,MyList},data() {return {todos:[{id:"001",title:'吃饭',done:true},{id:"002",title:'睡觉',done:false},{id:"003",title:'学习',done:true},{id:"004",title:'抽烟',done:false},{id:"005",title:'喝酒',done:false},{id:"006",title:'开车',done:true}]}},methods:{// 添加一个todoaddTodo(todoObj){console.log("我是组件App,我收到数据:",todoObj);//this.todos.push(x);//将数据加入数组中this.todos.unshift(todoObj);//将数据加入数组中},//勾选or取消一个todocheckTodo(id){// for (let index = 0; index < this.todos.length; index++) {// if(this.todos[index].id===id){// this.todos[index].done=!this.todos[index].done;// }// }//使用forEach,注意:当foreach无法使用的使用可能是脚手架没有安装对应的js版本,需要运行:npm install core-js@3.6.4名this.todos.forEach((todo)=>{if (todo.id===id) {todo.done=!todo.done;}});},//删除一个todotodoDelete(id){//使用过滤器删除,需要运行npm install core-js@3.6.4命令才能使用filter过滤器this.todos=this.todos.filter((todo)=>{return todo.id!==id;});//传统的过滤删除方法// for (let index = 0; index < this.todos.length; index++) {// if(this.todos[index].id===id){// this.todos.pop(index);// }// }},//全选or取消全选checkAllTodo(done){this.todos.forEach((todo)=>{todo.done=done;});},//清除所有已经完成的todoclearAllTodo(){this.todos=this.todos.filter((todo)=>{return !todo.done;});}}}
</script><style>/*base*/body {background: #fff;}.btn {display: inline-block;padding: 4px 12px;margin-bottom: 0;font-size: 14px;line-height: 20px;text-align: center;vertical-align: middle;cursor: pointer;box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);border-radius: 4px;}.btn-danger {color: #fff;background-color: #da4f49;border: 1px solid #bd362f;}.btn-danger:hover {color: #fff;background-color: #bd362f;}.btn:focus {outline: none;}.todo-container {width: 600px;margin: 0 auto;}.todo-container .todo-wrap {padding: 10px;border: 1px solid #ddd;border-radius: 5px;}
</style>
MyHeader.vue
<template><div class="todo-header"><input type="text" placeholder="请输入你的任务名称,按回车键确认" v-model="title" @keyup.enter="add"/></div>
</template><script>import {nanoid} from 'nanoid'export default {name:'MyHeader',props:['addTodo'],data() {return {title:''}},methods:{add(){//校验数据if(!this.title){alert("数据不能为空!");return;}//将用户的输入包装成一个todo对象const todoObj={id:nanoid(),title:this.title,done:false};//通知App组件去添加一个todo对象this.addTodo(todoObj);this.title='';//清空输入}}}
</script><style scoped>/*header*/.todo-header input {width: 560px;height: 28px;font-size: 14px;border: 1px solid #ccc;border-radius: 4px;padding: 4px 7px;}.todo-header input:focus {outline: none;border-color: rgba(82, 168, 236, 0.8);box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);}
</style>
MyItem.vue
<template><div><li><label><input type="checkbox" :checked="todo.done" @change="handleCheck(todo.id)"/><!-- 如下代码也能实现功能,但不太推荐,因为有点违反原则,因为修改了props --><!-- <input type="checkbox" v-model="todo.done"/> --><span>{{todo.title}}</span></label><button class="btn btn-danger" @click="handleDelete(todo.id)">删除</button></li></div>
</template><script>export default {name:'MyItem',//声明接收todo对象props:['todo','checkTodo','todoDelete'],methods:{// 勾选or取消勾选handleCheck(id){this.checkTodo(id);},//删除一个todohandleDelete(id){if(confirm("确定删除吗?")){this.todoDelete(id);}}}}
</script><style scoped>/*item*/li {list-style: none;height: 36px;line-height: 36px;padding: 0 5px;border-bottom: 1px solid #ddd;}li label {float: left;cursor: pointer;}li label li input {vertical-align: middle;margin-right: 6px;position: relative;top: -1px;}li button {float: right;display: none;margin-top: 3px;}li:before {content: initial;}li:last-child {border-bottom: none;}li:hover{background-color: #ddd;}li:hover button{display: block;}
</style>
MyList.vue
<template><div><ul class="todo-main"><!-- 记录详情组件 --><MyItem v-for="todoObj in todos" :key="todoObj.id" :todo="todoObj":checkTodo="checkTodo":todoDelete="todoDelete"></MyItem></ul></div>
</template><script>import MyItem from './MyItem.vue'export default {name:'MyList',components:{MyItem},props:['todos','checkTodo','todoDelete']}
</script><style scoped>/*main*/.todo-main {margin-left: 0px;border: 1px solid #ddd;border-radius: 2px;padding: 0px;}.todo-empty {height: 40px;line-height: 40px;border: 1px solid #ddd;border-radius: 2px;padding-left: 5px;margin-top: 10px;}
</style>
MyFooter.vue
<template><div class="todo-footer" v-if="total"><label><input type="checkbox" v-bind:checked="isAll" @click="checkAll"/></label><span><span>已完成{{doneTotal}}</span> / 全部{{total}}</span><button class="btn btn-danger" @click="clearAll">清除已完成任务</button></div>
</template><script>export default {name:'MyFooter',props:['todos','checkAllTodo','clearAllTodo'],// 计算属性computed:{//完整书写方式total:function(){return this.todos.length;},//计算属性的简写方式doneTotal() {//原始的统计方法// let count=0;// for (let index = 0; index < this.todos.length; index++) {// if (this.todos[index].done) {// count++;// }// }// return count;//使用原型的reduce条件统计方法,第一个参数为函数体,第二个为统计开始值const count=this.todos.reduce((pre,todo)=>{return pre+(todo.done? 1 : 0);},0);return count;},isAll(){return this.doneTotal===this.total&&this.total>0;//计算属性是可以嵌套的}},methods:{checkAll(event){console.log(event.target.checked);this.checkAllTodo(event.target.checked);},clearAll(){this.clearAllTodo();}}}
</script><style scoped>/*footer*/.todo-footer {height: 40px;line-height: 40px;padding-left: 6px;margin-top: 5px;}.todo-footer label {display: inline-block;margin-right: 20px;cursor: pointer;}.todo-footer label input {position: relative;top: -1px;vertical-align: middle;margin-right: 5px;}.todo-footer button {float: right;margin-top: 5px;}
</style>
浏览器本地存储
浏览器本地存储是一种在用户的本地浏览器中存储数据的机制,以便在后续访问同一网站或应用程序时能够更快地加载和显示内容,同时也可以用于在会话之间保持数据。常见的浏览器本地存储技术包括:
-
Cookies(Cookie):Cookies 是一种小型文本文件,可以存储在用户的计算机上。它们通常用于存储少量的数据,如用户登录信息、会话标识等。Cookies 可以在服务器和浏览器之间传递数据,但存储容量有限(通常不超过4KB)。
-
Web Storage:Web Storage 提供了两种存储数据的方式:
localStorage
和sessionStorage
。localStorage
:用于长期存储数据,数据在浏览器关闭后仍然保留。sessionStorage
:用于临时会话数据存储,数据在会话结束后被清除。
-
IndexedDB:IndexedDB 是一种低级别的数据库系统,允许你在浏览器中存储大量结构化数据。它提供了强大的查询和事务支持,并适用于需要离线访问或较大数据集的应用程序。
-
Cache API:Cache API 是一个用于存储和检索网络请求和响应的浏览器缓存系统。它允许开发者明确地控制哪些资源被缓存以及缓存的生命周期,通常用于提高网页性能和离线访问。
-
Service Worker:Service Worker 是一个在浏览器后台运行的脚本,它可以拦截和处理网络请求,实现高级的缓存策略,包括离线访问和推送通知。它通常与Cache API一起使用。
这些本地存储技术允许开发者在浏览器中存储和管理数据,以提高应用程序的性能、响应速度和离线访问能力。选择适当的本地存储技术通常取决于应用程序的需求和数据的类型。
需要注意的是,由于本地存储是存储在用户计算机上的数据,开发者需要处理数据的过期、清理以及安全性等问题,以确保用户数据的完整性和隐私安全。
localStorage
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>localStorage</title></head><body><h2>localStorage</h2><button onclick="saveData()">点我保存数据</button><button onclick="readData()">点我读取数据</button><button onclick="deleteData()">点我删除数据</button><button onclick="deleteAllData()">点我清空数据</button><script type="text/javascript">let p = {name:'张三',age:18};console.log(p.toString());function saveData(){window.localStorage.setItem('msg','你好啊本地存储');//将数据存进浏览器的本地缓存中window.localStorage.setItem('msg2',666);window.localStorage.setItem('person',JSON.stringify(p));//将对象类型转成json字符串类型}function readData(){console.log(localStorage.getItem('msg'));console.log(localStorage.getItem('msg2'));let result=localStorage.getItem('person');console.log(JSON.parse(result));//将json字符串类型解析成object类型}function deleteData(){localStorage.removeItem('msg');//移除数据}function deleteAllData(){localStorage.clear();//清空数据}</script></body>
</html>
sessionStorage
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>sessionStorage</title></head><body><h2>sessionStorage</h2><button onclick="saveData()">点我保存数据</button><button onclick="readData()">点我读取数据</button><button onclick="deleteData()">点我删除数据</button><button onclick="deleteAllData()">点我清空数据</button><script type="text/javascript">let p = {name:'张三',age:18};console.log(p.toString());function saveData(){window.sessionStorage.setItem('msg','你好啊本地存储');//将数据存进浏览器的本地缓存中window.sessionStorage.setItem('msg2',666);window.sessionStorage.setItem('person',JSON.stringify(p));//将对象类型转成json字符串类型}function readData(){console.log(sessionStorage.getItem('msg'));console.log(sessionStorage.getItem('msg2'));let result=sessionStorage.getItem('person');console.log(JSON.parse(result));//将json字符串类型解析成object类型}function deleteData(){sessionStorage.removeItem('msg');//移除数据}function deleteAllData(){sessionStorage.clear();//清空数据}</script></body>
</html>
相关文章:
vue学习-07todoList案例与浏览器本地存储
TodoList Todo List(任务列表)是一个简单的Web应用程序示例,用于管理任务、代办事项或清单。Vue.js 是一个非常适合构建这种类型应用程序的框架,因为它提供了数据绑定、组件化、响应式和轻松管理用户界面的能力。 以下是一个基本…...

探索智能应用的基石:多模态大模型赋能文档图像处理
目录 0 写在前面1 文档图像分析新重点2 token荒:电子文档助力大模型3 大模型赋能智能文档分析4 文档图像大模型应用可能性4.1 专有大模型4.2 多模态模型4.3 设计思路 总结 0 写在前面 中国智能产业高峰论坛(CIIS2023)旨在为政企研学各界学者专家提供同台交流的机会…...

自动化发布npm包小记
1.注册npm账号 打开npm官网,并注册自己的npm账号 2.申请AccessToken 1.登录npm官网,登录成功后,点开右上角头像,并点击Access Tokens选项 2.点开Generate New Token下拉框,点击Classic Token(和Granular Access To…...
详解机器视觉性能指标相关概念——混淆矩阵、IoU、ROC曲线、mAP等
目录 0. 前言 1. 图像分类性能指标 1.1 混淆矩阵(Confusion Matrix) 1.2 准确率(Precision) 1.3 召回率(Recall) 1.4 F1值(F1 score) 1.5 ROC曲线(接收者工作特征曲线,Receiver Operating Characteristic curve) 1.6 mAP(mean Average Precision) 2. 图像分…...

想要精通算法和SQL的成长之路 - 预测赢家
想要精通算法和SQL的成长之路 - 预测赢家 前言一. 预测赢家二. 石子游戏(预测赢家的进阶版)2.1 博弈论 前言 想要精通算法和SQL的成长之路 - 系列导航 一. 预测赢家 原题链接 主要思路: 我们定义dp[i][j]:在区间 [i, j] 之间先…...

高精度PWM脉宽调制信号转模拟信号隔离变送器1Hz~10KHz转0-5V/0-10V/1-5V/0-10mA/0-20mA/4-20mA
主要特性: >>精度等级:0.1级。产品出厂前已检验校正,用户可以直接使用 >>辅助电源:8-32V 宽范围供电 >>PWM脉宽调制信号输入: 1Hz~10KHz >>输出标准信号:0-5V/0-10V/1-5V,0-10mA/0-20mA/4-20mA等&…...

Vue路由和Node.js环境搭建
文章目录 一、vue路由1.1 简介1.2 SPA1.3 实例 二、Node.js环境搭建2.1 Node.js简介2.2 npm2.3 环境搭建2.3.1 下载解压2.3.2 配置环境变量2.3.3 配置npm全局模块路径和cache默认安装位置2.3.4 修改npm镜像提高下载速度 2.4 运行项目 一、vue路由 1.1 简介 Vue 路由是 Vue.js…...

【Vue】使用vue-cli搭建SPA项目的路由,嵌套路由
一、SPA项目的构建 1、前期准备 我们的前期的准备是搭建好Node.js,测试: node -v npm -v2、利用Vue-cli来构建spa项目 2.1、什么是Vue-cli Vue CLI 是一个基于 Vue.js 的官方脚手架工具,用于自动生成vue.jswebpack的项目模板,它可以帮助开发者…...

Excel 通过条件格式自动添加边框
每录入一次数据就需要手动添加一次边框,非常麻烦,这不是我们想要的。 那么有没有办法,在我们录入数据后,自动帮我们加上边框呢? 选中要自动添加边框的列,然后按箭头流程操作 ↓ ↓ ↓ ↓...

mysql 备份和还原 mysqldump
因window系统为例 在mysql安装目录中的bin目录下 cmd 备份 备份一个数据库 mysqldump -uroot -h hostname -p 数据库名 > 备份的文件名.sql 备份部分表 mysqldump -uroot -h hostname -p 数据库名 [表 [表2…]] > 备份的文件名.sql ## 多个表 空格隔开,中间…...

ELK日志分析系统+ELFK(Filebeat)
本章结构: 1、ELK日志分析系统简介 2、Elasticsearch介绍(简称ES) 3、Logstash介绍 4、Kibana介绍 5、实验,ELK部署 一、ELK日志分析系统简介 ELK平台是一套完整的日志集中处理解决方案,将 ElasticSearch、Logst…...

ULID 在 Java 中的应用: 使用 `getMonotonicUlid` 生成唯一标识符
🌷🍁 博主猫头虎 带您 Go to New World.✨🍁 🦄 博客首页——猫头虎的博客🎐 🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 &a…...

实用的嵌入式编码技巧:第三部分
每个触发器都有两个我们在风险方面违反的关键规格。“建立时间”是时钟到来之前输入数据必须稳定的最小纳秒数。“保持时间”告诉我们在时钟转换后保持数据存在多长时间。 这些规格因逻辑设备而异。有些可能需要数十纳秒的设置和/或保持时间;其他人则需要少一个数量…...
8个很棒的Vue开发技巧
1.路由参数解耦 通常在组件中使用路由参数,大多数人会做以下事情。 export default { methods: {getParamsId() {return this.$route.params.id} } } 在组件中使用 $route 会导致与其相应路由的高度耦合,通过将其限制为某些 URL 来限制组件的灵活性。…...
Python - 小玩意 - 文字转语音
import pyttsx3 from tkinter import *def recognize_and_save():try:say pyttsx3.init()rate say.getProperty(rate) # 获取当前语速属性的值say.setProperty(rate, rate - 20) # 设置语速属性为当前语速减20text text_var.get()# 语音识别say.say(text)say.runAndWait()…...

聚焦数据库和新兴硬件的技术合力 中科驭数受邀分享基于DPU的数据库异构加速方案
随着新型硬件成本逐渐降低,充分利用新兴硬件资源提升数据库性能是未来数据库发展的重要方向之一,SIGMOD、VLDB、CICE数据库顶会上出现越来越多新兴硬件的论文和专题。在需求侧,随着数据量暴增和实时性的要求越来越高,数据库围绕处…...

哨兵模式(sentinel)
为什么需要哨兵模式 redis的主从复制模式能够缓解“读压力”,但是存在两个明显问题。 主节点发生故障,进行主节点切换的过程比较复杂,需要人工参与,导致故障恢复时间无法保障主节点通过主从复制模式将读压力分散出去,…...

b站老王 自动驾驶决策规划学习记录(十二)
自动驾驶之速度规划详解:SL与ST迭代 上一讲:b站老王 自动驾驶决策规划学习记录(十一) 接着上一讲学习记录b站老王对自动驾驶规划系列的讲解 参考视频: 自动驾驶决策规划算法第二章第七节(上) 速度规划详解:SL与ST迭代…...
服务器租用机房机房的类型应该如何选择
服务器租用机房机房的类型应该如何选择 1.单电信机房 单电信服务器机房业务模式比较固定,访问量也不是很大,适合新闻类网站或政务类网站。如果网站的PV流量持续增加,建议后期采用租赁CDN的方式解决非电信用户访问网站速度过慢的问题。 2.双线…...
大数据运维一些常见批量操作命令
大数据运维中,批量操作是一项常见的任务。在使用flume进行数据采集的过程中,有时会出现故障导致采集停止,此时积累了大量的文件。如果想要将这些文件迁移到新的目录,直接使用"mv"命令可能会因为文件数目过多而报错。为了…...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...

【Post-process】【VBA】ETABS VBA FrameObj.GetNameList and write to EXCEL
ETABS API实战:导出框架元素数据到Excel 在结构工程师的日常工作中,经常需要从ETABS模型中提取框架元素信息进行后续分析。手动复制粘贴不仅耗时,还容易出错。今天我们来用简单的VBA代码实现自动化导出。 🎯 我们要实现什么? 一键点击,就能将ETABS中所有框架元素的基…...
java+webstock
maven依赖 <dependency><groupId>org.java-websocket</groupId><artifactId>Java-WebSocket</artifactId><version>1.3.5</version></dependency><dependency><groupId>org.apache.tomcat.websocket</groupId&…...

华为OD机考- 简单的自动曝光/平均像素
import java.util.Arrays; import java.util.Scanner;public class DemoTest4 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint[] arr Array…...

今日行情明日机会——20250609
上证指数放量上涨,接近3400点,个股涨多跌少。 深证放量上涨,但有个小上影线,相对上证走势更弱。 2025年6月9日涨停股主要行业方向分析(基于最新图片数据) 1. 医药(11家涨停) 代表标…...