Vue.js course Β· Module 1: Vue and Vite

Diagnostic Tools

6 min read
In this lesson5

In space, diagnostics are a matter of life and death. Vue DevTools is our system scanner.

A panel shows a wrong reading and you don't know why: is it the data, the template, or maybe the component never rendered at all? Adding console.log in ten places is guesswork. You need tools that show you the inside of a running application.

Vue DevTools

Vue DevTools are the official developer tools for Vue; versions 7 and later support only Vue 3. The first way to install them is the browser extension:

  • Chrome: Vue.js devtools
  • Firefox: Vue.js devtools
  • Edge: Vue.js devtools

The second way is the vite-plugin-vue-devtools plugin, which the create-vue wizard adds to the Vite configuration for you. In development mode you then open the panel with a button at the bottom of the page, without installing anything in the browser. In Vite projects I recommend exactly this way - the DevTools documentation recommends it because of its additional features.

Diagnostic Features

  1. Component Inspector - scan the module tree
  2. State Inspector - monitor reactive data in real time
  3. Timeline - track event and change history
  4. Router - debug navigation
  5. Pinia - manage the mission database

In current versions, the component inspector and the state inspector form one Components tab: the tree on the left, and on the right the data of the selected component, which you can edit live. The tree of a typical application looks like this:

1App
2└── MainLayout          (layout: header, sidebar)
3    └── DashboardView   (view)
4        β”œβ”€β”€ OxygenCard  (UI)
5        └── AlertButton (UI)

At the top stands the root component, below it the layout, inside the layout a view, and at the end the smallest interface elements. Click any node and you'll see its data next to it.

Debugging Protocols

Logging system changes

Sometimes you want to react to every change, for example log it to the console or raise an alarm. That's what the watch function is for: the first argument is the watched source, the second is a function that Vue calls after every change, with the new and the old value:

1import { ref, watch } from 'vue'
2
3const oxygenLevel = ref(98.5)
4
5// Change monitoring
6watch(oxygenLevel, (newLevel, oldLevel) => {
7  console.log(`Oxygen level: ${oldLevel}% β†’ ${newLevel}%`)
8
9  if (newLevel < 90) {
10    console.error('ALERT: Low oxygen level!')
11  }
12})

Set oxygenLevel.value to 88, and the console shows an entry with an arrow followed by a red alert. watch doesn't display anything and doesn't change the oxygen level - it only reacts. The difference from computed is simple: computed calculates a value, watch performs an action.

Debug in template

The second technique is a diagnostic panel in the template. The v-if directive displays an element only when the condition is true, and JSON.stringify turns an object with data into readable text:

1<template>
2  <!-- Diagnostic panel -->
3  <div v-if="debugMode" class="debug-panel">
4    <pre>{{ JSON.stringify(systemData, null, 2) }}</pre>
5  </div>
6
7  <!-- Critical indicators -->
8  <div class="critical-systems">
9    <span>O2: {{ oxygen }}%</span>
10    <span>Temp: {{ temperature }}Β°C</span>
11    <span>Pressure: {{ pressure }} hPa</span>
12  </div>
13</template>

When debugMode is false, Vue doesn't create the diagnostic panel at all, and the indicators below it keep working unchanged. The variables used in the template are declared as ref() in the <script setup> section omitted here.

Sensor simulator

For testing, a field in which you type a reading comes in handy. The v-model directive binds the field to a container in both directions: the number you type goes into oxygen, and a change of oxygen in the code goes into the field. The v-if and v-else pair displays one of two paragraphs:

1<template>
2  <input v-model="oxygen" type="number" />
3  <p v-if="oxygen >= 90">Oxygen normal</p>
4  <p v-else>ALERT: low oxygen level</p>
5</template>
6
7<script setup>
8import { ref } from 'vue'
9
10const oxygen = ref(95)
11</script>

Type 85, and the alert replaces the normal message. v-else must come right after the element with v-if, because it refers to its condition. You'll learn conditional directives in the Hologram Workshop and forms with v-model in the Control Simulator.

Hot Module Replacement

Vite automatically updates modules without restarting, and the server terminal reports which file it swapped:

112:04:31 [vite] (client) hmr update /src/components/LifeSupport.vue

The time format depends on your system settings, and (client) stands for the browser environment. Changes are visible instantly - critical during system development!

