vue3 todolist 简单例子

news2025/1/19 16:59:11

vue3 简单的TodList
地址: https://gitee.com/cheng_yong_xu/vue3-composition-api-todo-app-my

效果
在这里插入图片描述

step-1

初始化项项目
在这里插入图片描述
我们不采用vue cli 搭建项目

直接将上图文件夹,复制到vscode编辑器,清空App.vue的内容

安装包

# 安装包
npm i
# 启动
npm run serve

在这里插入图片描述

step-2

先写样式结构
在这里插入图片描述

<!-- src\App.vue -->
<template>
	<h1>ToDo App</h1>
	<form>
		<label for="">添加待办项</label>
		<input type="text" name="newTodo" autocomplete="off" />
		<button>添 加</button>
	</form>

	<h2>待办列表</h2>
	<ul>
		<li>
			<span>代办列表</span>
			<button>删 除</button>
		</li>
	</ul>
</template>

<script>
export default {}
</script>

<style lang="scss">
$size1: 6px;
$size2: 12px;
$size3: 18px;
$size4: 24px;
$size5: 48px;
$backgroundColor: #27292d;
$primaryColor: #EC23F3;
$secondTextColor: #1f2023;

$border: 2px solid rgba($color: white,
		$alpha: 0.35,
	);

$textColor: white;
$border_r: 2px solid red;
$border_y: 2px solid rgb(241, 229, 50);
$border_g: 2px solid rgb(50, 241, 50);
$border_w: 2px solid white;

body {
	margin: 0;
	padding: 0;
	font-family: Avenir, Helvetica, Arial, sans-serif;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	background-color: $backgroundColor;
	color: $textColor;

	#app {
		max-width: 600px;
		margin-left: auto;
		margin-right: auto;
		padding: 20px;
		// border: $border_w;

		h1 {
			font-weight: bold;
			font-size: 28px;
			text-align: center;
			// border: $border_r;
		}

		form {
			display: flex;
			flex-direction: column;
			width: 100%;

			label {
				font-size: 14px;
				font-weight: bold;
			}

			input,
			button {
				height: $size5;
				box-shadow: none;
				outline: none;
				padding-left: $size2;
				padding-right: $size2;
				border-radius: $size1;
				font-size: 18px;
				margin-top: $size1;
				margin-bottom: $size2;
				transition: all 0.2s ease-in-out;
				/* 添加过渡效果,使变化平滑 */
			}

			input {
				background-color: transparent;
				border: $border;
				color: inherit;
			}

			input:hover {
				border: 2px solid rgb(236, 35, 243);
			}

			button {
				cursor: pointer;
				background-color: rgb(236, 35, 243);
				border: 1px solid $primaryColor;
				font-weight: bold;
				color: white;
				border-radius: $size1;
			}
		}

		h2 {
			// border: $border_g;
			font-size: 22px;
			border-bottom: $border;
			padding-bottom: $size1;

		}

		ul {
			padding: 10px;

			li {
				display: flex;
				justify-content: space-between;
				align-items: center;
				border: $border;
				padding: 10px;
				border-radius: $size1;
				margin-bottom: $size2;

				span {
					cursor: pointer;
				}

				button {
					cursor: pointer;
					font-size: $size2;
					background-color: rgb(236, 35, 243);
					border: 1px solid $primaryColor;
					font-weight: bold;
					color: white;
					padding: 5px 15px;
					border-radius: $size1;
				}
			}
		}
	}
}
</style>

step-3

双向绑定数据

<!-- src\App.vue -->
<template>
	<h1>ToDo App</h1>
	<form @submit.prevent="addTodo()">
		<label for="">添加待办项</label>
		<input type="text" name="newTodo" autocomplete="off" v-model="newTodo"/>
		<button>添 加</button>
	</form>

	<h2>待办列表</h2>
	<ul>
		<li>
			<span>代办列表</span>
			<button>删 除</button>
		</li>
	</ul>
</template>

<script>
import {ref } from 'vue';
export default {
	name: 'App',
	setup(){
		const newTodo = ref('');

		function addTodo(){
			if(newTodo.value){
				console.log(newTodo.value);
			}
		}

		return {
			newTodo,
			addTodo
		}
	}
}
</script>

在这里插入图片描述

step-4

定义数据并将数据变成响应式的
将数据持久化到本地

定义数据并将数据变成响应式的


