Boise Code Camp 2026

Back to Basics

Essential JavaScript Foundations
for Modern Vue 3 Development


Nerando Johnson  ·  @Nerajno

Hi, I'm Nerando ~

@Nerajno

  • Junior Frontend Dev at Hygiena — food safety tech software
  • former freeCodeCamp Atlanta organizer — 600+ members since 2018
  • Conference speaker · Tech Community Organizer
  • Bootcamp grad and self-taught developer · "Progress over Perfection"
Vue 3 TypeScript Pinia Supabase Nuxt ATL Dev Community
@Nerajno

Housekeeping


Disclaimer

Opinions are mine. Examples simplified for clarity. Vue 3 Composition API throughout.

CoC

Welcoming space. Be kind, curious, constructive. Questions welcome at any time.

Sponsors & Networking — "Links run di world" 🇯🇲

Note to Self

"May your console errors be zero
and your reactivity be perfect."

Inspired by Shepard's Prayer · May 5, 1961

State of JS ~ 2025

Source: State of JavaScript 2024 survey · State of Vue.js Report 2025

62%

of all devs use JavaScript — #1 language 12+ years running (Stack Overflow 2024)

#2

Vue.js at ~45% usage — firmly the #2 frontend framework globally behind React

3.3M+

live sites built with Vue — doubled in two years, still growing

Vite: 69% adoption · Most loved build tool. Nuxt: #2 meta-framework. Vue sentiment steady at 65–75% positive.

The Problem

Devs jump into Vue before understanding the JavaScript powering it

Reactivity bugs feel like "Vue bugs" — they're JS bugs in a costume

npm create vue@latest is line 1 of too many tutorials

The issue isn't Vue — it's the missing JS foundation underneath it

The Real Problem

● misconception.js
// What tutorials start with:
import { createApp } from 'vue'

// What you actually need first:
const foundation = {
  variables:     '✓ understand scope & types',
  arrowFns:      '✓ lexical this binding',
  asyncAwait:    '✓ promises under the hood',
  destructuring: '✓ props & composable returns',
  modules:       '✓ every import you write',
}

// Vue = JavaScript + opinions ✨

Framework ≠ JavaScript.  Framework = JavaScript + opinions.

Agenda

01

JS Fundamentals — the 11 concepts you need

02

Learning Bottom Up — why order matters

03

Fundamental → Vue 3 — every concept applied

04

Examples — real code, real patterns

05

Recommendations — what to do after this talk

The 11 Fundamentals

Non-negotiable before you go deep on Vue 3

Variables & Data Types
Template Literals
Arrow Functions
Objects & Destructuring
Arrays & Array Methods
Promises & Async/Await
Modules & Exports
Classes & OOP
Optional Chaining
Event Handling
Error Handling
JS first. Vue second.

Learning Happens Bottom Up

JavaScript Fundamentals — scope, closures, async, modules

Vue 3 Primitives — ref, reactive, computed, watch

Vue 3 Patterns — composables, Pinia, Vue Router, lifecycle

Production Apps — Nuxt, SSR, performance, scale

Skip the base, shake the tower. Every Composition API pattern traces back to vanilla JS.

01

Variables &
Data Types

The atoms of every JS program — and every Vue component

Concept → Vue 3
Variables & Data Types

Declarations map directly to reactivity APIs

let = reassignable · const = fixed reference · Know your primitives: string, number, boolean, null, undefined, symbol, bigint

const name = "Nerando"; // string
let score = 42;          // number
let isActive = true;     // boolean
const user = { id: 1 }; // object
const tags = ["vue"];    // array
● Vue 3 — ref() & reactive()
import { ref, reactive } from 'vue'

// ref wraps primitives
const name = ref("Nerando")
const score = ref(42)
const isActive = ref(true)

// reactive wraps objects
const user = reactive({
  id: 1,
  role: "developer"
})
// .value for ref, direct for reactive
console.log(name.value) // "Nerando"
console.log(user.role)  // "developer"
02

Template
Literals

Backticks that power your bindings

Concept → Vue 3
Template Literals

Embedded expressions — used daily in Vue bindings

