vue3 todolist 简单例子

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>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JVM双亲委派模型

在之前的JVM类加载器篇中说过&#xff0c;各个类加载器都有自己加载的范围&#xff0c;比如引导类加载器只加载Java核心库中的class如String&#xff0c;那如果用户自己建一个包名和类名与String相同的类&#xff0c;会不会被引导类加载器加载。可以通过如下代码测试&#xff0…

每周统计-20240531

用于测试程序的稳定性&#xff1a; 龙虎榜&#xff1a; 成交额&#xff1a; 封成比&#xff1a; 收盘前放量&#xff1a; 开盘抢筹&#xff1a; 封单额&#xff1a;

堆排序-java

这次主要讲了堆排序和堆的基本构造&#xff0c;下一期会详细讲述堆的各种基本操作。 文章目录 前言 一、堆排序 1.题目描述 2.堆 二、算法思路 1.堆的存储 2. 结点下移down 3.结点上移up 4.堆的基本操作 5.堆的初始化 三、代码如下 1.代码如下&#xff1a; 2.读入数据&#xff…

24年护网工具,今年想参加护网的同学要会用

24年护网工具集 吉祥学安全知识星球&#x1f517;http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247483727&idx1&sndb05d8c1115a4539716eddd9fde4e5c9&chksmc0e47813f793f105017fb8551c9b996dc7782987e19efb166ab665f44ca6d900210e6c4c0281&scene21…

2024拼多多 最新理论+实战干货,从入门到精通全链路多角度学习-7节课

基于最新规则理论结合实际的干货 课程内容&#xff1a; 01 2024年多多防比价新规则破局理论课与实操课.mp4 02 24年多多强付费第二节课基础内功.mp4 03 24年多多强付费第三节课直通车实操 .mp4 04 24年多多强付费第一节课市场定价格段,mp4 05 24年多多自然流第一节课市场…

Java+SVNCloud+Mysql课程设计

文章目录 1、主要内容2、所需准备3、与sql访问的中间类&#xff1a;SqlMessage4、窗口界面5、main方法 1、主要内容 课程设计&#xff0c;主要通过Javas wing创建窗口&#xff0c;jdbc连接云端mysql数据库进行基本操作&#xff0c;支持随机生成数据并用动态展示数据结果。 先…

计算机毕业设计 | springboot+vue会议室管理系统(附源码)

1&#xff0c;绪论 1.1 项目背景 随着企业规模的不断扩大&#xff0c;会议室管理愈加复杂。传统的手工预约会议室的方式已经无法满足现代企业的需求&#xff0c;因此&#xff0c;开发一套会议室系统方案变得尤为重要。会议室系统可以实现会议室的在线预约、会议室资源的有效利…

[SQL-SERVER:数据库安全及维护]:MSSM工具进行附加还原备份等操作

文章目录 目的介绍一、完整备份与还原&#xff08;20分&#xff09;1.将教师提供的TeachingDB数据库附加到个人使用的服务器上&#xff0c;并更名为TeachingDB_***&#xff08;***为个人姓名&#xff09;1.1 操作流程&#xff1a;将docker容器sqlserver数据库已有的mdf镜像文件…

C语言之旅:探索单链表

目录 一、前言 二、实现链表的功能&#xff1a; 打印 创建节点 尾插 尾删 头插 头删 查找 在指定位置之前插入数据 指定位置删除 在指定位置之后插入数据 打印 销毁 三、全部源码&#xff1a; 四、结语 一、前言 链表是一个强大且基础的数据结构。对于很多初…

Mac连接虚拟机(Linux系统)

1.确定虚拟机的IP地址 ifconfig //终端命令&#xff0c;查询ip地址 sudo apt install net-tools 安装完成后再次执行 ifconfig&#xff1a; 2.安装SSH&#xff08;加密远程登录协议&#xff09; (1).安装OpenSSH服务器软件包&#xff1a; sudo apt-get install openssh-ser…

Linux开发