<script>
import { ref } from 'vue';
export default {
	name: 'App',
	setup() {
		const newTodo = ref('');
		const defaultData = ref([
			{
				done: false,
				content: '今天要学习Vue'
			}
		]);

		const todos = ref(defaultData);

		function addTodo() {
			if (newTodo.value) {
				todos.value.push({
					done: false,
					content: newTodo.value
				})
			}
			console.log(todos.value)
		}

		return {
			newTodo,
			addTodo
		}
	}
}
</script>

在这里插入图片描述

将数据持久化到本地

<script>
import { ref } from 'vue';
export default {
	name: 'App',
	setup() {
		const newTodo = ref('');
		const defaultData = ref([
			{
				done: false,
				content: '今天要学习Vue'
			}
		]);

		const todos = ref(defaultData);

		function addTodo() {
			if (newTodo.value) {
				todos.value.push({
					done: false,
					content: newTodo.value
				})
			}
			saveData()
			console.log(sessionStorage.getItem('todos'))
		}

		function saveData () {
			const storageData = JSON.stringify(todos.value)
			sessionStorage.setItem('todos', storageData)
		}

		return {
			newTodo,
			addTodo
		}
	}
}
</script>

在这里插入图片描述

step-5

渲染待办列表

	<h2>待办列表</h2>
	<ul>
		<li v-for="(todo, index) in todos" :key="index">
			<span>{{ todo.content }}</span>
			<button>删 除</button>
		</li>
	</ul>

在这里插入图片描述
点击文字划横线
点击删除从待办列表移除

<!-- src\App.vue -->
<template>
	<h1>ToDo App</h1>
	<form @submit.prevent="addTodo()">
		<label for="">添加待办项</label>
		<input type="text" name="newTodo" autocomplete="off" v-model="newTodo" />
		<button>添 加</button>
	</form>

	<h2>待办列表</h2>
	<ul>
		<li v-for="(todo, index) in todos" :key="index">
			<span
			:class="{ done: todo.done }"
			@click="todo.done = !todo.done"
			>{{ todo.content }}</span>
			<button @click="removeTodo(index)">删 除</button>
		</li>
	</ul>
</template>

<script>
import { ref } from 'vue';
export default {
	name: 'App',
	setup() {
		const newTodo = ref('');
		const defaultData = ref([
			{
				done: false,
				content: '今天要学习Vue'
			}
		]);

		const todos = ref(defaultData);

		function addTodo() {
			if (newTodo.value) {
				todos.value.push({
					done: false,
					content: newTodo.value
				})
				newTodo.value = ''
			}
			saveData()
			console.log(sessionStorage.getItem('todos'))
		}

		function removeTodo(index) {
			todos.value.splice(index, 1)
			saveData()
		}
		function saveData() {
			const storageData = JSON.stringify(todos.value)
			sessionStorage.setItem('todos', storageData)
		}

		return {
			newTodo,
			todos,
			addTodo,
			removeTodo
		}
	}
}
</script>
<style lang="scss">
$size1: 6px;
$size2: 12px;
$size3: 18px;
$size4: 24px;
$size5: 48px;
$backgroundColor: #27292d;
$primaryColor: #EC23F3;
$secondTextColor: #1f2023;

$border: 2px solid rgba($color: white,
		$alpha: 0.35,
	);

$textColor: white;
$border_r: 2px solid red;
$border_y: 2px solid rgb(241, 229, 50);
$border_g: 2px solid rgb(50, 241, 50);
$border_w: 2px solid white;

body {
	margin: 0;
	padding: 0;
	font-family: Avenir, Helvetica, Arial, sans-serif;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	background-color: $backgroundColor;
	color: $textColor;

	#app {
		max-width: 600px;
		margin-left: auto;
		margin-right: auto;
		padding: 20px;
		// border: $border_w;

		h1 {
			font-weight: bold;
			font-size: 28px;
			text-align: center;
			// border: $border_r;
		}

		form {
			display: flex;
			flex-direction: column;
			width: 100%;

			label {
				font-size: 14px;
				font-weight: bold;
			}

			input,
			button {
				height: $size5;
				box-shadow: none;
				outline: none;
				padding-left: $size2;
				padding-right: $size2;
				border-radius: $size1;
				font-size: 18px;
				margin-top: $size1;
				margin-bottom: $size2;
				transition: all 0.2s ease-in-out;
				/* 添加过渡效果,使变化平滑 */
			}

			input {
				background-color: transparent;
				border: $border;
				color: inherit;
			}

			input:hover {
				border: 2px solid rgb(236, 35, 243);
			}

			button {
				cursor: pointer;
				background-color: rgb(236, 35, 243);
				border: 1px solid $primaryColor;
				font-weight: bold;
				color: white;
				border-radius: $size1;
			}
		}

		h2 {
			// border: $border_g;
			font-size: 22px;
			border-bottom: $border;
			padding-bottom: $size1;

		}

		ul {
			padding: 10px;

			li {
				display: flex;
				justify-content: space-between;
				align-items: center;
				border: $border;
				padding: 10px;
				border-radius: $size1;
				margin-bottom: $size2;

				span {
					cursor: pointer;
				}
				.done {
					text-decoration: line-through;
				}

				button {
					cursor: pointer;
					font-size: $size2;
					background-color: rgb(236, 35, 243);
					border: 1px solid $primaryColor;
					font-weight: bold;
					color: white;
					padding: 5px 15px;
					border-radius: $size1;
				}
			}
		}
		h4 {
			text-align: center;
			opacity: 0.5;
			margin: 0;
		}
	}
}
</style>