Backticks (`) embed expressions: `Hello, ${name}!`. Multiline, expression-aware, composable.

const role = "developer"
const msg = `Hello, ${name}!
You are a ${role}.`

// Expression inside
const total =
  `$${(qty * 9.99).toFixed(2)}`
● Vue 3 usage
// Computed string
const greeting = computed(() =>
  `Welcome back, ${user.name}!`
)

// Dynamic :class binding
// in template
// :class="`btn ${isActive
//   ? 'btn--active'
//   : 'btn--idle'}`"

// Dynamic route path
const path = computed(() =>
  `/users/${userId.value}/profile`
)
03

Arrow
Functions

The backbone of the Composition API

Concept → Vue 3
Arrow Functions

Concise syntax + lexical this — critical for Composition API

// Traditional
function add(a, b) { return a+b }

// Arrow — implicit return
const add = (a, b) => a + b

// Arrow with body
const greet = (name) => {
  return `Hello, ${name}`
}

// In array methods
const evens =
  [1,2,3,4].filter(n => n%2===0)
● Vue 3 Composition API
const count = ref(0)

// computed uses arrow callback
const doubled = computed(
  () => count.value * 2
)

// watch uses arrow callback
watch(count, (newVal, oldVal) => {
  console.log(`${oldVal} → ${newVal}`)
})

// event handler in <script setup>
const handleClick = () => {
  count.value++
}
04

Objects &
Destructuring

How composables return values to you

Concept → Vue 3
Objects & Destructuring

Extract exactly what you need — composables depend on this

const user = {
  name: "Nerando",
  role: "dev",
  city: "Atlanta"
}
// Destructure
const { name, role } = user
// Rename
const { name: devName } = user
// Default value
const { theme = "dark" } = user
// Array destructure
const [first,,third] = ["a","b","c"]
● Vue 3 — composable returns
// defineProps destructuring
const { title, count } =
  defineProps(['title', 'count'])

// Composable return destructure
const { data, error, pending } =
  useFetch('/api/users')

// Route params
const { params, query } = useRoute()

// Pinia store destructure
// (use storeToRefs to keep reactivity!)
const { user, isAuth } =
  storeToRefs(useAuthStore())

Vue 3 gotcha: destructuring a reactive() object breaks reactivity — use toRefs() or storeToRefs()

👏

Halfway Point

4 of 11 done. Questions before we continue?

@Nerajno
05

Arrays &
Array Methods

.map() .filter() .reduce() — your v-for fuel

Concept → Vue 3
Arrays & Array Methods

Data transformation — the engine behind v-for

const nums = [1, 2, 3, 4, 5]

// transform each item
const doubled =
  nums.map(n => n * 2)
// [2, 4, 6, 8, 10]

// keep matching items
const evens =
  nums.filter(n => n % 2 === 0)
// [2, 4]

// accumulate
const sum =
  nums.reduce((acc,n) => acc+n, 0)
// 15
● Vue 3 — v-for + computed
<!-- template -->
<li
  v-for="item in activeItems"
  :key="item.id"
>
  {{ item.name }}
</li>

<!-- script setup -->
<script setup>
const items = ref([...])

const activeItems = computed(() =>
  items.value
    .filter(i => i.active)
    .sort((a, b) =>
      a.name.localeCompare(b.name))
)
</script>
06

Promises &
Async/Await

onMounted, useAsyncData, and every API call you'll ever write

Concept → Vue 3
Promises & Async/Await

Async operations — the foundation of data fetching in Vue

// Promise chain
fetch('/api/user')
  .then(r => r.json())
  .then(d => console.log(d))
  .catch(e => console.error(e))

// async/await — cleaner
async function getUser() {
  try {
    const res = await fetch('/api/user')
    return await res.json()
  } catch (err) {
    console.error('Failed:', err)
  }
}
● Vue 3 — onMounted + async
const data = ref(null)
const error = ref(null)
const loading = ref(false)

onMounted(async () => {
  loading.value = true
  try {
    const res = await fetch('/api/data')
    data.value = await res.json()
  } catch (e) {
    error.value = e.message
  } finally {
    loading.value = false
  }
})

Nuxt users: useAsyncData() and useFetch() are built on this exact pattern

07

Modules &
Exports

Every composable is a module. Every import is this.

Concept → Vue 3
Modules & Exports

ES Modules → Composables

// math.js — named exports
export const add = (a, b) => a + b
export const PI = 3.14159

// user.js — default export
export default function createUser(n) {
  return { name: n, active: true }
}

// app.js
import createUser from './user.js'
import { add } from './math.js'
● Vue 3 — composables as modules
// composables/useCounter.js
import { ref } from 'vue'

export function useCounter(initial = 0) {
  const count = ref(initial)
  const inc = () => count.value++
  const dec = () => count.value--
  const reset = () =>
    count.value = initial

  return { count, inc, dec, reset }
}

// MyComponent.vue <script setup>
import { useCounter }
  from '@/composables/useCounter'

const { count, inc } = useCounter(10)
08

Classes &
OOP

Blueprints for custom directives & plugins

Concept → Vue 3
Classes & OOP

Useful for Vue plugins, directives & complex state models

class ApiClient {
  constructor(baseURL) {
    this.baseURL = baseURL
    this.headers = {
      'Content-Type': 'application/json'
    }
  }

  async get(path) {
    const res = await fetch(
      `${this.baseURL}${path}`,
      { headers: this.headers }
    )
    return res.json()
  }
}
● Vue 3 — Plugin pattern
// plugins/apiClient.js
class ApiClient { /* ... */ }

export default {
  install(app, options) {
    const client =
      new ApiClient(options.baseURL)

    // Available via inject()
    app.provide('api', client)

    // Or as global property
    app.config.globalProperties.$api =
      client
  }
}
// main.js
app.use(ApiClientPlugin, {
  baseURL: 'https://api.example.com'
})
09

Optional
Chaining

Navigate API responses safely — every time

Concept → Vue 3
Optional Chaining & Nullish Coalescing

Safe access — most adopted JS feature in State of JS 2024

// Without optional chaining
const city =
  user && user.address
    ? user.address.city
    : undefined

// With optional chaining ✨
const city = user?.address?.city

// Call functions safely
const str = name?.toUpperCase()

// Nullish coalescing fallback
const display = city ?? "Atlanta"
● Vue 3 — templates & computed
<!-- Template — safe access -->
<p>{{ user?.profile?.bio }}</p>
<p>{{ post?.author?.name ?? 'Anonymous' }}</p>

<!-- Script setup -->
const city = computed(() =>
  store.user?.address?.city ?? 'N/A'
)

// In watch — handle undefined initial
watch(user, (u) => {
  if (u?.isAdmin) enableAdminMenu()
})
10

Event
Handling

@click is just addEventListener with Vue superpowers

Concept → Vue 3
Event Handling

Vue's event system is native JS events + directive sugar

// Native JS
el.addEventListener('click', (e) => {
  console.log(e.target)
  e.preventDefault()
  e.stopPropagation()
})

// Event object properties
// e.target — element clicked
// e.currentTarget — listener element
// e.key — for keyboard events
// e.detail — for custom events
● Vue 3 — v-on / @ directives
<!-- Basic -->
<button @click="handleClick">Go</button>

<!-- .prevent modifier -->
<form @submit.prevent="onSubmit">

<!-- .stop modifier -->
<div @click.stop="doSomething">

<!-- Emit custom events -->
<!-- child component -->
const emit = defineEmits(['update'])
emit('update', { value: 42 })

<!-- parent -->
<Child @update="handleUpdate" />
11

Error
Handling

Fail gracefully. Your users deserve it.

Concept → Vue 3
Error Handling

try/catch in JS → onErrorCaptured in Vue 3

// Synchronous
try {
  riskyOperation()
} catch (err) {
  console.error(err.message)
} finally {
  cleanup()
}

// Async
async function load() {
  try {
    const data = await fetchData()
    return data
  } catch (err) {
    // Handle fetch errors
    notifyUser(err.message)
  }
}
● Vue 3 — error lifecycle hooks
// In a parent/layout component
onErrorCaptured((err, instance, info) => {
  console.error('Vue caught:', err)
  errorLog.value = {
    message: err.message,
    component: info
  }
  return false // stop propagation
})

// Global handler in main.js
app.config.errorHandler = (err, vm, info) => {
  // Send to Sentry, Datadog, etc.
  trackError(err, info)
}
🎉

All 11 Concepts — Done!

Every one of those is JavaScript. Every one shows up in your Vue 3 code today.

@Nerajno

Examples ~ In Practice

Build these in vanilla JS first — then translate to Vue 3. See the 1:1 map.

🌤️

Weather App

async/await · optional chaining · template literals · ref()

🎨

BG Color Picker

event handling · template literals · reactive() · v-model

✅

Todo App

.map() .filter() · modules · composables · Pinia

All three available on GitHub — links in the comments after the talk.

Recommendations ~ What's Next

Leave with a plan, not just slides

📚

Solidify JS First

javascript.info is the best free resource for fundamentals. Read the "JavaScript Fundamentals" and "Advanced" sections before your next Vue project.

🔬

Read Vue Source

Open node_modules/vue/dist/vue.esm-browser.js — find ref() and read 20 lines. You'll see a plain JS class. Demystify the magic.

🧪

Build the Trio

Weather app → Color Picker → Todo. Vanilla JS first, Vue 3 second. Document every connection you find. Share it on dev.to or your blog.

🏗️

Write a Composable

Take one thing you've done in a component and extract it as a useX() composable. You'll immediately see which JS concepts power it.

Summary

Vue 3's Composition API is JavaScript. ref() is a class. computed() is a derived function. watch() is a callback on a closure. Composables are modules. Master the JS, and Vue becomes obvious.

Variables → ref() Literals → :class bindings Arrows → computed() Destructuring → composables .filter() → v-for computed async/await → onMounted Modules → composables Classes → plugins ?. → template safety Events → @click try/catch → onErrorCaptured

JS Concept → Vue 3 Application

JavaScript Concept Vue 3 Usage Key API / Pattern
Variables & Data TypesReactive state primitivesref() / reactive()
Template LiteralsDynamic class & route binding:class / computed()
Arrow FunctionsComposition API callbackscomputed() / watch()
DestructuringComposable & store returnsstoreToRefs() / toRefs()
Array MethodsFiltered & sorted list renderingv-for + computed()
Promises & Async/AwaitData fetching lifecycleonMounted() / useFetch()
Modules & ExportsComposable architectureuseX() pattern
Classes & OOPPlugins & provide/injectapp.use() / provide()
Optional ChainingSafe template & store accessuser?.profile?.bio
Event HandlingDOM & component events@click / defineEmits()
try / catch / finallyComponent error boundariesonErrorCaptured()

Questions / Fin

Let's Talk. 🗣️


Nerando Johnson

@Nerajno  ·  Boise Code Camp 2026

Bluesky

@nerajno.bsky.social

LinkedIn

GitHub

Progress over Perfection. Let's go. 💚