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"命令可能会因为文件数目过多而报错。为了…...

(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...

STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...

C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...

自然语言处理——Transformer
自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...