Vue.js and Alpine.js - What is the difference?

Vue.js is one of the most popular Javascript frameworks in the world right now, originally released in 2014 and with version 3 just around the corner that’s unlikely to change any time soon.

So why yet another javascript framework, why Alpine? Well, unlike most modern javascript frameworks, Alpine requires absolutely no build, you simply include the library and away you go, all features included. It’s also super lightweight, at the time of writing, Alpine is just 4.3kb (v.1.9.3). However, probably the most attractive things about Alpine for me is its syntax, if you already know Vue, you basically know Alpine, making it perfect for Vue developers to turn to for projects where Vue is simply overkill and without the headache of learning something completely alien. Creator Caleb Porzio (Creator of Laravel Livewire) has kept much of the syntax in line with Vue, for example: v-for becomes x-for, v-show becomes x-show etc, he’s even included the shortener syntax for x-on, so x-on:click=”” can become @click=”” if you prefer. All 13 directives can be found here: https://github.com/alpinejs/alpine#learn.

(For those wondering why Alpine uses x- instead of a-,before deciding on a name, Alpine was known as “project-x”, a nod to it’s past.)

The simple app I want to look at is a simple todo example. “WWWHHHYYYYY? WHY ANOTHER TODO EXAMPLE?” I hear you asking… Well it displays lot’s of basic concepts so…

Getting started with Vue

There a couple of ways to get up and running with Vue, the simplest way is to include Vue via CDN:

<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>

But Vue also offers Vue CLI, to use Vue CLI you’ll need to install node, which you can find here: https://nodejs.org/ and install the Vue CLI by opening your terminal and using the following command:

npm install -g @vue/cli

Once you have Vue CLI installed you can create your project by running:

vue create my-project

Follow the instructions and then change directory to your project:

cd my-project
npm run serve

Getting started with Alpine

Alpine doesn’t currently have a command line interface but is super easy to use via CDN — Create a new html file and add the following line before the closing body tag:

<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v1.9.3/dist/alpine.js" defer></script>

Creating our template:

We’re creating a todo app, so we need a few key features:

1: A list of our Todo’s

2: A checkbox mark completed Todo’s as done

3: A delete button to remove any old Todos

4: A form to submit new Todo’s

Creating our template in Vue:

<template>
    <div id="app">
       <form @submit.prevent="addNewTask()">
           <input type="text" v-model="task" />
           <button type="submit">Add new task</button>
       </form>
       <ul>
           <li v-for="todo in todos" :key="todo.id" :class="{ 'is-complete': todo.isComplete === true }">
               <span v-text="todo.task"></span>
               <input type="checkbox" v-model="todo.isComplete" />
               <button @click="removeTask(todo.id)">Delete</button>
           </li>
       </ul>
    </div>
</template>

Creating our template in Alpine:

<div id="app" x-data="todos()">
    <form @submit.prevent="addNewTask()">
        <input type="text" x-model="task" />
        <button type="submit">Add new task</button>
    </form>
    <ul>
        <template x-for="todo in todos" :key="todo.id">
            <li :class="{ 'is-complete': todo.isComplete === true }">
                <span x-text="todo.task"></span>
                <input type="checkbox" x-model="todo.isComplete" />
                <button @click="removeTask(todo.id)">Delete</button>
            </li>
        </template>
    </ul>
</div>

The templates for both Vue and Alpine incredibly similar, although there are some minor changes so let’s go through them:

  • The most obvious change is the use of the tag, the template tag was an element introduced in HTML 5 that holds code but does not display it. In Vue files, we use tags to wrap our template code. In Alpine we do not need to do this, as the it can be written in plain HTML files. Instead the tag in Alpine, because it doesn’t have a virtual DOM, is for smart functionality like for loops and if statements.
  • Unlike Vue, in Alpine we need to find attach our data to our element ourselves, we can see this on our parent #app element which uses the x-data directive. In our example we’ve bound the function todos(), which will hold all of our data and methods.
  • The only other change we had to make was swapping out v-* for x-*

Our data in Vue:

export default {
    data() {
        return {
            increment: 3,
            task: '',
            todos: [
                {
                   id: 1,
                   task: 'Open VS code',
                   isComplete: true
                },
                {
                    id: 2,
                    task: 'Write a todo app in vuejs',
                    isComplete: false
                }
            ]
        }
    },
    /**/
}

Our data in Alpine:

function todos() {
    return {
        //data
        increment: 3,
        task: '',
        todos: [
           {
               id: 1,
               task: 'Open VS code',
               isComplete: true
           },
           {
               id: 2,
               task: 'Write a todo app in alpinejs',
               isComplete: false
           }
       ],
    /**/
    }
}

Like in our templates, there are very few discrepancies the data mark up in Vue and Alpine. /**/ has been used in the above examples to represent where more code will sit. In both examples we use a function to return an object which holds our data, in Vue we use:

data() {/**/}

In alpine we use the todos() method that we referenced in the x-data directive in our Alpine template:

todos() {/**/}

There’s 2 other small differences between the examples above:

  • In Vue we have to export within our , in Alpine, we can write our functions directly in the tags.
  • In Vue, our “more code” representation sits outside of our data() method, as apposed to in Alpine, where our “more code” representation sits within our todos() method. The reason for this is that all methods in Vue should be placed inside the methods object.

Our methods in Vue:

export default {
    /**/
    methods: {
        addNewTask() {
            //Return if empty
            if (this.task.trim() === '') return;
            //Add new todo and clear task
            this.todos.push({
               id: this.increment++,
               task: this.task,
               isComplete: false
            });
            this.task = '';
        },
        removeTask(todoToRemove) {
            this.todos = this.todos.filter(todo => todo.id != todoToRemove);
        }
    }
}

Our methods in Alpine:

function todos() {
    return {
        /**/
        addNewTask() {
            //Return if empty
            if (this.task.trim() === '') return;
            //Add new todo and clear task
            this.todos.push({
                id: this.increment++,
                task: this.task,
                isComplete: false
            });
            this.task = '';
        },
        removeTask(todoToRemove) {
            this.todos = this.todos.filter(todo => todo.id != todoToRemove);
        }
}

Here there are no changes at all to the methods themselves, just where they sit within the code. In Vue, methods sit within our methods object, in Alpine, directly in the object returned by our todos() method.

Conclusion:

In conclusion, if you’re a Vue developer but find yourself using Vue in situations where its completely overkill or you want to demo some simple functionality, quickly, with no build then Alpine is perfect. As the examples above illustrate, the learning curve of Alpine for a Vue developer is almost nothing. If you’re not a Vue developer but want to move away from jQuery or writing custom Vanilla JS for simple functionality, I think Alpine is certainly worth a try, with no build necessary, it’s quick and easy to get up and running.

While Vue is still my JavaScript framework of choice in many cases, I think it’s important that it has its place. Personally, I believe Alpine will be a very welcome addition in the front end development world.

Thank you for reading!

#vuejs #javascript #alpinejs #webdev #front-end

Vue.js and Alpine.js - What is the difference?
1 Likes144.40 GEEK