What is Vue? It's a JavaScript framework. It has a Virtual DOM and composable, reactive components. Its core is small and works well with companion libraries for routing, global state, and HTTP requests. It's light, fast, and flexible.
How is it different from ... • jQuery? (jQuery is not a framework, it's a library) • Knockout? (more modern, lifecycle hooks, better component management, more active development) • AngularJS? (simpler, faster, less opinionated, more flexible, one-way data binding) • React? (faster, simpler tooling, and prefers HTML/CSS over JavaScript for templates) • Ember? (simpler, less opinionated, no need for Ember objects, faster)
What did that just do? • Create a Vue instance that's bound to a div with an id of "app" • Interpret the contents of that div as its template • Read Mustache-style syntax ({{ message }}) and in response echo out the contents of the "message" variable
Reactive data The data in the previous example is "reactive"—if we change the message it'll update the template: <br/>var vm = new Vue({<br/>el: '#app',<br/>data: {<br/>message: 'Hello World!'<br/>}<br/>})<br/>// here, or in your console:<br/>vm.message = 'Goodbye World!'<br/>// ... template will update<br/>
What else can we do in our templates? • You could write your own render functions and even use JSX • mustache: {{ propertyName }} • v-bind for attributes: • expressions: {{ signedUp ? 'Cancel' : 'Sign up' }},
Interlude: shortcuts Commonly used directives often have shortcuts. • v-on:click can be represented as @click click me • v-bind:href can be represented as :href
Computed properties Like decorators with magical listeners built in. Any property based on the content of another. What's different between a method and a computed property? Methods run every they're re-requested; computed properties are cached based on their dependencies, and only change when their dependencies change.
Computed properties (continued) Are "get"-only by default, but can be both get and set: // ... computed: { fullName: { // getter get: function () { return this.firstName + ' ' + this.lastName }, // setter set: function (newValue) { var names = newValue.split(' ') this.firstName = names[0] this.lastName = names[names.length - 1] } } } // ... // @todo make this real example
A few caveats (with Vue's reactive model) • If you set props on a instance after it starts up, those props won't be reactive (vm.newProperty = 'please-track-me') • If you're setting a prop of an array/object, you have to use Vue.set in order for it to be tracked/reactive Vue.set(myArray, itemIndex, value)
Defining and using Vue components Each component is a little Vue instance. Defining a global component named "todo-item": Vue.component('todo-item', { props: ['todo'], template: '{{ todo.text }}' })
Defining and using Vue components You can also define components locally: var TodoItem = { props: ['todo'], template: '{{ todo.text }}' } new Vue({ // ... components: { 'todo-item': TodoItem } })
Vue component caveats • data property must be a method, not an object: Vue.component('whatever', { // ... data: function () { return { propName: true } } }) • If your template is in HTML, you may have to use is="todo-item">
Using a new Vue instance as an event bus var bus = new Vue() // in component A's method bus.$emit('id-selected', 1) // in component B's created hook bus.$on('id-selected', function (id) { // ... })
Mixins Like mixins in Ruby or traits in PHP; bring in a group of properties. // define a mixin object var myMixin = { created: function () { this.hello() }, methods: { hello: function () { console.log('hello from mixin!') } } } // define a component that uses this mixin var Component = Vue.extend({ mixins: [myMixin] }) var component = new Component() // -> "hello from mixin!"