在这里插入图片描述

step-6

目前我们的数据虽然存在本地,但是我们使用的是内存中的数据,应该使用本地的数据
关闭浏览器再打开看到的还是和关闭之前一样的数据

<template>
	<h1>ToDo App</h1>
	<form @submit.prevent="addTodo()">
		<label>New ToDo </label>
		<input
			v-model="newTodo"
			name="newTodo"
			autocomplete="off"
		>
		<button>Add ToDo</button>
	</form>
	<h2>ToDo List</h2>
	<ul>
		<li
			v-for="(todo, index) in todos"
			:key="index"
		>
			<span
				:class="{ done: todo.done }"
				@click="doneTodo(todo)"
			>{{ todo.content }}</span>
			<button @click="removeTodo(index)">Remove</button>
		</li>
	</ul>
	<h4 v-if="todos.length === 0">Empty list.</h4>
</template>

<script>
	import { ref } from 'vue';
	export default {
		name: 'App',
		setup () {
			const newTodo = ref('');
			const defaultData = [{
				done: false,
				content: 'Write a blog post'
			}]
			const todosData = JSON.parse(localStorage.getItem('todos')) || defaultData;
			const todos = ref(todosData);
			function addTodo () {
				if (newTodo.value) {
					todos.value.push({
						done: false,
						content: newTodo.value
					});
					newTodo.value = '';
				}
				saveData();
			}

			function doneTodo (todo) {
				todo.done = !todo.done
				saveData();
			}

			function removeTodo (index) {
				todos.value.splice(index, 1);
				saveData();
			}

			function saveData () {
				const storageData = JSON.stringify(todos.value);
				localStorage.setItem('todos', storageData);
			}

			return {
				todos,
				newTodo,
				addTodo,
				doneTodo,
				removeTodo,
				saveData
			}
		}
	}
</script>

<style lang="scss">
$border: 2px solid
	rgba(
		$color: white,
		$alpha: 0.35,
	);
$size1: 6px;
$size2: 12px;
$size3: 18px;
$size4: 24px;
$size5: 48px;
$backgroundColor: #27292d;
$textColor: white;
$primaryColor: #a0a4d9;
$secondTextColor: #1f2023;
body {
	margin: 0;
	padding: 0;
	font-family: Avenir, Helvetica, Arial, sans-serif;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	background-color: $backgroundColor;
	color: $textColor;
	#app {
		max-width: 600px;
		margin-left: auto;
		margin-right: auto;
		padding: 20px;
		h1 {
			font-weight: bold;
			font-size: 28px;
			text-align: center;
		}
		form {
			display: flex;
			flex-direction: column;
			width: 100%;
			label {
				font-size: 14px;
				font-weight: bold;
			}
			input,
			button {
				height: $size5;
				box-shadow: none;
				outline: none;
				padding-left: $size2;
				padding-right: $size2;
				border-radius: $size1;
				font-size: 18px;
				margin-top: $size1;
				margin-bottom: $size2;
			}
			input {
				background-color: transparent;
				border: $border;
				color: inherit;
			}
		}
		button {
			cursor: pointer;
			background-color: $primaryColor;
			border: 1px solid $primaryColor;
			color: $secondTextColor;
			font-weight: bold;
			outline: none;
			border-radius: $size1;
		}
		h2 {
			font-size: 22px;
			border-bottom: $border;
			padding-bottom: $size1;
		}
		ul {
			padding: 10px;
			li {
				display: flex;
				justify-content: space-between;
				align-items: center;
				border: $border;
				padding: $size2 $size4;
				border-radius: $size1;
				margin-bottom: $size2;
				span {
					cursor: pointer;
				}
				.done {
					text-decoration: line-through;
				}
				button {
					font-size: $size2;
					padding: $size1;
				}
			}
		}
		h4 {
			text-align: center;
			opacity: 0.5;
			margin: 0;
		}
	}
}
</style>

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

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

