Hi there again,
Together we will develop the Nuxt 3 version of the Create ToDo App With Vue 3 Composition API blog post I wrote earlier.
1. Let's create the Nuxt 3 application.
npx nuxi init nuxt-app
cd nuxt-app
yarn install
2. Install the required packages and configure its.
yarn add -D sass sass-loader #for sass
yarn add cookie-universal-nuxt #for cookie
nuxt.config.ts
export default defineNuxtConfig({
modules: [
'cookie-universal-nuxt',
]
})
3. Create form and todo list in app.vue.
<template>
<h1>ToDo App</h1>
<form @submit.prevent="addTodo()">
<label>New ToDo </label>
<input v-model="newTodo" name="newTodo" autocomplete="off" />
<button @click="addTodo()">Add ToDo</button>
</form>
<h2>ToDo List</h2>
<ul>
<li v-for="(todo, index) in todos" :key="index">
<span :class="{ done: todo.done }" @click="doneTodo(todo)">{{ todo.content }}</span>
<button @click="removeTodo(index)">Remove</button>
</li>
</ul>
<h4 v-if="todos.length === 0">Empty list.</h4>
</template>
4. With Nuxt 3's auto import feature, we no longer need to import packages. We just need add setup attribute to script tag.
<script setup>
// all logic code in here
</script>
5. Create all property and methods. We use $cookies
for data saving and useHead
for meta tags. $cookies
come from the cookie-universal-nuxt
package and useHead comes in nuxt.
<script setup>
const newTodo = ref('')
const defaultData = [
{
done: true,
content: 'Write a blog post'
},
{
done: false,
content: 'Listen a podcast'
}
]
const { $cookies } = useNuxtApp()
const todosData = $cookies.get('todos') || defaultData
const todos = ref(todosData)
function addTodo() {
if (newTodo.value) {
todos.value.push({
done: false,
content: newTodo.value
})
newTodo.value = ''
}
saveData()
}
function doneTodo(todo) {
todo.done = !todo.done
saveData()
}
function removeTodo(index) {
todos.value.splice(index, 1)
saveData()
}
function saveData() {
$cookies.set('todos', todos.value)
}
useHead({
title: 'ToDo App',
meta: [
{
name: 'description',
content: 'Nuxt 3 ToDo App with Composition API'
}
]
})
</script>
6. Also we add some SCSS code.
<style lang="scss">
$border: 2px solid
rgba(
$color: white,
$alpha: 0.35
);
$size1: 6px;
$size2: 12px;
$size3: 18px;
$size4: 24px;
$size5: 48px;
$backgroundColor: #27292d;
$textColor: white;
$primaryColor: #a0a4d9;
$secondTextColor: #1f2023;
body {
margin: 0;
padding: 0;
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
background-color: $backgroundColor;
color: $textColor;
#__nuxt {
max-width: 600px;
margin-left: auto;
margin-right: auto;
padding: 20px;
h1 {
font-weight: bold;
font-size: 28px;
text-align: center;
}
form {
display: flex;
flex-direction: column;
width: 100%;
label {
font-size: 14px;
font-weight: bold;
}
input,
button {
height: $size5;
box-shadow: none;
outline: none;
padding-left: $size2;
padding-right: $size2;
border-radius: $size1;
font-size: 18px;
margin-top: $size1;
margin-bottom: $size2;
}
input {
background-color: transparent;
border: $border;
color: inherit;
}
}
button {
cursor: pointer;
background-color: $primaryColor;
border: 1px solid $primaryColor;
color: $secondTextColor;
font-weight: bold;
outline: none;
border-radius: $size1;
}
h2 {
font-size: 22px;
border-bottom: $border;
padding-bottom: $size1;
}
ul {
padding: 10px;
li {
display: flex;
justify-content: space-between;
align-items: center;
border: $border;
padding: $size2 $size4;
border-radius: $size1;
margin-bottom: $size2;
span {
cursor: pointer;
}
.done {
text-decoration: line-through;
}
button {
font-size: $size2;
padding: $size1;
}
}
}
h4 {
text-align: center;
opacity: 0.5;
margin: 0;
}
}
}
</style>
That's it.
See demo:
Demo: https://nuxt3-composition-api-todo-app.vercel.app/
Repo: https://github.com/BurakGur/nuxt3-composition-api-todo-app
My GitHub: https://github.com/BurakGur
Thanks for reading 😊
Top comments (1)
It is really easy to understand and very helpful. Keep continue to share like this post :)