Skip to content

alphapialpha/vue3-js-crashcourse

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 

Repository files navigation

Vue.js Crash Course – Cheatsheet

Vue.js License: GPL v3 Made with ❤️

A compact Vue 3 crash course cheatsheet with examples from Lection 1–10.
Perfect for quick refreshers, workshops, and reference.


📖 Table of Contents


Quick start, directives, forms, computed vs methods vs watchers, components, dynamic components, lifecycle, Composition API.


1) Quick Start (CDN)

Drop this into an index.html and you’re ready:

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Vue Quick Start</title>
  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
  <div id="app">
    <h1>{{ message }}</h1>
  </div>

  <script>
    const { createApp } = Vue;
    const app = createApp({
      data() { return { message: "Hello Vue!" } }
    }).mount("#app");
  </script>
</body>
</html>

2) Forms & v-model

Two‑way binding:

<input v-model="name" placeholder="Your name">
<p>Hello, {{ name }}!</p>

Checkbox / Radio / Select:

<input type="checkbox" v-model="accepted"> Terms
<input type="radio" value="a" v-model="choice"> A
<input type="radio" value="b" v-model="choice"> B
<select v-model="country">
  <option disabled value="">Pick one</option>
  <option>Germany</option>
  <option>UK</option>
</select>

💡 v-model:value + @input


3) Core Directives

Bind attributes:

<img :src="avatarUrl" :alt="username">
<a :href="profileLink">{{ username }}</a>

Events, conditionals:

<button @click="count++">Clicked {{ count }}</button>
<p v-if="loggedIn">Welcome</p>
<p v-else>Please log in</p>
<p v-show="debug">Debug panel</p>

Lists + class/style:

<li v-for="user in users" :key="user.id">{{ user.name }}</li>
<p :class="{ active: isActive, danger: hasError }">Status</p>
<p :style="{ fontSize: size + 'px' }">Big text</p>

4) Computed vs Methods vs Watchers

Methods – run every render

methods: {
  randomNumber() { return Math.random() }
}

Computed – cached until deps change

computed: {
  fullName() { return this.firstName + " " + this.lastName }
}

Watchers – side effects

watch: {
  email(newVal) { this.valid = newVal.includes("@") }
}

💡 Rule of thumb: Computed for derived values, Methods for actions, Watchers for effects


5) Components, Props & Events

Register + use:

app.component("user-card", {
  props: ["username", "role"],
  template: `<div><strong>{{ username }}</strong> ({{ role }})</div>`
})
<user-card :username="u.name" :role="u.role"></user-card>

Events up:

<!-- Child -->
<button @click="$emit('remove', id)">Remove</button>

<!-- Parent -->
<user-card @remove="removeUser"></user-card>
methods: { removeUser(id){ /* ... */ } }

List of components:

<user-card v-for="u in users"
  :key="u.id" :username="u.name" :role="u.role">
</user-card>

6) Dynamic Components & Keep‑Alive

<button @click="current='home-view'">Home</button>
<button @click="current='profile-view'">Profile</button>

<keep-alive>
  <component :is="current"></component>
</keep-alive>

💡 Switch with <component :is>. Use <keep-alive> to preserve state.


7) Lifecycle Hooks

created(){ /* data ready */ }
mounted(){ /* in DOM */ }
updated(){ /* after reactive changes */ }
unmounted(){ /* cleanup */ }

8) Composition API

const { ref, computed, watch } = Vue
createApp({
  setup() {
    const count = ref(0)
    const double = computed(() => count.value * 2)
    function inc(){ count.value++ }
    watch(count, (n,o) => console.log(o, "→", n))
    return { count, double, inc }
  }
}).mount("#app")
<div id="app">
  <p>Count: {{ count }}</p>
  <p>Double: {{ double }}</p>
  <button @click="inc">+1</button>
</div>

Full Code Examples (Lection 1–10)

Jump to:


Lection 1 – Introduction & Basics

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Vue Intro</title>
  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
  <div id="app">
    <h1>{{ message }}</h1>
  </div>
  <script>
    const { createApp } = Vue;
    const app = createApp({
      data() {
        return { message: "Hello Vue!" };
      }
    }).mount("#app");
  </script>
</body>
</html>

