vue框架下的TodoMVC

TodoMVC 案例官网:http://todomvc.com/

        

 注意进入官网后,获取TodoMVC模板是一个非常不起眼的template。

嘿嘿我这有准备好的压缩包(请看我的主页)

完整的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="todoapp">
			<header class="header">
				<h1>todos</h1>
				<input @keyup.enter="addItem" class="new-todo" placeholder="What needs to be done?" autofocus>
			</header>
			<!-- This section should be hidden by default and shown when there are todos -->
			<template v-if="items.length">
				<section class="main">
					<input id="toggle-all" class="toggle-all" type="checkbox" v-model="toggleAll">
					<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 filterItems" :key="item.id" :class="{completed:item.completed,editing:currentItem===item}">
							<div class="view">
								<input class="toggle" type="checkbox" v-model="item.completed">
								<label @dblclick="toEdit(item)">{{item.context}}</label>
								<button class="destroy" @click="removeItem(index)"></button>
							</div>
							
							<input class="edit" :value="item.context" v-todofocus="currentItem===item" @keyup.esc="cancelEdit" @keyup.enter="finish(index,item,$event)" @blur="finish(index,item,$event)">
						</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>{{filterItem}}</strong> item{{filterItem === 1?"":"s"}} left</span>
					<!-- Remove this if you don't implement routing -->
					<ul class="filters">
						<li>
							<a :class="{selected: filterStatus === 'all'}" href="#/">All</a>
						</li>
						<li>
							<a :class="{selected: filterStatus === 'active'}" href="#/active">Active</a>
						</li>
						<li>
							<a :class="{selected: filterStatus === 'completed'}" href="#/completed">Completed</a>
						</li>
					</ul>
					<!-- Hidden if no completed items are left ↓ -->
					<button class="clear-completed" v-show="filterItem<items.length" @click="removeCompleted">Clear completed</button>
				</footer>
			</template>
			</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/todomvc-common/base.js"></script>
		<script src="./node_modules/vue/dist/vue.js"></script>
		<script src="js/app.js"></script>
	</body>
</html>

完整的app.js代码

// (function (window) {
// 	'use strict';

// 	// Your starting point. Enjoy the ride!

// })(window);

(function(Vue){
const arr=[]
	const itemStorage = {
		fetch: function () { // 获取本地数据
			return JSON  .parse(localStorage.getItem('todo-vuejs') || '[]');
		},
		save: function (items) { // 保存数据到本地
			localStorage.setItem('todo-vuejs', JSON.stringify(items));
		}
	}
	var app = new Vue({
		el:'#todoapp',
		data:{
			items:itemStorage.fetch(),
			currentItem:null,
			filterStatus: 'all' // 上面不要少了逗号,接收变化的状态值
		},
		watch:{
			items:{deep:true,
			handler:function(newValue){
				itemStorage.save(newValue)
			}}
			
		},
		directives:{
			'todofocus':{
				update(el,binding){
					if(binding.value){
						el.focus();
					}
				}
			}
		},
		methods:{
			addItem(event){
				// 1.获取input内的值,并去掉空格
				const context = event.target.value.trim()
				// 2.判断如果数据为空,什么都不做
				// console.log(context);
				if(!context.length){
					return
				}
				// 3.如果数据不为空
				// 1)生成id
				const id = this.items.length + 1;
				// 2)添加到数组中
				this.items.push({
					id:id,
					context:context,
					completed:false
				})
				// 3)清空input
				event.target.value=''
			},
			removeItem(index){
				this.items.splice(index,1)
			},
			removeCompleted(){
				this.items = this.items.filter(function(item){
					return !item.completed
				})
			},
			toEdit(item){
				this.currentItem = item
			},
			cancelEdit(){
				this.currentItem=null
			},
			finish(index,item,event){
				if(!event.target.value.trim()){
					return this.removeItem(index);
				}
				item.context = event.target.value.trim();
				this.currentItem = null;
			}
		},
			computed:{
				   // 过滤出不同状态数据
				   filterItems() {
                    //this.filterStatus 作为条件,变化后过滤不同数据
                    switch (this.filterStatus) {
                        case "active": // 过滤出未完成的数据
                            return this.items.filter(item => !item.completed)
                            break
                        case "completed": // 过滤出已完成的数据
                            return this.items.filter(item => item.completed)
                            break
                        default: // 其他,返回所有数据
                            return this.items
                    }
                },

				filterItem(){
					return this.items.filter(function(item){
						return !item.completed
					}).length
				},
				toggleAll:{
					get(){
						return this.filterItems===0
					},
					set(newValue){
						this.items.forEach(function(item){
							item.completed = newValue
						})
					}
				}
			}
		
	})

	//当路由 hash 值改变后会自动调用此函数
	window.onhashchange = function () {
		console.log('hash改变了' + window.location.hash)
		// 1.获取点击的路由 hash , 当截取的 hash 不为空返回截取的,为空时返回 'all'
		var hash = window.location.hash.substr(2) || 'all'
		// 2. 状态一旦改变,将 hash 赋值给 filterStatus
		// 当计算属性 filterItems 感知到 filterStatus 变化后,就会重新过滤
		// 当 filterItems 重新过滤出目标数据后,则自动同步更新到视图中
		app.filterStatus = hash
	}
	// 第一次访问页面时,调用一次让状态生效
	window.onhashchange()
})(Vue)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值