Vue——组件化todolist

index部分 

<!DOCTYPE html>
<html lang="en">

<head>
	<meta charset="UTF-8">
	<title>Title</title>
	<link rel="stylesheet" type="text/css" href="css/todolist.css" />
</head>

<body>
	<div id="app">
		<header>
			<form @submit.prevent='submit($event)'>
				<label for="inpTitle">ToDoList</label>
				<input type="text" id="inpTitle" placeholder="添加ToDo" required="required" />
			</form>
		</header>
		<section>
			<ullist title="正在进行" :local="local" :num="todonum" :flag="todoflag" @dellist="delitem"
				@editdatalist="editdataitem(arguments)" @changedatalist="changedataitem"></ullist>
			<ullist title="已完成" :local="local" :num="donenum" :flag="doneflag" @dellist="delitem"
				@editdatalist="editdataitem(arguments)" @changedatalist="changedataitem"></ullist>
		</section>
		<footer>
			<p>Copyright &copy; 2014 todolist.cn <a @click="clearLocal()">clear</a></p>
		</footer>
	</div>
	<template id="ullist">
		<div>
			<slot>
				<h2>{{title}}<span>{{num}}</span></h2>
				<ul>
					<li v-for="(item,index) in local" :key="index" v-if="item.todo===flag">
						<input type="checkbox" @change="changedata(index)" :checked="flag" />
						<input type="text" v-model="item.title" @blur="editdata($event,index)" />
						<a @click="del(index)">-</a>
					</li>
				</ul>
			</slot>
		</div>
	</template>
	<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
	<script>
		const ullist = {
			template: '#ullist',
			props: {
				title: {
					type: String
				},
				local: {
					type: Array
				},
				flag: {
					type: Boolean,
					default: false
				},
				num: {
					type: Number,
					default: 0
				}
			},
			methods: {
				del(index) {
					this.$emit('dellist', index)
				},
				editdata(e, index) {
					this.$emit('editdatalist', e, index)
				},
				changedata(index) {
					this.$emit('changedatalist', index)
				}
			}
		}
	</script>
	<script src="js/todolist.js"></script>
</body>

</html>

css部分:

*{
	margin: 0;
	padding: 0;
}
a{
	text-decoration: none;
	cursor: pointer;
}
li{
	list-style: none;
}
body{
	background-color: #CDCDCD;
}
header{
	width: 100%;
	height: 50px;
	background-color: #323232;
}
header form{
	width: 620px;
	height: 50px;
	margin: 0 auto;
}
form label{
	color: #DDDDDD;
	font-size: 24px;
	line-height: 50px;
	cursor: pointer;
}
form input{
	width: 364px;
	height: 26px;
	outline: 0;
	padding-left: 10px;
	box-sizing: border-box;
	border-radius: 5px;
	background-color: #FFFFFF;
	float: right;
	margin-top: 12px;
	border: none;
	box-shadow: 0 1px 0 rgb(255 255 255 / 24%), 0 1px 6px rgb(0 0 0 / 45%) inset;
}
section{
	width: 620px;
	padding: 0px 10px;
	box-sizing: border-box;
	margin: 0 auto;
}
section h2{
	margin: 20px 0px;
}
section h2 span{
	display: inline-block;
	height: 20px;
	line-height: 20px;
	text-align: center;
	color: #666666;
	font-size: 14px;
	background-color: #E6E6FA;
	padding: 0px 5px;
	border-radius: 20px;
	float: right;
	margin-top: 6px;
}

section ul li{
	height: 32px;
	background-color: #FFFFFF;
	border-left: 5px solid #629A9C;
	line-height: 32px;
	margin-bottom: 10px;
	border-radius: 3px;
	box-shadow: 0 1px 2px rgb(0 0 0 / 7%);
	padding: 0px 45px;
	position: relative;
}
section ul li p{
	margin: 0 auto;
	height: 32px;
}
section ul li>input:nth-of-type(1){
	width: 22px;
	height: 22px;
	position: absolute;
	top: 50%;
	left: 12px;
	margin-top: -11px;
}
section ul li>input:nth-of-type(2){
	width: 100%;
	height: 90%;
	box-sizing: border-box;
	border: none;
	font-size: 16px;
}
section ul li>input:nth-of-type(2):focus{
	outline: 1px solid #333333;
	padding-left: 5px;
}
section ul li a{
	display: block;
	width: 26px;
	height: 24px;
	line-height: 12px;
	text-align: center;
	box-sizing: border-box;
	border-radius: 14px;
	border: 6px double #FFF;
	background: #CCC;
	color: #FFFFFF;
	font-weight: 700;
	position: absolute;
	top: 50%;
	right: 12px;
	margin-top: -12px;
}

footer{
	color: #666666;
	font-size: 14px;
	text-align: center;
}
footer a{
	color: #999999;
}

JS部分

const app = new Vue({
	el: '#app',
	data() {
		return {
			local: [],
			todoflag: false,
			doneflag: true,
			todonum: 0,
			donenum: 0
		}
	},
	components: {
		ullist
	},
	methods: {
		submit(e) {
			console.log(e.target[0].value);
			let newtodo = {
				"title": e.target[0].value,
				"todo": false
			}
			e.target[0].value = ''
			//点击回车增加数据
			this.local.unshift(newtodo)
			//存储数据
			this.savedata()
			this.count()
		},
		//存储数据
		savedata() {
			window.localStorage.setItem('todo', JSON.stringify(this.local))
		},
		//删除数据
		delitem(index) {
			//删除点击的某一项
			this.local.splice(index, 1)
			//存储数据
			this.savedata()
			this.count()
		},
		//编辑数据
		editdataitem(e) {
			console.log(e[0]); //代表点击某一项失焦事件
			console.log(e[1]); //索引
			var index = e[1]
			this.local[index].title = e[0].target.value
			//存储数据
			this.savedata()
		},
		//切换数据
		changedataitem(index) {
			console.log(index);
			this.local[index].todo ? this.local[index].todo = false : this.local[index].todo = true,
				//存储数据
				this.savedata()
			this.count()
		},
		//数据个数
		count() {
			this.donenum = 0;
			this.todonum = 0;
			this.local.forEach((v, index) => {
				v.todo ? this.donenum++ : this.todonum++
			})
		}
	},
	created() {
		let data = window.localStorage.getItem('todo')
		if (data != null) {
			console.log(JSON.parse(data));
			this.local = JSON.parse(data)
			this.count()
		} else {
			this.local = []
		}
	}


})

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Southern Wind

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值