Difference between revisions of "VueJS"
(→Router specific notes) |
m (→Router specific notes) |
||
Line 8: | Line 8: | ||
== Router specific notes == | == Router specific notes == | ||
− | One thing I found very difficult to figure out as a Vue noob was how to have router components containing live data such as watchers that respond to changes in the global state. The reason this was difficult to set up is that the component referred to in the router needs to be a proper component (Vue instance) not just an object containing a template instance. This means they're defined with ''Vue.extend'', but that only returns a prototype that needs to be instantiated within the context of a DOM element in the page | + | One thing I found very difficult to figure out as a Vue noob was how to have router components containing live data such as watchers that respond to changes in the global state. The reason this was difficult to set up is that the component referred to in the router needs to be a proper component (Vue instance) not just an object containing a template instance. This means they're defined with ''Vue.extend'', but that only returns a prototype that needs to be instantiated within the context of a DOM element in the page, so it seems that the router is instantiating the component onto the element automatically. |
− | Here's an example. A child route (''PropertyBuy'') can have any part of the main shared state in its template such as ''<nowiki>{{bids}}</nowiki>'' which will have a live connection to the corresponding properties in ''state''. Watchers can be set etc | + | Here's an example. A child route (''PropertyBuy'') can have any part of the main shared state in its template such as ''<nowiki>{{bids}}</nowiki>'' which will have a live connection to the corresponding properties in ''state''. Watchers can be set in its code etc. |
<source lang="js"> | <source lang="js"> | ||
Line 40: | Line 40: | ||
bids: function( val ) { console.log( 'change detected' ); } | bids: function( val ) { console.log( 'change detected' ); } | ||
} | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
}); | }); | ||
Revision as of 14:14, 25 February 2017
It's becoming more and more critical in recent months that I get up to speed with a decent JavaScript framework that supports Single Page Applications. I've built a few simple SPA's before one without a framework, and the others using Backbone. Backbone is getting a bit dated now, and I need to build an SPA that is considerably more complicated than those I've made before.
After a lot of looking around I've settled on the Vue2 framework which is similar to React but has a simpler learning curve (it's practically as simple as jQuery to get started with by just including the script and writing code, or the next step, building with the simple template) while also scaling very well - in fact in virtually all tests it's shown to be faster and more scalable than React. Another popular option is AngularJS which shares a lot of similarities with Vue - both React and Angular have served as strong inspiration for the development of Vue. As is the case for React, Angular has a steep learning curve which is one of the main reasons for me to prefer Vue - I like the idea of an efficient minimalist system that is very easy to get started with and yet also very scalable. Angular is also very "opinionated" which means that it dictates a lot about the way you should structure you're application. Vue is much more flexible, but also offers the Webpack template if you want an entire tool-chain and structure predefined for you. Angular2 is much more efficient, but Vue still beats it, and in terms of size, Vue's 23KB is hard to beat (actually it is beatable though - RiotJS is only 10KB, but I feel that the massive efficiency gains of Vue are worth the extra few KB).
Notes
- It may be good to use Weex templates for cross-platform native rendering
- "Vue has a clearer separation between directives and components. Directives are meant to encapsulate DOM manipulations only, while components are self-contained units that have their own view and data logic. In Angular, there’s a lot of confusion between the two."
Router specific notes
One thing I found very difficult to figure out as a Vue noob was how to have router components containing live data such as watchers that respond to changes in the global state. The reason this was difficult to set up is that the component referred to in the router needs to be a proper component (Vue instance) not just an object containing a template instance. This means they're defined with Vue.extend, but that only returns a prototype that needs to be instantiated within the context of a DOM element in the page, so it seems that the router is instantiating the component onto the element automatically.
Here's an example. A child route (PropertyBuy) can have any part of the main shared state in its template such as {{bids}} which will have a live connection to the corresponding properties in state. Watchers can be set in its code etc.
// The main state accessible by all components
var state = {
bids: 'foo',
};
// Instantiate the router with no routes before the components are defined
var router = new VueRouter({
routes: []
});
// A template-only router component
const Property = {
template: '#tpl-property'
};
// Another template-only router component
const PropertySell = {
template: '#tpl-property-sell'
};
// A component with dynamic view depending on global state
const PropertyBuy = Vue.extend({
template: '#tpl-property-buy',
data: function() { return state; },
watch: {
bids: function( val ) { console.log( 'change detected' ); }
}
});
// Now that the components are defined we add the routes
router.addRoutes([
{ path: '/property', component: Property,
children: [
{ path: 'buy', component: PropertyBuy },
{ path: 'sell', component: PropertySell }
]
}
]);
// Now we can mount the app
var app = new Vue({router}).$mount('#app');
See also
- Awesome Vue - big list of examples and tutorials
- VueComponents.com - a lot of nice clear examples
- The Vue router
- Building large-scale apps