Lection 2 – v-model Forms

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Vue v-model Example</title>
  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
  <div id="app">
    <h2>Text Input</h2>
    <input v-model="name" placeholder="Enter your name">
    <p>Hello, {{ name }}!</p>

    <h2>Textarea</h2>
    <textarea v-model="message" placeholder="Write something..."></textarea>
    <p>You wrote: {{ message }}</p>

    <h2>Checkbox</h2>
    <input type="checkbox" v-model="accepted"> Accept terms?
    <p>Accepted: {{ accepted }}</p>

    <h2>Radio Buttons</h2>
    <input type="radio" value="male" v-model="gender"> Male
    <input type="radio" value="female" v-model="gender"> Female
    <p>Gender: {{ gender }}</p>

    <h2>Select Dropdown</h2>
    <select v-model="country">
      <option disabled value="">Please select</option>
      <option>USA</option>
      <option>UK</option>
      <option>Germany</option>
    </select>
    <p>Selected country: {{ country }}</p>
  </div>

  <script>
    const { createApp } = Vue;
    const app = createApp({
      data() {
        return {
          name: "",
          message: "",
          accepted: false,
          gender: "",
          country: ""
        };
      }
    }).mount("#app");
  </script>
</body>
</html>

Lection 3 – Core Directives

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Vue Directives Playground</title>
  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
  <style>
    .active { color: green; font-weight: bold; }
    .danger { color: crimson; }
    .badge { padding: 2px 6px; border: 1px solid #ccc; border-radius: 4px; }
    .info  { background: #eef; }
    .warn  { background: #ffe; }
  </style>
</head>
<body>
  <div id="app">
    <h1>Vue Directives</h1>

    <!-- v-bind (:) -->
    <h2>v-bind</h2>
    <img :src="avatarUrl" :alt="username + ' avatar'" width="60">
    <p>User: <a :href="profileLink" target="_blank">{{ username }}</a></p>

    <!-- v-on (@) -->
    <h2>v-on</h2>
    <button @click="count++">Clicked {{ count }} times</button>
    <div>
      <input v-model="live" placeholder="Type here">
      <p>Live: {{ live }}</p>
    </div>

    <!-- v-if / v-else -->
    <h2>v-if / v-else</h2>
    <button @click="loggedIn = !loggedIn">Toggle Login</button>
    <p v-if="loggedIn">Welcome back, {{ username }}!</p>
    <p v-else>Please log in to continue.</p>

    <!-- v-show -->
    <h2>v-show</h2>
    <label><input type="checkbox" v-model="debug"> Show debug</label>
    <pre v-show="debug">State: {{ $data }}</pre>

    <!-- v-for -->
    <h2>v-for</h2>
    <ul>
      <li v-for="user in users" :key="user.id">
        {{ user.name }} — <em>{{ user.role }}</em>
      </li>
    </ul>

    <!-- :class and :style -->
    <h2>:class / :style</h2>
    <label><input type="checkbox" v-model="isActive"> Active</label>
    <label><input type="checkbox" v-model="hasError"> Error</label>
    <label><input type="checkbox" v-model="faded"> Faded</label>
    <div :class="{ active: isActive, danger: hasError }"
         :style="{ fontSize: size + 'px', opacity: faded ? 0.5 : 1 }">
      Dynamic style / class text
    </div>
    <label>Size: <input type="range" min="12" max="48" v-model.number="size"></label>

    <p :class="['badge', badgeType]">Badge with array class</p>
    <select v-model="badgeType">
      <option value="info">info</option>
      <option value="warn">warn</option>
    </select>
  </div>

  <script>
    const { createApp } = Vue;
    const app = createApp({
      data() {
        return {
          username: "amy",
          profileLink: "https://example.com/u/amy",
          avatarUrl: "https://avatars.githubusercontent.com/u/9919?s=60&v=4",
          count: 0,
          live: "",
          loggedIn: false,
          debug: false,
          users: [
            { id: 1, name: "Amy", role: "Admin" },
            { id: 2, name: "Milan", role: "Editor" },
            { id: 3, name: "Sophy", role: "Viewer" }
          ],
          isActive: true,
          hasError: false,
          faded: false,
          size: 18,
          badgeType: "info"
        };
      }
    }).mount("#app");
  </script>
</body>
</html>

Lection 4 – Computed & Watchers

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Vue – Computed & Watcher</title>
  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
  <div id="app">
    <h1>Computed & Watcher</h1>
    <h2>Computed full name</h2>
    <input v-model="firstName" placeholder="First name">
    <input v-model="lastName" placeholder="Last name">
    <p>Full name: {{ fullName }}</p>

    <h2>Watcher email validation</h2>
    <input v-model="email" placeholder="Enter email">
    <p>Status: {{ status }}</p>
  </div>

  <script>
    const { createApp } = Vue;
    const app = createApp({
      data() {
        return {
          firstName: "",
          lastName: "",
          email: "",
          status: "Waiting..."
        };
      },
      computed: {
        fullName() { return this.firstName + " " + this.lastName; }
      },
      watch: {
        email(newVal) {
          this.status = newVal.includes("@") ? "Looks good ✅" : "Invalid email ❌";
        }
      }
    }).mount("#app");
  </script>
</body>
</html>

Lection 5 – Methods vs Computed vs Watchers

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Vue – Methods vs Computed vs Watchers (Clarified)</title>
  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
  <style>
    body { font-family: system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif; line-height: 1.4; padding: 20px; }
    .box { border: 1px solid #ddd; padding: 12px; border-radius: 8px; margin: 12px 0; }
  </style>
</head>
<body>
  <div id="app">
    <h1>Methods vs Computed vs Watchers – Re-render Demo</h1>

    <div class="box">
      <h2>Re-render triggers</h2>
      <button @click="forceRender++">Force re-render</button>
      <button @click="count++">Increase count</button>
      <p><strong>forceRender:</strong> {{ forceRender }}</p>
      <p><strong>count:</strong> {{ count }}</p>
    </div>

    <div class="box">
      <h2>Method (no caching)</h2>
      <p>Method value: <strong>{{ randomNumber() }}</strong></p>
    </div>

    <div class="box">
      <h2>Computed (cached until dependency changes)</h2>
      <p>Computed value: <strong>{{ randomNumberCached }}</strong></p>
      <button @click="seed++">Change seed (refresh computed)</button>
      <p><strong>seed:</strong> {{ seed }}</p>
    </div>

    <div class="box">
      <h2>Watcher (side effects)</h2>
      <p>Status: {{ status }}</p>
    </div>
  </div>

  <script>
    const { createApp } = Vue;
    const app = createApp({
      data() {
        return {
          forceRender: 0,
          count: 0,
          status: "Not yet 5",
          seed: 1
        };
      },
      methods: {
        randomNumber() { return Math.random(); }
      },
      computed: {
        randomNumberCached() {
          // Depends on seed -> only changes when seed changes
          return Math.random() * this.seed;
        }
      },
      watch: {
        count(newVal) {
          this.status = newVal >= 5 ? "Reached 5 or more!" : "Not yet 5";
        }
      }
    }).mount("#app");
  </script>
</body>
</html>

Lection 6 – Components & Lists

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Vue Components & Lists</title>
  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
  <style>
    .card {
      border: 1px solid #ddd;
      border-radius: 8px;
      padding: 12px;
      margin: 8px 0;
      background: #f9f9f9;
    }
    .role { font-size: 0.9em; color: #666; }
  </style>
</head>
<body>
  <div id="app">
    <h1>User List</h1>

    <user-card
      v-for="user in users"
      :key="user.id"
      :username="user.name"
      :role="user.role">
    </user-card>

    <button @click="addUser">Add random user</button>
  </div>

  <script>
    const { createApp } = Vue;

    const app = createApp({
      data() {
        return {
          users: [
            { id: 1, name: "Amy", role: "Admin" },
            { id: 2, name: "Milan", role: "Editor" },
            { id: 3, name: "Sophy", role: "Viewer" }
          ]
        };
      },
      methods: {
        addUser() {
          const id = this.users.length + 1;
          const names = ["Tom", "Maggy", "Zahira", "Ed"];
          const roles = ["Guest", "Member", "Owner"];
          const name = names[Math.floor(Math.random() * names.length)];
          const role = roles[Math.floor(Math.random() * roles.length)];
          this.users.push({ id, name, role });
        }
      }
    });

    app.component("user-card", {
      props: ["username", "role"],
      template: `
        <div class="card">
          <strong>{{ username }}</strong>
          <div class="role">{{ role }}</div>
        </div>
      `
    });

    app.mount("#app");
  </script>
</body>
</html>

Lection 7 – Props & Events

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Vue – Props & Events</title>
  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
  <style>
    .card { border: 1px solid #ddd; border-radius: 6px; padding: 10px; margin: 6px 0; }
    .role { font-size: 0.9em; color: #555; }
    button { margin-left: 10px; }
  </style>
</head>
<body>
  <div id="app">
    <h1>User List</h1>

    <user-card
      v-for="user in users"
      :key="user.id"
      :username="user.name"
      :role="user.role"
      @remove="removeUser(user.id)">
    </user-card>

    <button @click="addUser">Add random user</button>
  </div>

  <script>
    const { createApp } = Vue;

    const app = createApp({
      data() {
        return {
          users: [
            { id: 1, name: "Amy", role: "Admin" },
            { id: 2, name: "Milan", role: "Editor" },
            { id: 3, name: "Sophy", role: "Viewer" }
          ]
        };
      },
      methods: {
        addUser() {
          const id = this.users.length + 1;
          const names = ["Tom", "Maggy", "Zahira", "Ed"];
          const roles = ["Guest", "Member", "Owner"];
          const name = names[Math.floor(Math.random() * names.length)];
          const role = roles[Math.floor(Math.random() * roles.length)];
          this.users.push({ id, name, role });
        },
        removeUser(id) {
          this.users = this.users.filter(u => u.id !== id);
        }
      }
    });

    app.component("user-card", {
      props: ["username", "role"],
      template: `
        <div class="card">
          <strong>{{ username }}</strong>
          <span class="role">({{ role }})</span>
          <button @click="$emit('remove')">Remove</button>
        </div>
      `
    });

    app.mount("#app");
  </script>
</body>
</html>

Lection 8 – Dynamic Components & Keep-Alive

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Vue – Dynamic Components</title>
  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
  <style>
    .tabs button { margin: 5px; padding: 5px 10px; }
    .active { font-weight: bold; }
    .view { border: 1px solid #ccc; padding: 10px; margin-top: 10px; }
  </style>
</head>
<body>
  <div id="app">
    <h1>Dynamic Components (Tabs)</h1>

    <div class="tabs">
      <button
        v-for="tab in tabs"
        :key="tab"
        @click="currentView = tab"
        :class="{ active: currentView === tab }">
        {{ tab }}
      </button>
    </div>

    <keep-alive>
      <component :is="currentView" class="view"></component>
    </keep-alive>
  </div>

  <script>
    const { createApp } = Vue;

    const app = createApp({
      data() {
        return {
          tabs: ["home-view", "about-view", "profile-view"],
          currentView: "home-view"
        };
      }
    });

    app.component("home-view", {
      template: `<div><h2>Home</h2><p>Welcome to the homepage!</p></div>`
    });

    app.component("about-view", {
      template: `<div><h2>About</h2><p>This is an app built with Vue.</p></div>`
    });

    app.component("profile-view", {
      data() {
        return { name: "Amy" };
      },
      template: `
        <div>
          <h2>Profile</h2>
          <p>Edit your name:</p>
          <input v-model="name">
          <p>Hi, {{ name }}!</p>
        </div>`
    });

    app.mount("#app");
  </script>
</body>
</html>

Lection 9 – Lifecycle Hooks

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Vue – Lifecycle Hooks</title>
  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
  <style>
    .tabs button { margin: 5px; padding: 5px 10px; }
    .active { font-weight: bold; }
    .view { border: 1px solid #ccc; padding: 10px; margin-top: 10px; }
  </style>
</head>
<body>
  <div id="app">
    <h1>Lifecycle Demo (Check Console)</h1>

    <div class="tabs">
      <button
        v-for="tab in tabs"
        :key="tab"
        @click="currentView = tab"
        :class="{ active: currentView === tab }">
        {{ tab }}
      </button>
    </div>

    <component :is="currentView" class="view"></component>
  </div>

  <script>
    const { createApp } = Vue;

    const app = createApp({
      data() {
        return {
          tabs: ["home-view", "about-view"],
          currentView: "home-view"
        };
      }
    });

    app.component("home-view", {
      template: `<div><h2>Home</h2><p>Welcome to the homepage!</p></div>`,
      created() { console.log("Home created"); },
      mounted() { console.log("Home mounted"); },
      updated() { console.log("Home updated"); },
      unmounted() { console.log("Home unmounted"); }
    });

    app.component("about-view", {
      data() { return { counter: 0 }; },
      template: `
        <div>
          <h2>About</h2>
          <p>This is an app built with Vue.</p>
          <button @click="counter++">Counter: {{ counter }}</button>
        </div>`,
      created() { console.log("About created"); },
      mounted() { console.log("About mounted"); },
      updated() { console.log("About updated"); },
      unmounted() { console.log("About unmounted"); }
    });

    app.mount("#app");
  </script>
</body>
</html>

Lection 10 – Composition API

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Vue – Composition API</title>
  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
  <div id="app">
    <h1>Options API</h1>
    <p>Count: {{ count }}</p>
    <p>Double: {{ double }}</p>
    <button @click="increment">+1</button>
  </div>

  <div id="app2">
    <h1>Composition API</h1>
    <p>Count: {{ count }}</p>
    <p>Double: {{ double }}</p>
    <button @click="increment">+1</button>
  </div>

  <script>
    const { createApp, ref, computed, watch } = Vue

    // Options API
    createApp({
      data() {
        return { count: 0 }
      },
      computed: {
        double() { return this.count * 2 }
      },
      methods: {
        increment() { this.count++ }
      }
    }).mount("#app")

    // Composition API
    createApp({
      setup() {
        const count = ref(0)
        const double = computed(() => count.value * 2)
        function increment() { count.value++ }
        watch(count, (newVal, oldVal) => {
          console.log("Count changed:", oldVal, "→", newVal)
        })
        return { count, double, increment }
      }
    }).mount("#app2")
  </script>
</body>
</html>

About

A compact Vue.js Crash Course - Cheatsheet with Code Examples in 10 Lections

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published