Last active
August 23, 2021 10:14
-
-
Save chrisvfritz/9e5f2d6826af00fcbace7be8f6dccb89 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- | |
In Vue, we use v-model for all form bindings, while | |
Knockout maintains separate binding types, such as | |
textInput, checked, and options. In some cases, | |
such as for an input of type "range", Knockout | |
simply doesn't have an equivalent two-way binding | |
helper and the more verbose value and valueUpdate | |
must be used. | |
--> | |
<div id="app"> | |
<input data-bind="textInput: newTodoText, event: { keypress: addTodo }"> | |
<ul data-bind="foreach: todos"> | |
<!-- | |
Inside of the foreach, a new scope is implicitly | |
created and we must reference $parent or $root to | |
access other scopes. In contrast, Vue maintains | |
the root scope and allows you to explicitly name | |
any nested scopes, so that it's always clear | |
what data you're accessing. | |
--> | |
<li> | |
<span data-bind="text: title"></span> | |
<button data-bind="event: { click: $root.removeTodo }"> | |
X | |
</button> | |
</li> | |
</ul> | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var TodoList = function () { | |
var self = this | |
self.todos = ko.observableArray([]) | |
self.newTodoText = ko.observable('') | |
self.addTodo = function (_, event) { | |
// Since it's such a common use case, it's worth | |
// noting that Knockout lacks native keyCode | |
// modifiers. This means it's necessary to either | |
// detect the keyCode here, thus coupling addTodo | |
// to the specific context it's called in, as we | |
// do below, or go through the tedious process of | |
// declaring a new bindingHandler. | |
if (event.keyCode === 13 && self.newTodoText()) { | |
self.todos.push({ title: self.newTodoText() }) | |
self.newTodoText('') | |
} | |
// Since event handlers in Knockout will interfere | |
// with each other by default, we must explicitly | |
// return true to avoid breaking the input. | |
return true | |
} | |
self.removeTodo = function (todo) { | |
// Instead of making it easy to pass arguments | |
// to a method, Knockout implicitly passes the | |
// current scope as the first argument then adds | |
// a proprietary method to observable arrays so | |
// that manipulating them is easier. | |
self.todos.remove(todo) | |
} | |
} | |
ko.applyBindings(new TodoList(), document.getElementById('app')) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div id="app"> | |
<!-- | |
Vue uses separate directives for different kinds of | |
binding, such as v-model for two-way input binding, | |
v-on for events, and v-for to repeat elements. | |
--> | |
<input v-model="newTodoText" v-on:keyup.enter="addTodo"> | |
<ul> | |
<!-- | |
Vue prefers to explicitly name new variables, rather | |
than implicitly creating new scopes. | |
--> | |
<li v-for="(todo, index) in todos"> | |
{{ todo.title }} | |
<!-- | |
In general, Vue tries its best to act in very | |
unsurprising ways. One example of this is that | |
event callbacks in Vue behave exactly like they do | |
outside of Vue. In Knockout however, it's | |
surprisingly cumbersome to just pass an argument | |
to a method. | |
--> | |
<button v-on:click="removeTodo(index)">X</button> | |
</li> | |
</ul> | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
new Vue({ | |
el: '#app', | |
// Instead of wrapping reactive data in observable | |
// objects, Vue knows what to make reactive by | |
// having it declared in the `data` option | |
data: { | |
todos: [] | |
newTodoText: '', | |
}, | |
// Instead of adding everything directly to the | |
// instance, Vue has specific options to help | |
// organize your components. Any methods are | |
// registered under the "methods" options, computed | |
// properties are registered under "computed", etc. | |
methods: { | |
addTodo: function () { | |
// In Knockout, reactive data acts mostly like | |
// plain JavaScript objects, except getting | |
// and setting are done through a function call. | |
// In Vue, there's no special syntax for getters | |
// and setters. | |
if (this.newTodoText) { | |
this.todos.push({ title: this.newTodoText }) | |
this.newTodoText = '' | |
} | |
}, | |
removeTodo: function (index) { | |
this.todos.splice(index, 1) | |
} | |
} | |
}) |
First!
NOT!
I feel like this comment,
Inside of the foreach, a new scope is implicitly
created and we must reference $parent or $root to
access other scopes. In contrast, Vue maintains
the root scope and allows you to explicitly name
any nested scopes, so that it's always clear
what data you're accessing.
is unfair, knockout does have a way of maintaining scope, and will use it frequently,
<ul data-bind="foreach: { data: todos, as: "todo" }">
Nice! 👍
As I'm new to Vue and a rather old hand at Knockout this was highly useful to me. Thanks so much for putting this together!
data: {
todos: []
newTodoText: '',
},
There should be a coma between todos:[] and netTodoText
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The data object in the Vue js example has a missing comma. Looks like you switched the order of data.todos and data.newTodoText, but forgot to change the position of the comma.