
Daniel Kelly
Lead Instructor @ Vue School
Full Stack developer (10 + years)
Husband and Father
presentation Icons from fontawesome.com


We've
Got
The
Meats
The Game-Changer Your New Projects Deserve

ue
&
❌
The Game-Changer Your New Projects Deserve

ue
&
We've got the meats

ue
&
Both have a lot of great things going on
How do I know?
🤔

ue
It's used worldwide by many successful companies, agencies, and governments.












ue
Vue Core is
- easy to learn
- yet has robust functionality
- a stable/proven framework
- still pushing the boundaries with features like Vapor Mode
has a lot of great things going on!
The Vue Ecosystem is 🔥
But it doesn't stop there...
Lot's of Quality UI Libraries
Quality









Lot's of Quality UI Libraries
Quality




Several are perfect for use with

Some screenshots of my favorite shad-cn

Some screenshots of my favorite shad-cn


Some screenshots of my favorite shad-cn



Need to make mobile apps?
Vue can do that too

Quasar
supports:
- SPAs
- SSRs
- PWAs
- Mobile app
- Desktop apps
- Browser Extension
Need to make API requests?
Of course you do!
- Backend agnostic
- Dedicated Devtools
- Auto Caching
- Auto Refetching
- Window Focus Refetching
- Polling/Realtime Queries
- Parallel Queries
- Dependent Queries
- Mutations API
- Automatic Garbage Collection
- Data Selectors
- Paginated/Cursor Queries
- Load-More/Infinite Scroll Queries
- Scroll Recovery
- Request Cancellation
- Suspense Ready!
- Render-as-you-fetch
- Prefetching
- Variable-length Parallel Queries
- Offline Support
- SSR Support

There's a Vue solution for that
Vue
Need to interact with browser API's?
My bet is on yes
-
useGeolocation
-
useIdle
-
useLocalStorage
-
useKeyModifier
-
useInfiniteScroll
-
useOnline
-
useSelectedText
-
useClipboard
-
useBluetooth
-
useFavicon
-
useFileSystemAccess
-
useDark
-
useCssVar
-
useWebNotification
🔥 200 +
can handle that easily and intuitively

useLocalStorage Example
Need to robust form functionality?
Need to robust form functionality?

<FormKit
type="text"
label="Your Email"
name="email"
prefix-icon="email"
placeholder="email@domain.com"
validation="required|email"
help="Order confirmation will be sent to your address"
/>
Built-in validation or validation with zod

Smart
submission
states

Let's talk about
It supports end-to-end TypeSafety out of the box

the API endpoint is auto-completed for you


The response is correctly typed!
Event the accepted methods are typed

Note the suffix just before the file type
Event the accepted methods are typed

Rendering options in Nuxt are also insane!
You can generate pages on demand with server-side rendering
You can generate pages on demand with server-side rendering
or
You can statically generate them all at build time
You can generate pages on demand with server-side rendering
You can statically generate them all at build time
You can render completely in the client
or
Or you can mix and match these at the page level
export default defineNuxtConfig({
routeRules: {
// Homepage pre-rendered at build time
'/': { prerender: true },
// Blog posts page generated on demand, revalidates in background,
// cached on CDN for 1 hour (3600 seconds)
'/blog': { isr: 3600 },
// Blog post page generated on demand once
// until next deployment, cached on CDN
'/blog/**': { isr: true },
// Admin dashboard renders only on client-side
'/admin/**': { ssr: false },
}
})
Or you can render on client or server even at the component level!
// given a file exists at
// components/Comments.client.vue
<template>
<div>
<!-- this component will only be rendered on client side -->
<Comments />
</div>
</template>
Client-only components
// given a file exists at
// components/HighlightedMarkdown.server.vue
<template>
<div>
<!--
this will automatically be rendered on the server,
meaning your markdown parsing + highlighting
libraries are not included in your client bundle.
-->
<HighlightedMarkdown markdown="# Headline" />
</div>
</template>
Server-only components

ue
Crash Course
for the beginners

