In this post we’ll take a look at upgrading VueJS. We have a cool tutorial about Vue.js but alas, JavaScript moves in Internet time – which means some of the information has become dated already. Well fear not! The tutorial is getting updated, and this post is a chronicle of what you might encounter when completing your own migration path from an earlier version to 1.0.0 or a release candidate of 1.0.0. We will be using 1.0.0-rc2.
Creating A View Instance
The first thing we did was to create a view instance. Testing out the code from the tutorial with our new build of Vue appears to work just fine. No warnings, and a fresh Vue instance in the browser as we see here, so nothing to change or worry about.
Two Way Data Binding
Next up on the agenda was to create some two way data bindings. On updating the source code to a release candidate of 1.0.0, we encountered a clean slate in the console window and no errors. Testing out the two way data binding in the browser was working just fine, so no need to make any changes.
Displaying Lists
We now take a look at displaying lists with Vue using the latest build and we encounter our first few errors. Let’s see.
We have some very helpful warnings in the console that will guide us on how to resolve our issues.
- [Vue warn]: Failed to resolve directive: repeat
Let’s update our code to fix the problems. The syntax for v-repeat has changed to v-for. In order to get our code work properly, we need to make this change.
Old
1 2 3 |
<ul class="nav nav-pills"> <li v-repeat="library: libraries" class="active"><a href="#">{{ library }}</a></li> </ul> |
New
1 2 3 |
<ul class="nav nav-pills"> <li v-for="library in libraries" class="active"><a href="#">{{ library }}</a></li> </ul> |
With that quick update, everything is now working again.
Moving further along we had added some functionality to add or delete a JavaScript Library. It looks like this one does cause some errors.
- [Vue warn]: Invalid expression. Generated function body: scope.click:scope.addLibrary
- TypeError: expParser.parse(…) is undefined
var fn = expParser.parse(expression).get - [Vue warn]: You are setting a non-existent path “newlibrary” on a vm instance. Consider pre-initializing the property with the “data” option for more reliable reactivity and better performance.
Lets see if we can figure out how to fix these… (hacking in the sandbox) … turns out this is a pretty easy fix.
Old
1 2 3 |
<input class="form-control" type="text" placeholder="Type the library name here, then click the button below." v-model="newlibrary"> <button class="btn btn-info" v-on="click: addLibrary">Click to add library</button> <button class="btn btn-danger" v-on="click: deleteLibraries">Click to delete all libraries</button> |
New
1 2 3 |
<input class="form-control" type="text" placeholder="Type the library name here, then click the button below." v-model="newlibrary"> <button class="btn btn-info" v-on:click="addLibrary">Click to add library</button> <button class="btn btn-danger" v-on:click="deleteLibraries">Click to delete all libraries</button> |
This is another welcome change. It does in fact appear much more readable to me. Now we can see that the event action is moved out of the attribute value and attached to the v-on directive. With regard to that third error listed above, we simply add the newlibrary property to the data object like the warning asked and it did in fact make the error go away.
1 2 3 4 |
data: { libraries: ['angular.js', 'd3', 'node', 'jquery'], newlibrary: '' }, |
Updating Event System Syntax
With our new found knowledge from the prior step, we can now update the parts of the tutorial that deal with events.
Filtering
On testing the filtering with VueJs portion of the tutorial, it does appear we are getting some warnings.
We have already seen these however so they should be easy to fix.
Old
html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<div id="myvueinstance" class="container"> <div class="row">UI List Element</div> <input type="text" class="form-control" v-model="filterkey"> <table class="table table-hover"> <thead> <tr> <th><a href="#" v-on="click: sortvia('id')">id</a></th> <th><a href="#" v-on="click: sortvia('framework')">Framework</a></th> </tr> </thead> <tbody> <tr v-repeat="frameworks | filterBy filterkey | orderBy sortparam reverse"> <td>{{ id }}</td> <td>{{ framework }}</td> </tr> </tbody> </table> </div> |
js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
var viewmodel = new Vue({ el: '#myvueinstance', data: { sortparam: '', reverse: false, fitlerkey: '', frameworks: [ {id: '001', framework: 'angular'}, {id: '002', framework: 'd3'}, {id: '003', framework: 'node'}, {id: '004', framework: 'jquery'}, {id: '005', framework: 'reveal.js'}, {id: '006', framework: 'impress.js'}, {id: '007', framework: 'backbone.js'}, {id: '008', framework: 'meteor.js'}, {id: '009', framework: 'express'}, {id: '010', framework: 'moment'}, {id: '011', framework: 'underscore'}, {id: '012', framework: 'gulp'}, {id: '013', framework: 'react'}, {id: '014', framework: 'ghost'}, {id: '015', framework: 'sweetalert'}, {id: '016', framework: 'select2'}, ] }, methods: { sortvia: function (sortparam) { this.reverse = (this.sortparam == sortparam) ? !this.reverse : false; this.sortparam = sortparam; } } }); |
New
html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<div id="myvueinstance" class="container"> <div class="row">UI List Element</div> <input type="text" class="form-control" v-model="filterkey"> <table class="table table-hover"> <thead> <tr> <th><a href="#" v-on:click="sortvia('id')">id</a></th> <th><a href="#" v-on:click="sortvia('framework')">framework</a></th> </tr> </thead> <tbody> <tr v-for="framework in frameworks | filterBy filterkey | orderBy sortparam order"> <td>{{ framework.id }}</td> <td>{{ framework.framework }}</td> </tr> </tbody> </table> </div> |
js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
var viewmodel = new Vue({ el: '#myvueinstance', data: { sortparam: '', fitlerkey: '', order: 1, frameworks: [ {id: '001', framework: 'angular'}, {id: '002', framework: 'd3'}, {id: '003', framework: 'node'}, {id: '004', framework: 'jquery'}, {id: '005', framework: 'reveal.js'}, {id: '006', framework: 'impress.js'}, {id: '007', framework: 'backbone.js'}, {id: '008', framework: 'meteor.js'}, {id: '009', framework: 'express'}, {id: '010', framework: 'moment'}, {id: '011', framework: 'underscore'}, {id: '012', framework: 'gulp'}, {id: '013', framework: 'react'}, {id: '014', framework: 'ghost'}, {id: '015', framework: 'sweetalert'}, {id: '016', framework: 'select2'}, ] }, methods: { sortvia: function (sortparam, order) { this.order = this.order * -1; this.sortparam = sortparam; } } }); |
With the updated code, all errors are gone and the test subject is functional again. Do the old “stare and compare” of the old versus new code above to see if you can spot what changed. Then read up on filterBy and orderBy and you’ll be good to go.
Custom Filters
The code which was used for the custom filters section of the tutorial seems to be working just fine with no errors. A quick scan seems to indicate these work as they did before, but it’s worth reading up of course on the latest docs.
Components
The Components code is working on the latest build of Vue.js, so that is good.
Component Props
Component Props also seem to be working nicely with no modifications to the original markup.
Custom Directives
Lastly, Custom Directives do appear to work just fine as well with the latest VueJS code.
Upgrading VueJS Summary
In this post we went through our original snippets and tutorials about Vue.js and updated some of the syntax to be compatible with the very latest versions of Vue.js. It really wasn’t that painful, and the changes that I found seemed to be well worth it in terms of better readability of the code. We found that v-repeat is now v-for, the events system changed a little bit, and a few other minor things. Of course this is only scratching the surface, but you can check the release notes and github to stay current with all that is new. Another great feature built into Vue.js is that you can simply download the development version that includes full warnings and debug mode and apply it to your existing markup in a test environment. Once you become satisfied that you have updated everything you need to, and warnings go away, you can probably move to production as well.