Intermediate45 minVueVite

First Vue App with Vite

Use the familiar Todo List project to understand Vue components, reactive state, and how a small Vite + Vue app fits together.

Learning Objectives

By the end of this lesson, you'll be able to:

  • βœ“ Explain Explain how a small Vue app starts inside a Vite project
  • βœ“ Identify Identify the main roles of `main.js` and `App.vue`
  • βœ“ Store Todo List data in reactive state
  • βœ“ Render repeated todo items from data in the template
  • βœ“ Describe Describe how Vue changes the UI update workflow

Why This Matters:

A first framework lesson works best when it translates a project you already understand into a more structured application model.

Before You Start:

You should be familiar with:

Why Vue Fits Here

Vue makes more sense once you already understand two ideas:

  • why frameworks exist at all
  • why tooling such as Vite appears around them

That is why this lesson comes here instead of earlier. You are not being asked to learn JavaScript, framework theory, and build tooling all at once. Instead, you are using a project you already recognise to see how Vue organises the same kind of work differently.

Project bridge: the Todo List is already familiar from earlier work. That reduces project noise so the framework ideas can stand out more clearly.

The Shape of the Project

In a small Vite + Vue app, the path usually feels like this:

  • index.html gives the root mount point
  • main.js starts the Vue app
  • App.vue becomes the main component shell
  • the component template renders the visible interface
Diagram showing a Vite plus Vue app flow from main.js into App.vue and then into the Todo List interface.
Start by tracing the path into the app. Once you can name the entry flow, the project becomes easier to reason about.

`main.js` and `App.vue`

You do not need to memorise every generated file to start using Vue well. The first important distinction is simple:

  • `main.js` starts the app and mounts it into the page
  • `App.vue` acts as the main component where your interface logic begins
// main.js
import { createApp } from 'vue';
import App from './App.vue';

createApp(App).mount('#app');

That line does not build the whole application for you. It simply connects the Vue app to the root element so your component tree can render inside it.

Reactive State in Plain English

The biggest shift in a first Vue app is not the file extension. It is the data model. Instead of reaching into the DOM every time the user changes something, you store the changing values in state and let the template reflect them.

Diagram showing user action flowing into reactive state and then into rendered Todo List output in the browser.
The mental loop matters more than the exact syntax. Action changes state, and state drives the rendered interface.

Todo List state candidates

  • newTask for the text currently being typed
  • todos for the list of task objects
  • done inside each task object for completion state
<script setup>
import { ref } from 'vue';

const newTask = ref('');
const todos = ref([
  { id: 1, text: 'Outline the Vue Todo List', done: false },
  { id: 2, text: 'Render tasks from state', done: true },
]);

function addTodo() {
  if (!newTask.value.trim()) return;

  todos.value.push({
    id: Date.now(),
    text: newTask.value.trim(),
    done: false,
  });

  newTask.value = '';
}
</script>

Rendering the Todo List from Data

In plain DOM code, you may have built list items by creating elements, appending nodes, and wiring listeners by hand. Vue still ends up producing DOM output, but the route there is calmer: the template describes what the UI should look like for the current state.

<template>
  <section class="section">
    <div class="container">
      <h1>Todo List</h1>

      <input v-model="newTask" type="text" placeholder="Add a task" />
      <button @click="addTodo">Add</button>

      <ul>
        <li v-for="todo in todos" :key="todo.id">
          &#123;&#123; todo.text &#125;&#125;
        </li>
      </ul>
    </div>
  </section>
</template>

The important part is not memorising every directive name immediately. The important part is noticing that the list is rendered from the data structure instead of being written as separate static markup.

πŸ“ Checkpoint for Understanding

Pause here and make sure the shift from DOM-pushing to state-driven rendering feels clear.

  1. Why is the Todo List project a useful first Vue example?
  2. What is the practical job of `main.js` in a small Vue project?
  3. What changes when you move from manual DOM updates to Vue state-driven rendering?
Show sample answers
  1. Because learners already know the interface problem, so they can focus on Vue ideas such as state, template rendering, and event handling instead of learning a brand-new project goal at the same time.
  2. It starts the Vue application and mounts it into the page, usually by connecting the app to a root element such as `#app`.
  3. Instead of pushing changes into the DOM directly in many places, you update the data and let the template reflect that state more consistently.

How confident are you with this concept?

πŸ˜• Still confused | πŸ€” Getting there | 😊 Got it! | πŸŽ‰ Could explain it to a friend!

Events and Updates

Vue does not remove events. It changes how you connect them to the interface. In a Todo List, that might mean:

  • typing into an input updates reactive state
  • clicking a button calls a function that changes the state
  • checking a box toggles one task’s completion flag
  • the template updates because the data changed

The workflow is still logical and explicit. It is just organised around the state layer instead of many scattered DOM edits.

