Congratulations!
Congratulations, your habit tracker works, and you've reached the end of the Vue course! The app loads its suggestions from a file, lets you check habits off, add your own and remove them, filters the list, shows your progress and your streak, and remembers all of it. And you built it yourself, piece by piece.
One last improvement. A streak can break, but your best one shouldn't be forgotten. Save it with the composable under the key "best", and in finishDay(), once the streak has changed, raise the best when the streak is longer:
const best = useLocalStorage("best", 0);
if (streak.value > best.value) {
best.value = streak.value;
}
What you've learned. Look at how the whole course found its place in your app:
- Components:
App.vueholds the data, andHabitItem.vueshows one habit. Props bring the data down (:habit="habit"), and events go up (emit('toggle', habit.id)and@toggle="toggle"). - The template:
{{ }}shows values,:classcrosses out a habit that's done, and:stylesets the width of the bar. - State: refs hold what changes, with
.valuein the script and without it in the template, and whenever they change, Vue updates the page by itself. - Conditions and lists:
v-if,v-else-ifandv-elsechoose between loading, an error and the app, andv-forwith:keyshows the habits. - Forms:
v-modelwith.trim,@submit.preventand an error message. - Computed values: the count, the percentage,
allDoneand the filtered list, recomputed whenever the habits change. - The lifecycle:
onMountedloads the habits withfetch()once the app is on the page. - Watchers and composables:
useLocalStoragesaves any value withwatch, so three lines save three values.
The app has no slots, but you know them too: with them, a component such as the panel from the lesson Slots, or the lightbox of the photo gallery, takes whole pieces of the page from its parent.
Vue on your own computer. Here, our site prepares your files every time you click Run. On your own computer, a tool called Vite does that, and create-vue, Vue's official tool for starting a project, sets it all up for you. You need Node.js (take the LTS version), which comes with npm, a program for installing packages, and the terminal (the command line). In the terminal, go to the folder where you want your projects, and run:
npm create vue@latest
create-vue asks a few questions: first the project's name, such as habit-tracker, which also becomes the name of its folder, and then what to add to the project, such as TypeScript, Vue Router or Pinia. You don't need any of them yet, so don't choose any. If it asks anything else, keep the suggested answer. At the end, it shows the next commands:
cd habit-tracker
npm install
npm run dev
cd goes into the project's folder, npm install downloads Vue, Vite and everything else the project needs (into the folder node_modules), and npm run dev starts Vite. It shows an address such as http://localhost:5173/: open it in your browser. Leave the terminal running: whenever you save a file, the page in the browser updates by itself. Ctrl+C in the terminal stops it.
The project's files. They're the files of the exercises, just in folders:
index.htmlis in the project's main folder and has the same<div id="app">. Its script loads/src/main.js.src/main.jsmountsAppwithcreateApp(App).mount("#app"), just like yourmain.js.src/App.vueis the main component. In a new project, it holds an example: replace it with yours.src/components/is for the other components, such asHabitItem.vue(if the folder isn't there, create it). The import inApp.vuethen becomesimport HabitItem from "./components/HabitItem.vue";. You can delete the example components in the folder.public/is for files that the page loads as they are. Puthabits.jsonthere, andfetch("habits.json")finds it.
Put useLocalStorage.js into src, next to App.vue, and its import stays as it is. (Bigger projects often keep their composables in a folder of their own, src/composables.) Your style.css goes into src too, and src/main.js imports it with import "./style.css";, in place of the example's stylesheet if it has one.
The Vue DevTools. Add the Vue DevTools extension to your browser (for Chrome, Edge and Firefox; devtools.vuejs.org explains how). The developer tools (F12) then get a Vue tab, which shows your components as a tree, with their props and their state. You can even change a ref there and watch the page change. It works on pages that run with npm run dev.
Putting it online. When your app is ready, npm run build prepares it for the internet: Vite puts the finished files into the folder dist, with all the .vue files turned into plain JavaScript that any browser understands. npm run preview shows you the finished version on your own computer. Then the dist folder goes on a web server. The quickest way is Netlify Drop (app.netlify.com/drop): drag the dist folder onto the page, and you get an address you can send to anyone (to keep the site online, sign up for a free account). Services such as Netlify and Vercel can also build and publish a project by themselves, every time you change its code on GitHub, a website for keeping code.
What's next? You now know the core of Vue: the same components, refs and computed values are in every Vue app, small or big. These come next:
- Vue Router, for apps with several pages, each with an address of its own, such as
/and/stats. Each page is a component. - Pinia, for state that many components share, such as the café's order. It's like the module
order.jsfrom the lesson Composables, with more tools and with support in the DevTools. - TypeScript: with
<script setup lang="ts">, you write down the types of your props and refs, and the editor finds many mistakes before you even run the app. The TypeScript course teaches it. - Nuxt, a framework built on Vue for whole websites. It makes a page from each file in its
pagesfolder, it can render the pages on the server, so that visitors and search engines get finished HTML right away, and its server routes let your own code on the server answer the page'sfetch().
In older tutorials, you'll meet the Options API from the first lesson again: components written with export default { data() { … }, methods: { … } } instead of <script setup>. Underneath, it's the same Vue, so with what you know, you'll understand it quickly. The documentation at vuejs.org explains everything you've met here, in both styles.
Instructions
- 1
Add
bestwith the composable, raise it infinishDay()as above, and show it under the streak:<p>Best: {{ best }}</p>. Finish two days in a row with all the habits checked off:Best: 2. Then finish a day with nothing done: the streak is back at 0, and the best stays at 2.