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.
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)
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
we change the message it'll update the template: <script> var vm = new Vue({ el: '#app', data: { message: 'Hello World!' } }) // here, or in your console: vm.message = 'Goodbye World!' // ... template will update
can be represented as @click <a @click="doThing">click me</a> • v-bind:href can be represented as :href <my-component :propertyName="propertyValue"></my-component>
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.
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)
not an object: Vue.component('whatever', { // ... data: function () { return { propName: true } } }) • If your template is in HTML, you may have to use <td is="todo-item"></td>
as a "prop" on the component instance— sort of like a constructor property. <my-component message="Do it!"></my-component> Vue.component('banner', { props: ['message'], template: '<li>{{ message }}</li>' })
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) { // ... })
<h2>Title of child</h2> <slot> Fallback content here </slot> </div> <!-- Parent component passes data to slot --> <div> <h1>Title of parent</h1> <my-component> <p>This is some original content</p> </my-component> </div>
<slot name="header"></slot> </header> <main> <slot></slot> </main> </div> <!-- parent --> <app-layout> <h1 slot="header">Here might be a page title</h1> <p>A paragraph for the main content.</p> </app-layout>
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!"