ue
Crash Course
Single File Components (SFC)
<!-- HelloFEN.vue -->
<script setup lang="ts">
const msg = "Hello Frontend Nation 👋"
</script>
<template>
<h1>{{ msg }}</h1>
</template>
<style scoped>
h1 {
font-size: 2em;
}
</style>


ue
Crash Course
<script setup>
const msg = ref('Hello World');
</script>
Dead Simple Reactivity

ue
Crash Course
<script setup>
const msg = ref('Hello World');
setTimeout(() => {
msg.value = 'Hello Frontend Nation!';
}, 1000);
</script>
Just set data to a new value and the display re-renders

ue
Crash Course
<script setup>
const msg = ref('Hello World');
</script>
<template>
{{ msg }}
<input v-model="msg" />
</template>
SOOO easy to react to user input

ue
Crash Course
Auto-calculated and cached computed data
const users = ref([
{
id: 1,
votes: 0,
name: 'Debra Hunt',
avatar: '/debra-1.jpg'
},
// ...
]);
const top3Users = computed(() => {
return [...users.value]
.sort((a, b) => b.votes - a.votes)
.slice(0, 3)
.filter((user) => user.votes > 0);
});

ue
Crash Course
<script setup lang="ts">
const pokemons = ref([
"bulbasaur",
"charmander",
//...
]);
</script>
<template>
<ul v-auto-animate>
<li v-for="pokemon in pokemons" :key="pokemon">
<PokemonCard :slug="pokemon" />
</li>
</ul>
</template>
Display lists with v-for

ue
Crash Course
Conditional displays with v-if
<script setup>
import { ref } from 'vue';
const modalOpen = ref(false);
</script>
<template>
<div>
<button @click="modalOpen=false">Open Modal</button>
<ModalOverlay v-if="modalOpen" @close="modelOpen = false" />
</div>
</template>

ue
Crash Course
Flexible Easy Components for logic and display re-use
<script setup lang="ts">
const count = ref(0);
</script>
<template>
<button
class="text-white bg-blue-500 px-4 py-2 rounded"
@click="count++"
>
{{ count }}
</button>
</template>

ue
Crash Course
Flexible Easy Components for logic and display re-use
<template>
<div class="flex gap-3">
<Counter />
<Counter />
<Counter />
<Counter />
</div>
</template>

ue
Crash Course
export const useCounter = () => {
const count = ref(0);
const increment = () => count.value++;
return { count, increment };
};
Composables for stateful logic re-use without need to render

ue
Crash Course
<script setup lang="ts">
const { count, increment } = useCounter();
</script>
<template>
<button
class="text-white bg-blue-500 px-4 py-2 rounded"
@click="increment"
>
{{ count }}
</button>
</template>
Composables for stateful logic re-use without need to render

ue
Crash Course
Composables for stateful logic re-use without need to render

ue
Crash Course
export const useCounterStore = defineStore("CounterStore", () => {
const count = ref(0);
const increment = () => count.value++;
return { count, increment };
});
Pinia stores for sharing reactive data between components

ue
Crash Course
<script setup lang="ts">
const counter = useCounterStore();
</script>
<template>
<button
class="text-white bg-blue-500 px-4 py-2 rounded"
@click="counter.increment"
>
{{ counter.count }}
</button>
</template>
Pinia stores for sharing reactive data between components

ue
Crash Course
Pinia stores for sharing reactive data between components

ue
Crash Course
Flexible Easy Components for logic and display re-use
This is just a small taste of the Vue API
and what it can do!
But before I go!
certificates.dev

83% say the exam is moderate to difficult
74% say it actually helped improve their Vue.js skills
vue.school/masterclass



frontendnation.com
60+
Speakers












Grab Some Swag 🤗





danielkelly_io
I'll tweet out the slides after this

Thank you 🙏
Go code awesome things!
(with Vue 😉)
Nuxt + Vue: The Game-Changer Your New Projects Deserve
By Daniel Kelly
Nuxt + Vue: The Game-Changer Your New Projects Deserve
- 505