Vue.js学习笔记(二) : 完成TodoMVC示例

上一章: Vue.js学习笔记(一) : 开发环境搭建

1.前言

    TodoMVC是一个示例项目,它使用目前流行的不同JavaScript框架的来实现同一个Demo,来帮助你熟悉和选择最合适的前端框架。官网地址:http://todomvc.com,学习框架最直接有效的方式就是上手练习,接下来我们将用Vue.js来完成TodoMVC的示例。

2.搭建TodoMVC开发环境

    2.1 访问官网:http://todomvc.com,点击下载模版。或直接输入:https://github.com/tastejs/todomvc-app-template进行下载

    

2.2 下载后,项目导入开发工具。目前我使用的是subline。


2.3 打开index.html并预览,会发现js和css文件没导入。这时我们可以使用node安装,cmd进入项目目录输入如下图命令,(在安装前修改package.json文件)

{
  "private": true,
  "dependencies": {
    "director": "^1.2.0",
    "vue": "^2.1.8",
    "todomvc-common": "^1.0.1",
    "todomvc-app-css": "^2.0.0"
  }
}


2.4 安装成功后,项目会新增node_modules文件夹。


2.5 打开index.html并在浏览器中预览,可以看见如下图:


3. TodoMVC需要实现的功能需求。

    3.1 TodoMVC环境已经搭建成功,接下来需要使用Vue.js来完成一些功能需求。

     3.1.1 新增数据

  • 在输入框填写新增的值,按Enter键保存。

     3.1.2 删除数据

  •  点击删除“按钮x”删除选择数据
  •  点击右下角“clear complete”清空已complete的数据

    3.1.3 修改数据

  •  双击某行数据时切换到输入框状态并且自动获得焦点。
  •  按“Enter”键或光标离开可以修改数据。

    3.1.4 浏览数据

  •  当list有值时,可以正常显示数据。
  •  左下角“item left”根据当前item数自动变化。
  •  点击下方的“all”“active”“complete”可以过滤list,并且a标签高亮自动能切换。
  •  勾选item可以切换“active”和“complete”样式。
  •  当item全选时,新增数据框左侧的“小箭头”高亮。
  •  点击新增数据框左侧的“小箭头”,可以全选或全不选item。
  •  进入首页时,新增输入框自动获得焦点。

    4.主要代码

    4.1 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" id="apps">
			<header class="header">
				<h1>todos</h1>
				<input class="new-todo" placeholder="What needs to be done?" v-focuz @keyup.enter="addTodo" >
			</header>
			<template v-if="fruits.length">
			<!-- This section should be hidden by default and shown when there are todos -->
			<section class="main" >
				<input id="toggle-all" class="toggle-all"  @click="toggleall" type="checkbox" v-model = "toggleAllStat.length ===0">
				<label for="toggle-all">Mark all as complete</label>
				<ul class="todo-list">
					<!-- These 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 
					v-for="(item,index) in fruitsFilter" 
					:class="{completed : item.checkstate,editing:item === editstate}">
						<div class="view">
							<input class="toggle" type="checkbox" v-model="item.checkstate">
							<label @dblclick="editstate = item">{{item.name}}</label>
							<button class="destroy" @click="removeItem(index)"></button>
						</div>
						<input class="edit" v-model="item.name" v-dblfocus="item === editstate" 
						@keyup.enter="editstate = null" 
						@blur="editstate = null" >
					</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>{{itemleft}}</strong> item left</span>
				<!-- Remove this if you don't implement routing -->
				<ul class="filters">
					<li>
						<a :class="{selected:filterStat===''}" href="#/">All</a>
					</li>
					<li>
						<a :class="{selected:filterStat==='active'}" href="#/active">Active</a>
					</li>
					<li>
						<a :class="{selected:filterStat==='completed'}" href="#/completed">Completed</a>
					</li>
				</ul>
				<!-- Hidden if no completed items are left ↓ -->
				<button class="clear-completed" @click="removeALLDone">Clear completed</button>
			</footer>
			</template>
		</section>
		<footer class="info" id="apps">
			<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.js"></script>
		<script src="node_modules/todomvc-common/base.js"></script>
		<script src="js/app.js"></script>
		
	</body>
</html>

4.2 app.js

(function (Vue) {
	//定义数组
	const fruitz = [
	{
		id : 1,
		name : '苹果',
		checkstate : true
	},
	{
		id : 2,
		name : '香蕉',
		checkstate : true
	},
	{
		id : 3,
		name : '葡萄',
		checkstate : false
	}
	]
	
	window.vm = new Vue({
		el : '#apps',
		data:{
			fruits : fruitz,
			editstate : null,
			filterStat : 'all'
		},
		computed : {
			
			fruitsFilter : function () {
				
				switch(this.filterStat){
					case 'active' : 
					return this.fruits.filter(function (item) {
						return item.checkstate === false
					})
					break;
					case 'completed' :
					return this.fruits.filter(function (item) {
						return item.checkstate === true
					})
					break;
					default :
					return this.fruits
					break;
				}
			},
			itemleft : function () {
				return this.fruitsFilter.length;
			},
			toggleAllStat : function () {
				return this.fruits.filter(item => item.checkstate === false);
			}
		},
		methods:{
		toggleall:function (event) {
			const check = event.target.checked;
			this.fruits.forEach(function(item){
					item.checkstate = check;
			})
		},

		addTodo : function (event){
			const valueStr = event.target.value;
			var lastFruits = this.fruits[this.fruits.length-1];
			var idStr = lastFruits ? lastFruits.id+1 : 1;
			this.fruits.push({
					id : idStr,
					name : valueStr,
					checkstate : false
				})
			
			event.target.value = '';
		},

		removeItem : function (index) {
			this.fruits.splice(index,1);
		},

		removeALLDone : function () {

			this.fruits =  this.fruits.filter(function(item){
				return !item.checkstate
			})
		},

		editInput:function () {
			console.log('editInput');
		},

		editSave : function (item,event) {
				this.editstate = null;
		}
		},
		directives : {
			focuz : {
				inserted : function (el) {
					el.focus();
				}
			},
			dblfocus : {
				update : function (el,binding) {
					console.log(binding.value);
					if(binding.value){
						console.log('fff');
						el.focus();
					}
					
				}
			}
		}
	})

	window.onhashchange = function () {
		const hashStr = location.hash.replace("#/","");
		vm.filterStat = hashStr;
	}

})(Vue)

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值