Operational Commands

CommandDescription
npm run devDevelopment mode (simulator)
npm run buildCompile for deployment
npm run previewTest production version
npm run test:unitRun unit tests (Vitest)
npm run lintCheck code quality

These are scripts from package.json that the wizard adds depending on the options you chose - hence test:unit instead of plain test. A typical work cycle: npm run dev, editing components, a refresh through HMR, and before deployment npm run build followed by checking the result with npm run preview.

Preparing for Deployment

The build runs in four stages. Vite starts from index.html and finds the entry script in it. Then Rolldown loads the modules one by one: each is transformed first (the Vue plugin compiles .vue files, and the Oxc tool turns TypeScript and JSX into JavaScript), and only then does Rolldown read its imports and fetch the next files, building a dependency graph. Next, Rolldown bundles the modules into chunks, removes unused code and minifies the result, and finally the files land in the dist folder. Up to version 7 the transformation was done by esbuild and the bundling by Rollup.

1# Compile the system
2npm run build
3
4# Output in /dist directory
5dist/
6β”œβ”€β”€ index.html
7β”œβ”€β”€ assets/
8β”‚   β”œβ”€β”€ index-[hash].js    # Compiled logic
9β”‚   └── index-[hash].css   # Compiled styles

[hash] is a fingerprint of the file's contents: when the code changes, the name changes too, so the browser won't use an old version from its cache. npm run preview serves this folder locally, but it isn't a production server - we'll deal with deployment at the Launch Platform.

This code will fly to Mars. Every bug could cost the crew's lives. Test thoroughly! In the editor below, change the counter, type a message and toggle the system while watching the same changes in DevTools.

Remember: DevTools shows the inside of the system, watch reacts to every change, and npm run build packs the tested code into the dist folder.

