• 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

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

    
    <template>
    	<h1>ToDo Apph1>
    	<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>
    
    
  • 相关阅读:
    Redis快速上手神册,17W字详解其实Redis也就那么一回事!
    【MySQL】(五)DML表数据操作——数据的插入、修改、删除
    研发日常踩坑-Mysql分页数据重复 | 京东云技术团队
    SQL Server远程登录失败
    【JAVASE系列】08_抽象类与接口
    Ubuntu 22报错:PAM unable to dlopen(pam_tally2.so)
    Springboot整合Redis的Cluster集群进行API限流
    头歌-信息安全技术-Java生成验证码
    国产API管理神器Eolink也太强了吧
    外呼系统线路不稳定,经常封号怎么办?
  • 原文地址:https://blog.csdn.net/pacong/article/details/139392805