Vue.js经典项目:TodoMvc

1、github拉取只含静态页面的项目

Vue.js经典项目:TodoMvc_第1张图片

2、app.js文件

(function (Vue) {
	const STORAGE_KEY='todo-items';
	const itemStorage={
		//获取数据
		fetch:function(key){
			return JSON.parse(localStorage.getItem(key)||'[]'); //json字符串转数组返回
		},
		//保存数据
		save:function(key,items){
			localStorage.setItem(key,JSON.stringify(items)); //json字符串
		}
	};
	const items = [
		{
			id: 1,
			content: "C#",
			isCompleted: false
		}, {
			id: 2,
			content: "Java",
			isCompleted: false
		}, {
			id: 3,
			content: "Python",
			isCompleted: false
		}];

	//注册全局指令
	Vue.directive('input-focus', {
		inserted(el, binding) {
			el.focus();
		},
		update(el, binding) {
			if (binding.value) {
				el.focus();
			}
		}
	});
	var vm = new Vue({
		el: "#todoapp",
		data: {
			title: 'todos',
			//items, //ES6对象属性的简写 items:items
			items:itemStorage.fetch(STORAGE_KEY),
			currentItem: null,
			filterStatus: 'all'
		},
		//侦听器
		watch:{
			//items:function(newItems,oldItems){};//数组监听
			//深度监听 监听数组中对象属性是否发生变化 deep:true
			items:{
				deep:true,
				handler:function(newItems,oldItems){//处理函数
					itemStorage.save(STORAGE_KEY,newItems);//监听到变化则保存到本地
				}
			}

		},
		//计算属性
		computed: {
			filterItems() {
				switch (this.filterStatus) {
					case 'active':
						return this.items.filter(item => !item.isCompleted);
						break;
					case 'completed':
						return this.items.filter(item => item.isCompleted);
						break;
					default:
						return this.items;
						break;
				}
			},
			toggleAll: {
				get() { //必须有返回值
					return this.remaining === 0;
				},
				set(newStatus) {
					this.items.forEach(item => item.isCompleted = newStatus);
				}
			},
			//剩余未完成的数量
			remaining() { //remaining:function()简写
				//const unCompletedItems=this.items.filter(function(item){
				//	return !item.isCompleted;
				//});
				//return unCompletedItems.length;
				return this.items.filter(item => !item.isCompleted).length;
			},
			itemOrItems() {
				if (this.remaining === 1) {
					return 'Item';
				}
				else {
					return 'Items';
				}
			},
			hasCompletedItem() {
				return this.items.some(item => item.isCompleted);
			}
		},
		methods: {
			toEdit(item) {
				this.currentItem = item;
			},
			cancleEdit() {
				this.currentItem = null;
			},
			finishedEdit(item, index, event) {
				const newContent = event.target.value;
				if (!newContent) {
					this.removeItem(index);
				}
				item.content = newContent;
				this.currentItem = null;
			},
			addItem(event) {
				const content = event.target.value.trim();
				let maxId = Math.max.apply(Math, this.items.map(item => item.id));//对象组id最大值
				if (content.length > 0) {
					this.items.push(
						{
							id: maxId + 1,
							content,
							isCompleted: false
						}
					);
					event.target.value = "";
				}
			},
			removeItem(index) {
				this.items.splice(index, 1);
			},
			clearAll() {
				this.toggleAll = false;
			},
			addClass(e) {
				let element = e.currentTarget;
				if (!element.classList.contains('editing')) {
					element.classList.toggle('editing');
				}
			}
		}
	});

	//路由hash值改变时调用
	window.onhashchange = () => {
		const hash = window.location.hash.substr(2) || 'all';
		vm.filterStatus = hash;
	};

	//刷新页面的时候调用
	window.onhashchange();
})(Vue);

3、index.html页面vuejs绑定





	
	
	Template • TodoMVC
	
	
	
	



	

{{title}}

 

你可能感兴趣的:(Vue.js,JavaScript,前端)