A simple CRUD app with vue.js
Simple create, update, delete with vue.js
What is vue.js?
Vue.js is an SPA framework like Angular or React. It is pleasant to use like svelte and that is why we keep seeing more of it.
Angular is bloated and boring, vue is fast and does not have dependencies or packaging issues. I use rollup and vite for that.
Here we are using the webpack edition.
Why is it important?
Single page applications are browser based programs that implement a functionality with a user interface which is the browser. Since every tool needs a UI, this is now very common. It is cross platform, works across the Internet and fun.
HTMX came along to disrupt the SPA idea, but we still need SPA for most complex projects.
How to setup?
$ npm create vue@latest
$ cd <project>
$ yarn
$ yarn serve
What is CRUD?
CRUD stands for create, read, update, delete. These are basic DB operations we perform on data. But we don’t need a DB. The DB is just an in memory object or collection inside the vue.js source code.
We need an interface for adding text in our case, just names and a handful of buttons to update and delete.
It is a very simple basic building block of any serious application.
Sample app and demo
The source code is here, really small.
VueCRUD.vue
<!--
https://eugenkiss.github.io/7guis/tasks/#crud
-->
<script setup>
import { ref, reactive, computed, watch } from 'vue'
const names = reactive(['Emil, Hans', 'Mustermann, Max', 'Tisch, Roman'])
const selected = ref('')
const prefix = ref('')
const first = ref('')
const last = ref('')
const filteredNames = computed(() =>
names.filter((n) =>
n.toLowerCase().startsWith(prefix.value.toLowerCase())
)
)
watch(selected, (name) => {
[last.value, first.value] = name.split(', ')
})
function create() {
if (hasValidInput()) {
const fullName = `${last.value}, ${first.value}`
if (!names.includes(fullName)) {
names.push(fullName)
first.value = last.value = ''
}
}
}
function update() {
if (hasValidInput() && selected.value) {
const i = names.indexOf(selected.value)
names[i] = selected.value = `${last.value}, ${first.value}`
}
}
function del() {
if (selected.value) {
const i = names.indexOf(selected.value)
names.splice(i, 1)
selected.value = first.value = last.value = ''
}
}
function hasValidInput() {
return first.value.trim() && last.value.trim()
}
</script>
<template>
<div><input v-model="prefix" placeholder="Filter prefix"></div>
<select size="5" v-model="selected">
<option v-for="name in filteredNames" :key="name">{{ name
}}</option>
</select>
<label>Name: <input v-model="first"></label>
<label>Surname: <input v-model="last"></label>
<div class="buttons">
<button @click="create">Create</button>
<button @click="update">Update</button>
<button @click="del">Delete</button>
</div>
</template>
<style>
* {
font-size: inherit;
}
input {
display: block;
margin-bottom: 10px;
}
select {
float: left;
margin: 0 1em 1em 0;
width: 14em;
}
.buttons {
clear: both;
}
button + button {
margin-left: 5px;
}
</style>
main.js
import { createApp } from 'vue'
import VueCrud from './VueCrud.vue';
createApp(VueCrud).mount('#app')
The explanation is that we are using the watch() lifecycle hook to look for updates, but otherwise very straight forward.
We cycle through the object array with v-for.
The @click modifier is useful for invoking methods on button clicks. We have one for update, one for create and one for delete.
A simple white based theming, so the styling is not really doing anything for us. You can prettify it if you want.
Conclusion
Vue.js is pleasant and with this sample code we are learning how to use vue.js click handlers, how to style and use the ref() system for reactivity.
Usually with SPA we need reactivity to be able to update data on screen as they change.
React makes it really painful but it is easy in vue.