We continue with our tutorial section on the ESP8266 and ESP32 by seeing how to integrate an application that combines VueJs, Vuetify, Axios and communicates with the ESP8266 through a Rest API.
We will refer to the ESP8266, but the same code is compatible for the ESP32, adjusting the library names. At the end you have the code for both the ESP8266 and the ESP32.
In the previous post of this series, we left off having integrated a VueJs application, which used the Axios library to communicate through a Rest API with the ESP8266 acting as the backend.
Our application could be a good example of architecture but… let’s admit it, it was ugly as sin. But this is about to change! To do this, we are going to incorporate Vuetify into our cocktail, which we already saw in this post.

The goal is to achieve functionality similar to the previous one, i.e., a demo showing how to perform the different actions through the Rest API, but with this more modern and appropriate aesthetic.
Looks better, right? Well, “let’s get to work”. The backend code, i.e., the ESP8266’s, is identical to that of the last two posts. So, once again, I’ll avoid copying it again and refer you to the previous posts or the code on Github.
What will change is the served web page.
The index.html file becomes
<!DOCTYPE html>
<html>
<head>
<title>ESP8266 Vuetify + Axios</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- From CDN -->
<!--<link href='https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons' rel="stylesheet">-->
<!--<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" rel="stylesheet">-->
<link href="./vendor/google-fonts.css" rel="stylesheet">
<link href="./vendor/vuetify.min.css" rel="stylesheet">
</head>
<body>
<div id="app">
<v-app id="inspire">
<v-container style="max-width: 600px">
<v-form>
<v-container>
<v-layout row>
<v-flex xs12 sm6 md3>
<v-btn color="info" @click="getAll">Get All</v-btn>
</v-flex>
</v-layout>
<v-layout row>
<v-flex xs12 sm6 md3>
<v-btn color="info" @click="getById">Get</v-btn>
</v-flex>
<v-flex xs12 sm6 md3>
<v-text-field v-model.number="getId" label="Id" solo type="number"></v-text-field>
</v-flex>
</v-layout>
<v-layout row>
<v-flex xs12 sm6 md3>
<v-btn color="info" @click="updateById">Update</v-btn>
</v-flex>
<v-flex xs12 sm6 md3>
<v-text-field v-model.number="updateId" label="Id" solo type="number"></v-text-field>
</v-flex>
<v-flex xs12 sm6 md3>
<v-text-field v-model="updateText" label="Text" solo></v-text-field>
</v-flex>
</v-layout>
</v-container>
</v-form>
<v-divider class="mb-3"></v-divider>
<v-text-field v-model="newItem" label="Add new item" solo @keydown.enter="create">
<v-fade-transition slot="append">
<v-icon v-if="newItem" @click="create">add_circle</v-icon>
</v-fade-transition>
</v-text-field>
<v-card>
<v-toolbar color="cyan" dark>
<v-toolbar-title>Total: {{ items.length }}</v-toolbar-title>
</v-toolbar>
<v-fade-transition class="py-0" group tag="v-list">
<template v-for="(item, i) in items">
<v-divider v-if="i !== 0" :key="`${i}-divider`" ></v-divider>
<v-list-tile :key="`${i}-${item.text}`">
<v-list-tile-action>
<v-list-tile-title v-text="item.id"></v-list-tile-title>
</v-list-tile-action>
<v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title v-text="item.text"></v-list-tile-title>
</v-list-tile-content>
</v-list-tile-action>
<v-spacer></v-spacer>
<div>
<v-btn color="error" v-model="item" @click="remove(item)">Delete</v-btn>
</div>
</v-list-tile>
</template>
</v-fade-transition>
<v-snackbar v-model="snackbar" :bottom="true" :timeout="timeout">
{{ text }}
<v-btn color="pink" flat @click="snackbar = false">
Close
</v-btn>
</v-snackbar>
</v-card>
</v-container>
</v-app>
</div>
<!-- From CDN -->
<!--<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>-->
<!--<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.js"></script>-->
<!--<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/axios.min.js"></script>-->
<script type="text/javascript" src="./vendor/vue.min.js"></script>
<script type="text/javascript" src="./vendor/vuetify.min.js"></script>
<script type="text/javascript" src="./vendor/axios.min.js"></script>
<script type="text/javascript" src="./js/API.js"></script>
<script type="text/javascript" src="./js/app.js"></script>
</body>
</html>
The page’s JavaScript file must also be modified to adapt to the new Vuetify Framework, ending up like this.
new Vue({
el: '#app',
data: () => ({
items: [
{
id: 0,
done: false,
text: 'Init 0'
}
],
newItem: null,
getId: null,
updateId: null,
updateText: null,
snackbar: false,
timeout: 1500,
text: '',
lastId : 0,
}),
computed: {
},
methods: {
create () {
lastId = Math.max(...this.items.map(d => d.id));
this.items.push({
id: ++this.lastId,
done: false,
text: this.newItem
})
API_post(this.newItem)
this.newItem = null
},
getAll() {
this.text = "Getting all"
this.snackbar = true
API_getAll()
lastId = Math.max(...this.items.map(d => d.id));
this.items.push({id: ++this.lastId, text: 'Loaded all '})
this.items.push({id: ++this.lastId, text: 'Loaded all '})
},
getById() {
if(this.getId == null) return;
if(((typeof this.items.find(x => x.id === this.getId) !== 'undefined'))) return;
this.text = "Getting by Id " + this.getId
this.snackbar = true
API_get(this.getId)
this.items.push({id: this.getId, text: 'Loaded by Id'})
},
updateById(id) {
if(this.updateId == null || this.updateId == null) return;
this.text = "Updating " + this.updateId + " with " + this.updateText
this.snackbar = true
API_put(this.updateId, this.updateText)
this.items.find(x => x.id === this.updateId).text = this.updateText
},
remove(item) {
this.text = "Deleting " + item.id
this.snackbar = true
API_delete(item.id)
this.items.splice(this.items.indexOf(item), 1)
}
}
})
Result
We upload our contents to the SPIFFS as we are used to, and press the different buttons to check that everything works correctly in the browser’s development console.

As well as that they correctly reach the ESP8266 as the backend, through the serial port terminal.

And we are done with this tutorial series! We have integrated a Rest API, Json, Axios, Vue and Vuetify into a functional and nice-looking demo app. You can be proud! (pat on the back)
So are we finished? Not at all. In the next three posts, we will see how to create an API for the ESP8266 that allows reading analog/digital inputs and performing actions, through Websocket, also using Vue in the frontend. See you soon!
Download the code
All the code from this post is available for download on Github.
Version for ESP8266: https://github.com/luisllamasbinaburo/ESP8266-Examples
Version for ESP32: https://github.com/luisllamasbinaburo/ESP32-Examples

