Vue.js框架入门经典项目TodoMVC

1. 介绍

  1. 项目地址:http://todomvc.com/
  2. github模板下载地址:https://github.com/tastejs/todomvc-app-template
  3. 可通过git和npm下载。
  4. 下载完毕之后主要修改app.js和index.html这两个文件。

2. index.html代码:

<!doctype html>
<html lang="en">
	<head>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<title>Template • TodoMVC</title>
		<link rel="stylesheet" href="node_modules/todomvc-common/base.css">
		<link rel="stylesheet" href="node_modules/todomvc-app-css/index.css">
		<!-- CSS overrides - remove if you don't need it -->
		<link rel="stylesheet" href="css/app.css">
	</head>
	<body>
		<section class="todoapp">
			<header class="header">
				<h1>todos</h1>
				<input class="new-todo" v-model="inputVal" @keyup.enter="addTodo" placeholder="What needs to be done?" autofocus>
			</header>
			<!-- This section should be hidden by default and shown when there are todos -->
			<section class="main">
				<input id="toggle-all" class="toggle-all" type="checkbox" @change="selectAll" v-model="isAll">
				<label for="toggle-all">Mark all as complete</label>
				<ul class="todo-list">
					<!-- Twhese are here just to show the structure of the list items -->
					<!-- List items should get the class `editing` when editing and `completed` when marked as completed -->
					<!-- <li class="completed">
						<div class="view">
							<input class="toggle" type="checkbox" checked>
							<label>Taste JavaScript</label>
							<button class="destroy"></button>
						</div>
						<input class="edit" value="Create a TodoMVC template">
					</li> -->
					<li @dblclick="changeStatus(index)" v-for="(item,index) in currentTodoList" :class="{completed:item.isCompeleted,editing:currentIndex===index}">
						<div class="view">
							<input class="toggle" type="checkbox" v-model="item.isCompeleted" @change="changeOneStatus">
							<label>{{item.content}}</label>
							<button class="destroy" @click="deleteTodo(index)"></button>
						</div>
						<input @blur="currentIndex=''" v-focus class="edit" value="Rule the web" v-model="item.content">
					</li>
				</ul>
			</section>
			<!-- This footer should hidden by default and shown when there are todos -->
			<footer class="footer">
				<!-- This should be `0 items left` by default -->
				<span class="todo-count"><strong>{{leftCount}}</strong> item left</span>
				<!-- Remove this if you don't implement routing -->
				<ul class="filters">
					<li>
						<a :class="{selected:hash=='#/'}" href="#/">All</a>
					</li>
					<li>
						<a :class="{selected:hash=='#/active'}" href="#/active">Active</a>
					</li>
					<li>
						<a :class="{selected:hash=='#/completed'}" href="#/completed">Completed</a>
					</li>
				</ul>
				<!-- Hidden if no completed items are left ↓ -->
				<button class="clear-completed" @click="clearCompleted">Clear completed</button>
			</footer>
		</section>
		<footer class="info">
			<p>Double-click to edit a todo</p>
			<!-- Remove the below line ↓ -->
			<p>Template by <a href="http://sindresorhus.com">Sindre Sorhus</a></p>
			<!-- Change this out with your name and url ↓ -->
			<p>Created by <a href="http://todomvc.com">you</a></p>
			<p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
		</footer>
		<!-- Scripts here. Don't remove ↓ -->
		<script src="node_modules/vue/dist/vue.min.js"></script>
		<script src="js/app.js"></script>
	</body>
</html>

3. app.js代码

var vm = new Vue({
	el: ".todoapp",
	data: {
		inputVal: '',
		todoList: [],
		isAll: false,
		currentIndex: '',
		hash: ''
	},
	//默认hash值为'#/'
	created() {
		window.addEventListener("load", () => {
			window.location.hash = "#/";
			this.hash = "#/";
			this.todoList=this.getStorage();
		})
		//根据本地hash值的改变,改变数据模型中的hash值
		window.addEventListener("hashchange", () => {
			this.hash = window.location.hash;
		})
	},
	computed: {
		//计数
		leftCount() {
			return this.todoList.reduce((total, item) => {
				if (item.isCompeleted) {
					return total;
				} else {
					total += 1;
					return total;
				}
			}, 0)
		},
		//根据hash值 改变显示数据
		currentTodoList() {
			if (this.hash == "#/") {
				return this.todoList
			} else if (this.hash == "#/active") {
				return this.todoList.filter((item) => {
					return item.isCompeleted == false;
				})
			} else if (this.hash == "#/completed") {
				return this.todoList.filter((item) => {
					return item.isCompeleted == true;
				})
			} else {
				return this.todoList
			}
		}
	},
	//创建自定义属性   聚焦
	directives: {
		focus(el) {
			el.focus()
		}
	},
	methods: {
		//1.设置本地存储
		setStorage(todoList){
			window.localStorage.setItem("list",JSON.stringify(todoList))
		},
		//2.读取本地数据
		getStorage(){
		return	window.localStorage.getItem("list")?JSON.parse(window.localStorage.getItem("list")):[]
		},
		//添加数据
		addTodo() {
			var obj = {
				content: this.inputVal,
				isCompeleted: false
			}
			this.todoList.push(obj);
			this.inputVal = '';
			this.setStorage(this.todoList);
		},
		//删除数据
		deleteTodo(index) {
			this.todoList.splice(index, 1);
			this.setStorage(this.todoList);
		},
		//全选/全不选
		selectAll() {
			// console.log(this.isAll)
			this.todoList.forEach((item) => {
				item.isCompeleted = this.isAll;
			})
			this.setStorage(this.todoList);
		},
		//编辑状态索引等于鼠标双击索引
		changeStatus(index) {
			// console.log(index)
			this.currentIndex = index;
		},
		//删除选中数据
		clearCompleted() {
			this.todoList = this.todoList.filter((item) => {
				return item.isCompeleted == false;
			})
			this.setStorage(this.todoList);
		},
		//状态改变,本地存储数据跟随改变   true/flase
		changeOneStatus(){
			this.setStorage(this.todoList);
		}
	}
})

4. 效果图

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值