My first open source project using Vue.js
Last year I decided to start working on version 2.0 of WebIssues, an open source, multi-platform system for issue tracking and team collaboration. The first version that I wrote in 2005 was a desktop application written in C++ with a PHP back-end. In 2010 I added a web interface, also written in PHP. At that time WebIssues gained some visibility and received very positive feedback. In 2014 I started working on other, commercial side projects, but last year I decided to return to open source development.
At that time it became clear that JavaScript is the future of application development. Platforms such as Electron blurred the lines between web applications and desktop applications. So I decided that version 2.0 of WebIssues will have a completely new user interface based on one of the modern JavaScript UI frameworks.
The most natural choice was React. However, I came across some articles praising Vue.js and I decided to give it a try. Honestly, it was just a shot in the dark, as I had almost no technical knowledge about any of these frameworks. I suspect that the idea that Vue was initially created by a “lone rider”, compared to the corporate background of React, somehow resonated with me 😉.
The prototype
The first prototype was basically a large HTML file with Bootstrap and some custom CSS. Using Bootstrap allowed me to quickly test various ideas and focus on the layout and responsiveness. The result looked like this:

The prototype used jQuery to simulate dynamic elements, so it could feel more “alive”, but it was just a few lines of JavaScript.
The second phase was splitting this large HTML file into a few basic Vue components: the header, sidebar, toolbar and grid. And that’s where Vue proved its power for the first time. The fact that Vue single file components use HTML for templates makes it very easy to copy existing markup and turn it into the skeleton of a component. This is really great for quick prototyping and testing various ideas.
Obviously, in order to make these single file components work in the browser, I had to compile them. It’s easy to create the scaffolding using vue-cli, but it bothered me that I didn’t understand what was going on under the hood. So I spent a few days trying to figure it out and I documented what I learned in this article about configuring webpack to bundle Vue components.
As a result, I had the same prototype, but instead of one large HTML file, it consisted of a few Vue components. I removed jQuery, so the next step was restoring the functionality of dynamic elements, such as the dropdown button. This allowed me to learn how to implement interaction logic in Vue and to write another article which explained the basics of Vue to jQuery developers.
Vuex store
It quickly turned out that components had to interact with other components. For example, selecting a folder in the sidebar should update the caption in the toolbar. At first I did it using events and properties, but I quickly realized that this solution wouldn’t scale very well. I decided to use a Vuex store, even though it was still just an early prototype.
State management libraries seem difficult and challenging to many developers. However, Vuex turned out to be quite easy to understand and start working with. Using shared state and actions was in fact much more convenient than passing events and properties up and down the components tree.
I recommend using Vuex in almost every Vue project, unless it’s just a very simple widget. Start using it from the beginning, even at the prototype stage; it will save you a lot of time later. Also it’s best to divide the store into modules from the start and to avoid putting any state directly in the root of the store. I use a dedicated module called “global” to store such general purpose state.
Keep in mind that using Vuex doesn’t mean that you have to put every piece of state and the entire logic in the store. For example, WebIssues has dozens of forms and most of them contain just a few simple fields. In such case I prefer to keep the state and logic in the Vue components. I only use Vuex to store data that need to be shared between components, and data that need to be stored longer than the component’s lifetime. Also if the logic of a component becomes complex, it’s probably a good idea to separate it from the presentation and move it to a Vuex module.
Routing
In a simple website or application there are a few components which can be mapped directly to different URLs using a router. In WebIssues things are a bit more complicated. Some URLs correspond to the state of the main components, for example the selected folder. Other URLs trigger opening a modal window with some dynamically loaded content. So instead of using the standard vue-router library, I decided to write a very simple utility which listened to the hashchange
event and dispatched an action in the Vuex store. Generally, routing is often very tightly coupled to the application state and it’s not just a matter of swapping components. I wrote more about it in this article.
PHP forms
When I had the list of issues and issue details working, it was time to start implementing all the forms for adding, editing and deleting various pieces of information. They were already implemented in PHP, so it was just a matter of rewriting them one by one using Vue. Then I had this crazy idea that instead of rewriting these forms, I could leave them on the server side and just load the generated HTML using AJAX requests and inject that markup into a Vue component. The proof of concept worked very well and I described it here.
If my goal was to release WebIssues 2.0 as soon as possible, this would be a perfect solution. But without any pressure from clients or shareholders, I didn’t have to hurry. I came to the conclusion that eventually I will have to port everything to Vue, so I could just do it from the start instead of splitting this work into two steps. So I abandoned the first prototype and started another attempt.
The current version
I gave myself some time to rethink everything, including the initial UI design. I decided to remove the side panel entirely and replace it with dropdown filters in the toolbar. The result looks like this:

Recently I moved the source code of WebIssues from SourceForge to GitHub (you can find it here). At the moment all issue operations are implemented and managing projects and folders is also completed. I still have to implement the remaining administration modules. I’m also planning to start working on a desktop version using Electron. My goal is to be able to compile both the web version and the desktop version from the same source code. They will have mostly the same UI and the Electron version will have some additional features such as client-side caching for improved performance.
Now I know Vue well enough that I can say without hesitation that it turned out to be a great choice. It’s so simple that I could start building a functional prototype in a matter of days. On the other hand, it’s powerful enough to efficiently build complex applications using its advanced features, for example custom mixins.
In case you’re curious, I don’t have any particular time frame for releasing WebIssues 2.0. The competition in issue tracking software is now much stronger than 10 years ago, so it’s very likely that it won’t get as much traction as its predecessor. But now I treat an open source project more like a sandbox, to test new ideas and learn new technology, without the pressure and constraints that come with commercial projects. I wrote more about the benefits of having such sandbox in a separate article.
✉️ Subscribe to CodeBurst’s once-weekly Email Blast, 🐦 Follow CodeBurst on Twitter, view 🗺️ The 2018 Web Developer Roadmap, and 🕸️ Learn Full Stack Web Development.