Code for this lesson: src/App.vue
1<template>
2  <div class="nova-lab">
3    <h1>Vue DevTools</h1>
4
5    <section class="info">
6      <h2>Your best friend during development</h2>
7      <p>
8        Vue DevTools is a browser extension that allows you to:
9      </p>
10      <ul>
11        <li>Browse the component tree</li>
12        <li>Inspect and edit state</li>
13        <li>Track events</li>
14        <li>Debug Pinia stores</li>
15        <li>Analyze performance</li>
16      </ul>
17    </section>
18
19    <section class="demo">
20      <h2>Interactive State</h2>
21      <p>Open DevTools and observe how the state changes:</p>
22
23      <div class="state-demo">
24        <div class="counter">
25          <button @click="count--">-</button>
26          <span>{{ count }}</span>
27          <button @click="count++">+</button>
28        </div>
29
30        <div class="input-demo">
31          <input v-model="message" placeholder="Type a message..." />
32          <p>{{ message }}</p>
33        </div>
34
35        <div class="toggle-demo">
36          <label>
37            <input type="checkbox" v-model="isActive" />
38            System active
39          </label>
40          <div class="status" :class="{ active: isActive }">
41            {{ isActive ? 'ONLINE' : 'OFFLINE' }}
42          </div>
43        </div>
44      </div>
45    </section>
46
47    <section class="install">
48      <h2>Installation</h2>
49      <div class="browser-links">
50        <a href="https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd" target="_blank" class="browser-btn">
51          Chrome
52        </a>
53        <a href="https://addons.mozilla.org/en-US/firefox/addon/vue-js-devtools/" target="_blank" class="browser-btn">
54          Firefox
55        </a>
56        <a href="https://microsoftedge.microsoft.com/addons/detail/vuejs-devtools/olofadcdnkkjdfgjcmjaadnlehnnihnl" target="_blank" class="browser-btn">
57          Edge
58        </a>
59      </div>
60    </section>
61  </div>
62</template>
63
64<script setup>
65import { ref } from 'vue'
66
67const count = ref(0)
68const message = ref('')
69const isActive = ref(true)
70</script>
71
72<style>
73.nova-lab {
74  min-height: 100vh;
75  background: #0a0e27;
76  color: #e0e0e0;
77  padding: 2rem;
78  font-family: system-ui, sans-serif;
79}
80
81h1 {
82  color: #00ff88;
83  text-align: center;
84}
85
86section {
87  background: rgba(26, 30, 55, 0.8);
88  border: 1px solid #00b4d8;
89  border-radius: 12px;
90  padding: 1.5rem;
91  margin: 1.5rem auto;
92  max-width: 600px;
93}
94
95h2 {
96  color: #00b4d8;
97  margin-top: 0;
98}
99
100ul {
101  list-style: none;
102  padding: 0;
103}
104
105ul li {
106  padding: 0.5rem 0;
107  border-bottom: 1px solid rgba(0, 180, 216, 0.2);
108}
109
110ul li::before {
111  content: "Β» ";
112  color: #00ff88;
113}
114
115.state-demo {
116  display: flex;
117  flex-direction: column;
118  gap: 1rem;
119}
120
121.counter {
122  display: flex;
123  align-items: center;
124  justify-content: center;
125  gap: 1rem;
126}
127
128.counter button {
129  width: 40px;
130  height: 40px;
131  background: #00b4d8;
132  color: #0a0e27;
133  border: none;
134  border-radius: 8px;
135  font-size: 1.25rem;
136  cursor: pointer;
137}
138
139.counter span {
140  font-size: 1.5rem;
141  font-weight: bold;
142  color: #00ff88;
143  min-width: 60px;
144  text-align: center;
145}
146
147.input-demo input {
148  width: 100%;
149  padding: 0.75rem;
150  background: #1a1e37;
151  border: 2px solid #00b4d8;
152  border-radius: 8px;
153  color: #fff;
154}
155
156.input-demo p {
157  color: #00ff88;
158  font-style: italic;
159  min-height: 1.5rem;
160}
161
162.toggle-demo {
163  display: flex;
164  align-items: center;
165  justify-content: space-between;
166}
167
168.toggle-demo label {
169  display: flex;
170  align-items: center;
171  gap: 0.5rem;
172  cursor: pointer;
173}
174
175.status {
176  padding: 0.5rem 1rem;
177  border-radius: 20px;
178  font-weight: bold;
179  background: rgba(255, 68, 68, 0.2);
180  color: #ff4444;
181}
182
183.status.active {
184  background: rgba(0, 255, 136, 0.2);
185  color: #00ff88;
186}
187
188.browser-links {
189  display: flex;
190  gap: 1rem;
191  justify-content: center;
192  flex-wrap: wrap;
193}
194
195.browser-btn {
196  padding: 0.75rem 1.5rem;
197  background: #1a1e37;
198  border: 2px solid #00b4d8;
199  border-radius: 8px;
200  color: #00b4d8;
201  text-decoration: none;
202  transition: all 0.2s;
203}
204
205.browser-btn:hover {
206  background: #00b4d8;
207  color: #0a0e27;
208}
209</style>

Spotted a mistake in this lesson?

Check yourself

Answer the questions from this lesson. Pick an answer to see right away whether it is correct.

  1. 1. What are the official developer tools for Vue.js called?

  2. 2. What command compiles a Vue/Vite project for production?

  3. 3. What is the watch() function used for in Vue 3?

  4. 4. Who is the creator of both Vue.js and Vite?

Hands-on tasks in the game

  • Vertical ordering

    Arrange the process of installing and running a Vue.js project from scratch:

  • Code editor

    Complete the component with watch() monitoring changes to a reactive variable and logging them to the console.

  • Click in order

    Arrange the syntax of the watch function in Vue 3:

  • Vertical ordering

    Arrange the typical Vite workflow from development to production:

  • Horizontal ordering

    Arrange the syntax for conditional rendering of an element:

  • Code editor

    Use v-if and v-else to conditionally display system status depending on a variable's value.

  • Vertical ordering

    Arrange the Vue project structure from the entry file to the component:

  • Horizontal ordering

    Arrange the syntax of a button with click event handling in Vue:

  • Click in order

    Arrange the correct import of the ref function from Vue:

  • Vertical ordering

    Arrange the order of operations in the main.js file:

  • Horizontal ordering

    Arrange the syntax for dynamic CSS class binding in Vue:

  • Click in order

    Arrange the syntax of a computed property in Vue 3:

  • Vertical ordering

    Arrange the stages of the Vite build process from source code to production:

  • Click in order

    Arrange the correct style section with the scoped attribute:

  • Horizontal ordering

    Arrange the syntax of an input with two-way data binding in Vue:

  • Vertical ordering

    Arrange the component hierarchy from the highest to the lowest level:

Useful articles