Step 2: Data Architecture

This entry is part of Vue.js Application Tutorial - Creating a Simple Budgeting App with Vue

This is part 2 of an 18 part series titled Vue.js Application Tutorial - Creating a Simple Budgeting App with Vue. It is highly recommended that you read the series in order, as each section builds on the last.

  1. Step 0: Intro
  2. Step 1: Planning Your Application
  3. Step 2: Data Architecture
  4. Step 3: Setup & Project Structure
  5. Step 4: Create & View Accounts
  6. Step 5: Edit & Delete Accounts
  7. Step 6: Adding LocalStorage to our Vue.js Application
  8. Step 7: Interlude & Refactor
  9. Step 8: Budgeting
  10. Step 9: Racing Through Budgets
  11. Step 10: Styling & Navigation
  12. Step 11: Finishing Budgets with Vue.js Dynamic Components
  13. Step 12: Planning for Transactions
  14. Step 13 - All Aboard the Transaction Train
  15. Step 14 - User Testing

The next entry is expected to be published on 03 August 2017. Sign up using the form at the bottom of this post to receive updates when posts are published.


The biggest decision to make with our data structure is how the different objects relate to one another. Vue.js focuses on reactive data, but largely leaves modeling the data to the programmer.

For our purposes, we will persist our data in local storage. We will only ever use the app on one machine, and not sending data to the Internet avoids a lot of security issues. It also makes the application easier to develop - our copy of the data is the only copy and we don't have to worry too much about keeping it in sync. Still, many of the principles of working with local storage are the same as working with an Internet backend.

Since we don't have a backend that uses a relational database, it is up to us if we want to borrow some relational features or keep our connections distinct. Our data is relatively simple and straight forward. We are building a single user application. And it will not grow exceptionally large. So we could rely on a simple object/JSON structure:

transactions = [
 {
 desc: 'bought new ear plugs',
 date: '2017-02-08',
 category: 'Spending Money'
 },
 ...
];
budget = [
 {
 category: 'Spending Money',
 month: '2017-02',
 amount: '200'
 },
 ...
];

When a user wants to view a list of categories, we have to iterate through every transaction and create a set of unique category names. If we change a category name we have to change each transaction with that category, and also each budget object. We can create a separate list of category objects, to store their additional data, but that doesn't solve the second problem.

Since the relationship between categories, budgets, accounts, and transactions is central to our applications we will take a simplified relational approach. We will reference objects by their ID in other objects.:

transactions = {
 'ijd4ijdoi3': {
 desc: 'bought new ear plugs',
 date: '2017-02-08',
 category: '4ijoidjie'
 },
 ...
};
categories = {
 '4ijoidjie': {
 name: 'Spending Money',
 type: 'Checking'
 }
 ...
};
budget = {
 'ijd3ij4id': {
 category: '4ijoidjie',
 month: '2017-02',
 amount: '200'
 },
 ...
};

We will create unique IDs for each record we are storing, and use those IDs as foreign keys. Instead of storing the category directly in the transaction and budget objects, we reference it using its ID. Now we already have a list of categories defined when we need it. And changing a category name is as simple as changing a single category object. However, when we are showing the list of transactions each with its category we must query the categories to figure out the name attached to each ID.

This is an extremely simplified breakdown of relational databases versus a simple object store. While I believe that long-term there would be a benefit to using a full scale relational database for this application, it introduces problems and libraries that are far outside the scope of this tutorial.

Continue to step 3, Setup & Project Structure

Originally published on

Last updated on