相关文章

css动态导航栏鼠标悬停特效

charset "utf-8"; /*科e互联特效基本框架CSS*/ body, ul, dl, dd, dt, ol, li, p, h1, h2, h3, h4, h5, h6, textarea, form, select, fieldset, table, td, div, input {margin:0;padding:0;-webkit-text-size-adjust: none} h1, h2, h3, h4, h5, h6{font-size:12px…

【c++入门】函数重载,引用,内联函数,auto

函数重载 函数重载概念 什么是函数重载&#xff1f; 函数重载&#xff1a;是函数的一种特殊情况&#xff0c;C允许在同一作用域中声明几个功能类似的同名函数&#xff0c;这些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同&#xff0c;常用来处理实现功能类似数据类…

3D开发工具HOOPS助力PLM/PDM系统创新,高效实现复杂数据精细处理、3D模型交互可视化!

在现代制造和工程领域&#xff0c;PLM&#xff08;产品生命周期管理&#xff09;和PDM&#xff08;产品数据管理&#xff09;已成为企业优化流程和提升竞争力的关键工具。 随着技术的飞速发展&#xff0c;PLM和PDM应用程序需要更先进的工具来处理复杂的CAD数据、实现高效的3D可…

揭秘!宠物空气净化器对抗猫毛过敏,效果真的超乎想象?

猫毛过敏困扰着不少爱猫人士。尽管网络上充斥着各种缓解策略&#xff0c;但究竟哪种方法效果最佳&#xff1f;作为一位经验丰富的宠物主人&#xff0c;我搜集了大量信息&#xff0c;对比了几种主流的猫毛过敏应对策略&#xff0c;比如药物治疗、日常清洁和宠物空气净化器的使用…

电子凭证3.0,助力企业实现报销自动化

在数字化浪潮汹涌澎湃的今天&#xff0c;企业对于高效、便捷、安全的财务管理需求日益凸显。传统的报销流程繁琐、耗时&#xff0c;不仅增加了企业的运营成本&#xff0c;还影响了员工的工作效率和满意度。用友BIP电子凭证3.0的发布&#xff0c;无疑为企业实现报销自动化提供了…

Nginx配置详细解释

文章目录 一、配置详细解释关闭版本修改启动的进程数cpu与work进程绑定nginx进程的优先级work进程打开的文件个数event事件 二、Http设置协议配置说明mime虚拟主机aliaslocationaccess模块验证模块自定义错误页面自定义日志存放位置try_files检测文件是否存在长连接 一、配置详…

Android Studio插件开发 - Dora SDK的IDE插件

IDE插件开发简介 Android Studio是一种常用的集成开发环境&#xff08;IDE&#xff09;&#xff0c;用于开发Android应用程序。它提供了许多功能和工具&#xff0c;可以帮助开发人员更轻松地构建和调试Android应用程序。 如果你想开发Android Studio插件&#xff0c;以下是一…

计算病理学的视觉语言基础模型| 文献速递-视觉通用模型与疾病诊断

Title 题目 A visual-language foundation model for computational pathology 计算病理学的视觉语言基础模型 01 文献速递介绍 数字病理学的快速普及和深度学习的进步使得可以开发出针对各种疾病和患者群体的各种病理学任务的强大模型。然而&#xff0c;由于医学领域标签…

解锁破解2024最新版会声会影,序列号注册码大揭秘!

会声会影2024是一款专业的视频编辑软件&#xff0c;它为用户提供了丰富的功能和工具&#xff0c;让用户能够轻松地制作出精美的视频作品。如果你是一位热爱视频制作的朋友&#xff0c;那么你一定不能错过这款软件。本文将为大家介绍会声会影2024的序列号注册码以及如何购买和使…

安徽某高校数据挖掘作业4-5 (与一些碎碎念)

1. 编写程序求函数、、的极限。 解答&#xff1a; import sympy as sp# 定义符号变量 x x sp.symbols(x)# 定义函数 f1 sp.sin(20 * x) / x f2 (1 4 * x)**(2 / x) f3 (1 4 / x)**(2 * x)# 计算极限 limit1 sp.limit(f1, x, 0) limit2 sp.limit(f2, x, 0) limit3 sp…

文件上传漏洞之upload-labs

前提&#xff1a; 本文中的以xshell命名的均为以密码为admin的一句话木马&#xff0c;而shell命名的则是由冰蝎工具生成的木马。 pass-01&#xff1a;js前端验证 测试性的上传一个一句话木马&#xff0c;发现被拦截了&#xff0c;而且根据推测大概率是前端检测&#xff0c;于…

开发人员申请Claude API Key教程:轻松获取Claude 3模型API Key并开发部署自己的Claude 3聊天应用

开发者如何申请并使用ClaudeAPI开发部署自己的Claude 3聊天应用 ClaudeAPI是由Anthropic公司开发的一款基于Claude模型的自然语言处理API服务。它可以帮助开发者在自己的应用中集成先进的自然语言理解和生成能力。本文将介绍如何申请和使用ClaudeAPI。 一、注册Anthropic账号 …

订单排队与链动模式塑造社交电商新格局

在数字化浪潮中&#xff0c;社交电商凭借其独特的魅力与潜力&#xff0c;正逐渐崭露头角。本文将解读一种融合了订单排队与链动模式的创新商业模式。这一模式旨在通过提高消费者复购率&#xff0c;优化销售流程&#xff0c;从而推动销售增长&#xff0c;塑造社交电商新生态。 …

【栈】736. Lisp 语法解析

本文涉及知识点 栈 LeetCode736. Lisp 语法解析 给你一个类似 Lisp 语句的字符串表达式 expression&#xff0c;求出其计算结果。 表达式语法如下所示: 表达式可以为整数&#xff0c;let 表达式&#xff0c;add 表达式&#xff0c;mult 表达式&#xff0c;或赋值的变量。表达…

Nacos注册中心 --学习笔记

Nacos注册中心是什么&#xff1f; 想象一下一个繁忙的购物中心&#xff0c;里面有很多商店&#xff0c;每个商店都在某个位置提供不同的商品或服务。这个购物中心有一个信息台&#xff0c;人们可以在这里查询任何商店的位置和提供的服务。等到有新的商店开张&#xff0c;或者现…

运维工具 - SFTP 和 FTP 的区别?

SFTP 和 FTP 的区别有三点 连接方式 SFTP 是在客户端和服务器之间通过 SSH 协议建立的安全连接来传输文件&#xff0c;而 FTP 则是 TCP 端口 21 上的控制连接建立连接。 安全性 SFTP 使用加密传输认证信息来传输数据&#xff0c;因此 SFTP 相对于 FTP 更安全的。 效率 SF…

DevOps全面综述:从概念到实践

一、背景与概述 1.1 DevOps的起源与发展 DevOps&#xff08;Development and Operations的缩写&#xff09;是软件工程领域中的一种文化和实践方法&#xff0c;旨在促进开发团队与运维团队之间的协作&#xff0c;从而实现更高效、更可靠的软件交付。DevOps起源于敏捷软件开发方…

应届生毕业择业必看!这三个朝阳行业错过就晚了!2024普通人赚钱的行业、2024最适合创业的项目

俗话说“男怕入错行&#xff0c;女怕嫁错郎”。尤其是对于现在的年轻人来说&#xff0c;一个好的处于上升期的行业&#xff0c;所能带来的收益是无法估量的。所以在这个大学生即将步入社会的毕业季&#xff0c;我们一起看看国家统计局发布的这份数据报告&#xff0c;来分析哪些…

机器学习18个核心算法模型

1. 线性回归&#xff08;Linear Regression&#xff09; 用于建立自变量&#xff08;特征&#xff09;和因变量&#xff08;目标&#xff09;之间的线性关系。 核心公式&#xff1a; 简单线性回归的公式为&#xff1a; , 其中 是预测值&#xff0c; 是截距&#xff0c; 是斜…

动态规划——浅谈dp如何入门,以及入门题目(值得收藏,持续更新)

前言 动态规划如何入门?如果你问我怎么精通,那我只能告诉你我也不知道,但你要问我怎么入门,那我就可以和你说道说道了. 我并没有能力也不想说你看完就会了,我只是想给大家开个头,你只要知道怎么写了怎么去思考了,你就可以通过刷题来强化思维了,能走多远就看各位的造化了! 动…