The power Of Vue

“Another year, another framework.”

Thinking this while building a quick site for a friend – and doing it easily, with Vue. We’ve been using Vue at work for nearly two years now, but I hadn’t done a personal project from scratch using it until now.

In the last decade, while software has (supposedly) engorged itself on the world, frameworks for everything have grown at every part of the ecosystem. Most all promise some sort of performance boost, “dynamic rehydration of eventually-consistent user-generated content” (whatever that means), or a level of prestige that comes with using the same Framework as facebook or uber or any other now- or future-extant company someone may build thinking it solves an imagined problem. For some people, these problems are real. Some applications – finance, governance, ultra-niche b2b shipping companies dealing with metric tonnes a day – require an extreme consideration of how components are built, how they’re served, and who they’re meant to help. But for most, the overhead of tooling and building in these frameworks is unnecessary and for the uninitiated it’s downright exclusive. I avoid React, backbone, ember, angular, meteor as much as I can. I’ve worked with companies that use these, I’ve built side projects in these, but I’ve never fully understood how they worked and the daunting language around each of them never helped.

After years of sticking with very vanilla front end implementations – build it in HTML and let the server do everything else – it feels like Vue has the power to make building sites fun, and to bring the ability to make the next great thing (actually great, like something for “wind ranchers” in Texas) more accessible to more developers.

The basics are quick, the parts are intuitive, and the community is great. A fully developed web experience is about 4MB, with most of that being fucking font-awesome icons. It can do everything react can do, it can do everything jquery can do, and it can do it all in a way that makes sense at a glance. There’s still some funkiness getting it into production, but it’s well worth it!

Getting started is easy:

vue create superSickSite

Step through the steps, add vuex to handle persisting data and vue-router to handle a bunch of pages, and it will output the bones of a fully-formed app. The basic directory structure looks like this:

.
├── babel.config.js
├── package.json
├── public
│   ├── authenticity.conf
│   ├── docker-compose.yml
│   ├── favicon.ico
│   └── index.html
└── src
    ├── App.vue
    ├── assets
    ├── components
    ├── config
    ├── main.js
    ├── router
    ├── store
    └── views

With the most important part being the src directory, where all of the application parts live:

src/
├── App.vue
├── assets
│   └── scss
├── components
│   ├── Footer.vue
│   ├── Nav.vue
│   └── home
├── main.js
├── router
│   └── index.js
├── store
│   └── index.js
└── views
    ├── About.vue
    ├── Form.vue
    └── Home.vue

The general gist is that views and components are where 90% of the development has to happen, with routes defined in router, data persisted in store, the app’s skeleton is set in App.vue and main.js is the interface to the world. That alone can be a lot to take in, so sit with it. Components and views are most of the front end experience for users, so it makes sense that this is where a lot of time and effort will get spent. The App file is a home for everything, where it all gets defined. And main.js is where it meets the world, and looks kind of like a normal javascript server.

A component is another amazing invention – a self-contained unit of front end. It has a place to define a bunch of functions to use throughout, it has a way to update data constantly and performantly, and you can do this at a number of different points along the page load path (a lifecycle). This is a stripped down file just pulled from a project:

<template>
<div id="cards">
    Here we go
</div>
</template>

<script>
import {
    mapState
} from 'vuex'


export default {
    name: 'Cards',
    data() {
        return {
            cardsData: [],
            cards: {},
            updated: [],
            sort: {
                field: '',
                desc: true
            },
            limit: 5,
            page: '',
            isActive: this.$route.hash.split('#')[1],
            isClicked: [],
            opened: false
        }
    },
    computed: {
        sorted(arr) {},
        split() {}
    },
    beforeMount() {
        this.page = window.location.href
    },
    mounted() {},
    methods: {
        test(url) {},
        open(card) {},
        showMore(i) {},
        showLess(i) {},
        groupBy(groupField, arr) {},
        sortCards(field) {},
        randomize() {},
        containsObject(obj, list) {},
        addCount(card, dir, index) {},
        sendData() {}
    },
    filters: {
        truncate: function(text, length, suffix) {},
    }
}
</script>

The most important things to note are a structure like this, where everything is defined in the module being exported (default):

<template>
<div id="cards">
    Here we go
</div>
</template>

<script>
import {
    mapState
} from 'vuex'


export default {
    name: 'Cards',
    data() {},
    computed: {},
    created() {},
    beforeMount() {},
    mounted() {},
    methods: {},
    filters: {}
}
</script>

Here there are some “hooks” into the lifecycle – beforeMount(), created(), mounted(); and there are some places to define normal javascript: methods and filters. data is where we defined properties and variables that are used throughout the component, and computed is a place to put functions that can return realtime data super seamlessly. I use computed to handle sorting a lot of categories and updating the HTML elements, and make API calls in mounted().

At the top of the script, vuex pulls in something called mapState, which we can use to persist data for the user. In the functions, we can reference the props (global variables at the top) use this.prop, and set their values dynamically. We can use those values to set CSS classes on the fly, paginate or filter content, turn modals on, and so much more!

I’ll be collecting more ideas here and adding additional pages.