Gerard Sans (@gerardsans)
Spoken at 66 events in 23 countries
2-way databinding
2009
Component based view library
2013
Native Mobile Apps using React
2014
Progressive framework
2015
Web Components library
Ready for large Apps
Better Tooling (single-file-component)
New syntax shortcuts
2016
Performance improvements
Virtual DOM
Scoped slots
Streaming SSR
2017
TypeScript support
SSR improvements
Functional Components
ngrx
RxJS
TypeScript
Visual Code
Ionic
NativeScript
Apollo
GraphQL
Vuex
vue-loader
TypeScript
Nuxt
Ionic v4
NativeScript
Apollo
GraphQL
📦
// main.ts
if (environment.production) { enableProdMode(); }
platformBrowserDynamic().bootstrapModule(AppModule);
// app.module.ts
@NgModule({
declarations: [AppComponent],
imports: [ BrowserModule,BrowserAnimationsModule],
bootstrap: [AppComponent]
})
export class AppModule { }
// app.component.ts
@Component({
selector: 'app-root',
template: `<h1>Hello World!</h1>`,
styles: [`h1 { color: #c0ffee; }`]
})
export class AppComponent {}
// index.js
Vue.config.productionTip = false
new Vue({
el: '#app',
template: '<App/>',
components: { App }
})
// App.vue
<template><h1>Hello World!</h1></template>
<script>
export default { name: "app" };
</script>
<style scoped>h1 { color: #c0ffee; }</style>
Feature | Angular | Vue |
---|---|---|
Interpolation | {{todo.text}} | {{todo.text}} |
conditional | *ngIf="exp" | v-if="exp" |
visibility | [hidden]="!exp" | v-show="exp" |
listings | *ngFor="let todo of todos" | v-for=”todo of todos” |
2-way | [(ngModel)] ="exp" | v-model="exp" |
events | (click)="exp" | @click="exp" |
// <todo [id]="todo.id" [text]="todo.text" [done]="todo.done"></todo>
@Component({
selector: 'todo',
template: `
<mat-list-item (click)="onTodoClick()">
<mat-checkbox class="checkbox" [checked]="done"></mat-checkbox>
<div class="todo-text">{{text}}</div>
</mat-list-item>`
})
export class TodoComponent {
@Input() id: number;
@Input() text: string;
@Input() done: boolean = false;
};
<!-- <todo :text="todo.text" :done="todo.done"/> -->
<template>
<v-content>
<v-list-tile-action>
<v-checkbox :input-value="done"></v-checkbox>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title>{{text}}</v-list-tile-title>
</v-list-tile-content>
</v-content>
</template>
<script>
export default {
name: "todo",
props: ["text", "done"],
};
</script>
// <add-todo (newTodo)="AddTodo($event)"></add-todo>
@Component({
selector: 'add-todo',
template: `
<mat-form-field (keydown.enter)="addTodo(todo)">
<input #todo placeholder="Add a new todo">
</mat-form-field>`
})
export class AddTodoComponent {
@Output() newTodo = new EventEmitter();
addTodo(todo){
this.newTodo.emit(todo);
}
};
// <add-todo v-on:new="newTodo"/>
<template>
<v-text-field v-model="newtodo" @keydown.enter.native="add"/>
</template>
<script>
export default {
name: 'add-todo',
data() { return { newtodo: ''} },
methods: {
add() {
this.$emit("new", this.newtodo);
}
}
}
</script>
// app.module.ts
@NgModule({
declarations: [
AppComponent, AddTodo, TodoList, Todo
],
imports: [
BrowserModule,
BrowserAnimationsModule,
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
// App.vue
<script>
import AddTodo from "./components/AddTodo";
import TodoList from "./components/TodoList";
import Filters from "./components/Filters";
export default {
name: "app",
components: {
AddTodo,
TodoList,
Filters
},
};
</script>