Build a Shopping List App with the Vue 3.0 Composition API
This article will show how the Vue Composition API is a great way to make your code more readable and maintainable. An alternative to the Options API, the Composition API introduced in Vue 3 handles methods and component state more accessibly.
The Composition API is a new (and optional) way of creating and organizing components in a Vue 3 application. It allows reactive component logic to be defined more intuitively by allowing all the code for a specific feature (search, for example) to be grouped. Using the Vue Composition API will make your application more scalable and reusable between several components.
In this article, we’ll build a simple shopping List app with the Vue Composition API.
You can check out a live demo of the app we’re building.
Prerequisites
For this tutorial, you’ll need:
Setting Up the Vue Application
Now let’s start by installing Vue Cli:
npm install -g vue-cli
This command will install Vue globally.
We’ll use the Vue CLI to build a simple application. To do that, open up your terminal and type the following:
vue create vueshoppinglist
After installation, move into the folder using the cd vueshoppinglist
and run npm run serve
.
This starts a development server that allows you to view your app on localhost:8080.
It’s now time to set up a nice Vue project.
The Vue Composition API
To Install the Composition API from the root of your project, run the following:
npm install --save @vue/composition-api
After successfully installing, we’ll import it into our project.
Modify src/main.vue
to register the Composition API globally in our application, so that we can use it in all our application components:
import Vue from 'vue'
import App from './App.vue'
import VueCompositionApi from '@vue/composition-api'
Vue.config.productionTip = false
Vue.use(VueCompositionApi)
new Vue({
render: h => h(App),
}).$mount('#app')
Building Out the User Interface
We’ll need a component that will house the UI of our app. Create a new ShoppingList.vue
component in the src/components/
directory and paste the following into the file:
<template>
<section>
<div class="form-container">
<h2>Add Item</h2>
<form>
<div>
<label>Product name</label>
<br />
<input type="text" />
</div>
<div>
<button type="submit" class="submit">Add Item</button>
</div>
</form>
</div>
<div class="list-container">
<ul>
<li>
Shopping List app
<span style="float:right;padding-right:10px;">
<button>X</button>
</span>
</li>
</ul>
</div>
</section>
</template>
<script>
export default {};
</script>
<style scoped>
input {
width: 20%;
height: 30px;
border: 2px solid green;
}
.submit {
margin: 10px;
padding: 10px;
border-radius: 0px;
border: 0px;
background: green;
color: white;
}
ul li {
list-style: none;
border: 2px solid green;
width: 30%;
margin-top: 10px;
}
</style>
The code snippet above is the initial boilerplate of our UI. We’ll now import our new component ShoppingList.vue
to App.vue
as shown below:
<template>
<div id="app">
<img alt="Shoppingd List" src="./assets/shopping.png">
<shopping-list msg="Welcome to Your Vue.js App"/>
</div>
</template>
<script>
import ShoppingList from './components/ShoppingList.vue'
export default {
name: 'App',
components: {
ShoppingList
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
Working with the Vue Composition API
Let’s get started by importing the Composition API to our component ShoppingList.Vue
:
<script>
import { reactive } from "@vue/composition-api";
export default {};
</script>
Here, we’re importing reactive
from the Vue Composition API.
We’ll now add some event listeners to the application by modifying our template to this:
<template>
<section>
<div class="form-container">
<h2>My Shopping List App</h2>
<form @submit.prevent="addItem">
<div>
<label> Product Name</label>
<br />
<input v-model="state.input" type="text" />
</div>
<div>
<button type="submit" class="submit">Add Item</button>
</div>
</form>
</div>
<div class="list-container">
<ul v-for="(Item,index) in state.Items" :key="index">
<li>
{{Item}}
<span style="float:right;padding-right:10px;">
<button @click="removeItem(index)">X</button>
</span>
</li>
</ul>
</div>
</section>
</template>
Vue 3 uses the data
and methods
option to define state and add functions rather than accessing to a setup
method. This method is called after the lifecycle hook beforeCreate
and prior to create
.
We’ll now declare the state
variable and methods inside the setup method, as shown below:
<script>
import { reactive } from "@vue/composition-api";
export default {
setup() {
const { state, addItem, removeItem } = ItemList();
return { state, addItem, removeItem };
}
};
</script>
After declaring Variables and methods, we need to define our component state:
<script>
import { reactive } from "@vue/composition-api";
export default {
setup() {
const { state, addItem, removeItem } = ItemList();
return { state, addItem, removeItem };
}
};
function ItemList() {
let state = reactive({
input: "",
Items: ["Grocery"]
});
return { state };
</script>
The state here is scoped to the ItemList
function. We define our input
state that we’ll bind to our input field and also define our Items
array that will hold all our Items
.
Let’s define our addItem
function:
<script>
import { reactive } from "@vue/composition-api";
export default {
setup() {
const { state, addItem, removeItem } = ItemList();
return { state, addItem, removeItem };
}
};
function ItemList() {
let state = reactive({
input: "",
Items: ["Grocery"]
});
let addItem = () => {
state.Items.push(state.input);
state.input = "";
};
return { state, addItem };
</script>
The add functionality will take the data in the input field and push it into the Items array using the push method.
Let’s implement deleting an item. We’ll get the index of the Item
and then remove the Item
from the users array using the splice method:
<script>
import { reactive } from "@vue/composition-api";
export default {
setup() {
const { state, addItem, removeItem } = ItemList();
return { state, addItem, removeItem };
}
};
function ItemList() {
let state = reactive({
input: "",
Items: ["Grocery"]
});
let addItem = () => {
state.Items.push(state.input);
state.input = "";
};
let removeItem = i => {
state.Items.splice(i, 1);
};
return { state, addItem, removeItem };
</script>
It’s important that everything we want to be able to access from the template is returned by both the itemList
and setup()
methods. At the end of the code snippet, we’re returning the state or method.
Our shopping list app is now complete:
Conclusion
Finally, we’ve built our Shopping List app with the Vue 3 Composition API. It’s interesting to see how the Composition API is used in Vue 2. One of its key advantages I’ve observed is the handling of methods, and component state is made more accessible and also its reactivity.
I hope you learned a few things about Vue. Hit me up on Twitter if you have any questions or feedback.
And feel free to add new features to the app, as this is a great way to learn. You can check out the source code here.