Guided Practice

Rebuild the Todo List mentally before you rebuild it in code

Use the existing Todo List project as the bridge from plain JavaScript thinking into Vue structure.

Step 1: Scaffold a Vue app and identify the entry files

Create a Vue project with the official scaffold command and open the generated files.

Find main.js, App.vue, and the root index.html. Write one short note describing what each file contributes to the app.

πŸ’‘ Need a hint?
Think of `main.js` as the startup file and `App.vue` as the first real application component.
You do not need to understand every generated file before you begin. Start with the entry path.

Step 2: Reframe the Todo List around state

List the core pieces of data the Todo List needs: the text currently being typed, the array of todo items, and each item’s completion state.

Then ask: which of these values should live in reactive state rather than being read from the DOM each time?

πŸ’‘ Need a hint?
If the value changes and the interface should respond, it is usually a state candidate.
The browser still shows the UI, but Vue is now keeping the source of truth in data.

Step 3: Render the list from data

Create a small todo array and render it in the template. Then add one event that changes the array, such as adding a new task or toggling completion.

Watch how the interface updates because the state changed.

πŸ’‘ Need a hint?
Do not overbuild the first version. One input, one button, one list, and one update loop is enough.
The goal is to feel the data-to-template connection clearly.

You are on track if you can:

  • ☐ You can point to the root entry path from `index.html` to `main.js` to `App.vue`
  • ☐ You identified which Todo List values belong in reactive state
  • ☐ You rendered todo items from data instead of hardcoding them into the HTML
  • ☐ You changed the state and watched the interface update from that change

Independent Practice

πŸ’ͺ Independent Practice: Build a small Vue Todo List shell

Now try the same idea with lighter support.

Your Task:

Scaffold a Vue app and rebuild a small Todo List interface with one input, one add button, and one rendered list. Keep the scope tight. The goal is not feature-complete polish. The goal is to feel how the app flows from state into the template.

Requirements:
  • Use a Vue component as the main Todo List shell
  • Store the current input and todo array in reactive state
  • Render the list from data rather than hardcoded markup
  • Handle at least one event that changes the state
Stretch Goals (Optional):
  • Add task completion toggling
  • Split the Todo List into a second child component once the main version works

Success Criteria:

CriteriaYou've succeeded if...
Project structure awarenessThe learner can explain what the Vue entry files do without confusing Vite, Vue, and the app code.
State thinkingThe learner stores the changing Todo List data in reactive state instead of relying on scattered DOM reads.
Template renderingThe interface is driven from state, with repeated todo items rendered from data rather than written manually one by one.
Reasoning clarityThe learner can explain how Vue changes the workflow compared with direct DOM manipulation.

Additional Resources

Recap

Vue becomes much more approachable when you stop treating it like a brand-new world and instead map it onto a familiar interface. The Todo List still asks the same questions as before: what is the current task, what are the items, and what changed? Vue simply gives you a more structured way to express those answers.

Lesson Complete: You Can Read a Small Vue App

Key Takeaways:

  • Vue becomes easier to understand when you attach it to a familiar project instead of a brand-new app idea.
  • `main.js` starts the app, `App.vue` acts as the main component shell, and the template reflects reactive state.
  • The biggest shift is not syntax. It is moving from direct DOM pushing to state-driven rendering.
  • The Todo List remains the same project underneath, but Vue changes how the project is organised and updated.

Learning Objectives Review:

Look back at what you set out to learn. Can you now:

  • βœ… Explain how a small Vite plus Vue app is structured Check!
  • βœ… Identify the Todo List values that belong in reactive state Got it!
  • βœ… Render repeated UI from data rather than hardcoded markup Can explain it!
  • βœ… Describe how Vue changes the update flow compared with direct DOM manipulation Could teach this!

If you can confidently answer "yes" to most of these, you're ready to move on!

Think & Reflect:

Project Shape

  • Which file feels most important to you now: `main.js`, `App.vue`, or the template inside the component?
  • What part of the app structure felt clearer after tracing the entry path?

State and Rendering

  • What changes when you think β€œchange the data” instead of β€œmanually rewrite the DOM”?
  • Which part of the Todo List is easiest to understand as reactive state?

🎯 Looking Ahead:

Next, keep the same Todo List project but add Bulma so you can see how a CSS framework speeds up interface structure inside a Vue template.

Recommended Next Steps

Continue Learning

Ready to move forward? Continue with the next tutorial in this series:

Using Bulma in a Vue Project

Related Topics

Explore these related tutorials to expand your knowledge:

Practice Projects

Apply what you've learned with these hands-on projects:

Todo List

Reuse the familiar Todo List project idea as your first Vue case study.

VueStateLists
Start Project

Additional Resources

Deepen your understanding with these helpful resources:

Progress tracking is disabled. Enable it in to track your completed tutorials.