建议大家使用 Linux 做开发 Linux 能用吗&#xff1f; 我身边还有些朋友对 linux 的印象似乎还停留在黑乎乎的命令行界面上。当我告诉他或者建议他使用 linux 时&#xff0c;会一脸惊讶的问我&#xff0c;那个怎么用&#xff08;来开发或者日常使用&#xff09;&#xff1f; …

鸿蒙开发接口资源管理:【@ohos.intl (国际化-Intl)】

国际化-Intl 说明&#xff1a;开发前请熟悉鸿蒙开发指导文档&#xff1a;gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到。 本模块首批接口从API version 6开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。Intl模块…

LabVIEW如何确保步进电机的长期稳定运行

步进电机因其良好的定位精度和控制性&#xff0c;在自动化设备中得到了广泛应用。然而&#xff0c;长期稳定运行对于任何电机系统都是一个重要的挑战。LabVIEW作为一款强大的图形化编程语言&#xff0c;通过其灵活的控制算法和实时监控能力&#xff0c;为步进电机的稳定运行提供…

慢SQL的治理思路

慢SQL的治理思路 什么是慢SQL慢SQL产生的原因查看慢 SQL 是否开启开启慢 SQL 记录开启慢查询日志分析慢 SQL解决和优化慢SQL的方法 什么是慢SQL 慢 SQL 指的是 MySQL 中执行比较慢的 SQL&#xff0c;排查慢 SQL 最常用的方法是通过慢查询日志来查找慢 SQL。 MySQL 的慢查询日志…

【并发程序设计】14.消息队列

14.消息队列 消息队列&#xff08;Message Queue&#xff09;是一种通信机制&#xff0c;用于在分布式系统中传递和管理消息的队列型数据结构。 消息队列通常是一个先进先出&#xff08;FIFO&#xff09;的数据结构&#xff0c;它允许多个进程或线程之间以异步方式进行通信。…

Google力作 | Infini-attention无限长序列处理Transformer

更多文章&#xff0c;请关注微信公众号&#xff1a;NLP分享汇 原文链接&#xff1a;Google力作 | Infini-attention无限长序列处理Transformerhttps://mp.weixin.qq.com/s?__bizMzU1ODk1NDUzMw&mid2247485000&idx1&sne44a7256bcb178df0d2cc9b33c6882a1&chksm…

OpenCV 的几种查找图像中轮廓边缘的方法

原始图片&#xff1a; 1、Sobel() Sobel 算子结合了高斯平滑和微分&#xff0c;用于计算图像的梯度&#xff0c;从而突出显示边缘。 import cv2# 读取图像 image cv2.imread(image.png, cv2.IMREAD_GRAYSCALE)# 使用 Sobel 算子查找水平和垂直边缘 sobel_x cv2.Sobel(image…

浅谈旧项目如何添加新依赖

Spring项目创建之后&#xff0c;还想添加新的依赖&#xff08;如Spring框架内置的依赖&#xff09;&#xff0c;可以安装插件&#xff1a; 装完该插件之后&#xff0c;就可以在pom.xml文件里&#xff0c;右键选择 Generate即可出现下述界面&#xff1a; 点击ok即可添加新的…

服务器硬件基础知识学习

服务器硬件基础知识涵盖了从CPU到存储&#xff0c;再到网络连接和总线技术等关键组件。 1. 处理器 - 两大流派&#xff1a;我们常用的处理器主要分为Intel和AMD两大阵营。Intel的Xeon系列和AMD的EPYC系列都是专为服务器设计的&#xff0c;它们支持多核处理&#xff0c;能够应对…

最新一站式AI创作中文系统网站源码+系统部署+支持GPT对话、Midjourney绘画、Suno音乐、GPT-4o文档分析等大模型

一、系统简介 本文将介绍最新的一站式AI创作中文系统&#xff08;集成ChatGPTMidjourneySunoStable Diffusion&#xff09;——星河易创AI系统&#xff0c;该系统基于ChatGPT的核心技术&#xff0c;融合了自然语言问答、绘画、音乐、文档分享、图片识别等创作功能&#xff0c;…