Evan You пре 9 година
родитељ
комит
ccd8d587d6

+ 157 - 0
examples/todomvc/app.js

@@ -0,0 +1,157 @@
+// Full spec-compliant TodoMVC with localStorage persistence
+// and hash-based routing in ~150 lines.
+
+// localStorage persistence
+var STORAGE_KEY = 'todos-vuejs-2.0'
+var todoStorage = {
+  fetch: function () {
+    var todos = JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]')
+    todos.forEach(function (todo, index) {
+      todo.id = index
+    })
+    todoStorage.uid = todos.length
+    return todos
+  },
+  save: function (todos) {
+    localStorage.setItem(STORAGE_KEY, JSON.stringify(todos))
+  }
+}
+
+// visibility filters
+var filters = {
+  all: function (todos) {
+    return todos
+  },
+  active: function (todos) {
+    return todos.filter(function (todo) {
+      return !todo.completed
+    })
+  },
+  completed: function (todos) {
+    return todos.filter(function (todo) {
+      return todo.completed
+    })
+  }
+}
+
+// app Vue instance
+var app = new Vue({
+  // app initial state
+  data: {
+    todos: todoStorage.fetch(),
+    newTodo: '',
+    editedTodo: null,
+    visibility: 'all'
+  },
+
+  // watch todos change for localStorage persistence
+  watch: {
+    todos: {
+      handler: function (todos) {
+        todoStorage.save(todos)
+      },
+      deep: true
+    }
+  },
+
+  // computed properties
+  // http://vuejs.org/guide/computed.html
+  computed: {
+    filteredTodos: function () {
+      return filters[this.visibility](this.todos)
+    },
+    remaining: function () {
+      return filters.active(this.todos).length
+    },
+    allDone: {
+      get: function () {
+        return this.remaining === 0
+      },
+      set: function (value) {
+        this.todos.forEach(function (todo) {
+          todo.completed = value
+        })
+      }
+    }
+  },
+
+  filters: {
+    pluralize: function (n) {
+      return n === 1 ? 'item' : 'items'
+    }
+  },
+
+  // methods that implement data logic.
+  // note there's no DOM manipulation here at all.
+  methods: {
+    addTodo: function () {
+      var value = this.newTodo && this.newTodo.trim()
+      if (!value) {
+        return
+      }
+      this.todos.push({
+        id: todoStorage.uid++,
+        title: value,
+        completed: false
+      })
+      this.newTodo = ''
+    },
+
+    removeTodo: function (todo) {
+      this.todos.splice(this.todos.indexOf(todo), 1)
+    },
+
+    editTodo: function (todo) {
+      this.beforeEditCache = todo.title
+      this.editedTodo = todo
+    },
+
+    doneEdit: function (todo) {
+      if (!this.editedTodo) {
+        return
+      }
+      this.editedTodo = null
+      todo.title = todo.title.trim()
+      if (!todo.title) {
+        this.removeTodo(todo)
+      }
+    },
+
+    cancelEdit: function (todo) {
+      this.editedTodo = null
+      todo.title = this.beforeEditCache
+    },
+
+    removeCompleted: function () {
+      this.todos = filters.active(this.todos)
+    }
+  },
+
+  // a custom directive to wait for the DOM to be updated
+  // before focusing on the input field.
+  // http://vuejs.org/guide/custom-directive.html
+  directives: {
+    'todo-focus': function (el, value) {
+      if (value) {
+        el.focus()
+      }
+    }
+  }
+})
+
+// handle routing
+function onHashChange () {
+  var visibility = window.location.hash.replace(/#\/?/, '')
+  if (filters[visibility]) {
+    app.visibility = visibility
+  } else {
+    window.location.hash = ''
+    app.visibility = 'all'
+  }
+}
+
+window.addEventListener('hashchange', onHashChange)
+onHashChange()
+
+// mount
+app.$mount('.todoapp')

+ 4 - 5
examples/todomvc/index.html

@@ -58,12 +58,11 @@
 			<p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
 		</footer>
 
-		<script src="../../dist/vue.js"></script>
-		<script src="js/store.js"></script>
-		<script src="js/app.js"></script>
-		<script src="js/routes.js"></script>
 		<script>
-		  app.$mount('.todoapp')
+		// for testing
+		if (navigator.userAgent.indexOf('PhantomJS') > -1) localStorage.clear()
 		</script>
+		<script src="../../dist/vue.js"></script>
+		<script src="app.js"></script>
 	</body>
 </html>

+ 0 - 127
examples/todomvc/js/app.js

@@ -1,127 +0,0 @@
-/*global Vue, todoStorage */
-
-(function (exports) {
-
-	'use strict';
-
-	var filters = {
-		all: function (todos) {
-			return todos;
-		},
-		active: function (todos) {
-			return todos.filter(function (todo) {
-				return !todo.completed;
-			});
-		},
-		completed: function (todos) {
-			return todos.filter(function (todo) {
-				return todo.completed;
-			});
-		}
-	};
-
-	exports.app = new Vue({
-		// app initial state
-		data: {
-			todos: todoStorage.fetch(),
-			newTodo: '',
-			editedTodo: null,
-			visibility: 'all'
-		},
-
-		// watch todos change for localStorage persistence
-		watch: {
-			todos: {
-				handler: function (todos) {
-				  todoStorage.save(todos);
-				},
-				deep: true
-			}
-		},
-
-		// computed properties
-		// http://vuejs.org/guide/computed.html
-		computed: {
-			filteredTodos: function () {
-				return filters[this.visibility](this.todos);
-			},
-			remaining: function () {
-				return filters.active(this.todos).length;
-			},
-			allDone: {
-				get: function () {
-					return this.remaining === 0;
-				},
-				set: function (value) {
-					this.todos.forEach(function (todo) {
-						todo.completed = value;
-					});
-				}
-			}
-		},
-
-		filters: {
-			pluralize: function (n) {
-			  return n === 1 ? 'item' : 'items'
-			}
-		},
-
-		// methods that implement data logic.
-		// note there's no DOM manipulation here at all.
-		methods: {
-			addTodo: function () {
-				var value = this.newTodo && this.newTodo.trim();
-				if (!value) {
-					return;
-				}
-				this.todos.push({
-					id: todoStorage.uid++,
-					title: value,
-					completed: false
-				});
-				this.newTodo = '';
-			},
-
-			removeTodo: function (todo) {
-				this.todos.splice(this.todos.indexOf(todo), 1);
-			},
-
-			editTodo: function (todo) {
-				this.beforeEditCache = todo.title;
-				this.editedTodo = todo;
-			},
-
-			doneEdit: function (todo) {
-				if (!this.editedTodo) {
-					return;
-				}
-				this.editedTodo = null;
-				todo.title = todo.title.trim();
-				if (!todo.title) {
-					this.removeTodo(todo);
-				}
-			},
-
-			cancelEdit: function (todo) {
-				this.editedTodo = null;
-				todo.title = this.beforeEditCache;
-			},
-
-			removeCompleted: function () {
-				this.todos = filters.active(this.todos);
-			}
-		},
-
-		// a custom directive to wait for the DOM to be updated
-		// before focusing on the input field.
-		// http://vuejs.org/guide/custom-directive.html
-		directives: {
-			'todo-focus': function (el, value) {
-				if (value) {
-					el.focus();
-				}
-			}
-		}
-	});
-
-})(window);

+ 0 - 24
examples/todomvc/js/routes.js

@@ -1,24 +0,0 @@
-/*global app, Router */
-
-(function (app, Router) {
-
-	'use strict';
-
-	var router = new Router();
-
-	['all', 'active', 'completed'].forEach(function (visibility) {
-		router.on(visibility, function () {
-			app.visibility = visibility;
-		});
-	});
-
-	router.configure({
-		notfound: function () {
-			window.location.hash = '';
-			app.visibility = 'all';
-		}
-	});
-
-	router.init();
-
-})(app, Router);

+ 0 - 23
examples/todomvc/js/store.js

@@ -1,23 +0,0 @@
-/*jshint unused:false */
-
-(function (exports) {
-
-	'use strict';
-
-	var STORAGE_KEY = 'todos-vuejs-2.0';
-
-	exports.todoStorage = {
-		fetch: function () {
-			var todos = JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]');
-			todos.forEach(function (todo, index) {
-			  todo.id = index
-			});
-			exports.todoStorage.uid = todos.length;
-			return todos;
-		},
-		save: function (todos) {
-			localStorage.setItem(STORAGE_KEY, JSON.stringify(todos));
-		}
-	};
-
-})(window);

+ 0 - 9
examples/todomvc/package.json

@@ -1,9 +0,0 @@
-{
-  "private": true,
-  "dependencies": {
-    "director": "^1.2.0",
-    "vue": "^1.0.0",
-    "todomvc-common": "^1.0.1",
-    "todomvc-app-css": "^2.0.0"
-  }
-}