a first look at nuxtJS part 3 - route parameters, dynamic pages
nuxtvuejavascriptaxiosIn the last part we created a layout for navigation with the <NuxtLink>
component. We also created a Mountain
component to fetch data with Nuxt's built in fetch
hook. In this part, we will use the @nuxtjs/axios
module to query the Dad Jokes API and create dynamic pages with the Joke id
.
Install @nuxtjs/axios
dependency #
yarn add @nuxtjs/axios
Add @nuxtjs/axios
to modules
in config file #
// nuxt.config.js
export default {
target: 'static',
components: true,
modules: [
'@nuxtjs/axios',
]
}
Jokes page #
Create a Jokes
directory with an index.vue
file.
mkdir pages/Jokes
touch pages/Jokes/index.vue
Include an <h2>
tag as a placeholder.
// pages/Jokes/index.vue
<template>
<div>
<h2>Jokes</h2>
</div>
</template>
Enter localhost:3000/jokes
to navigate to the new page.
Import axios
and make a get
request to https://icanhazdadjoke.com/search
.
// pages/Jokes/index.vue
<template>
...
</template>
<script>
import axios from "axios"
export default {
async created() {
const config = {
headers: {
Accept: "application/json"
}
}
try {
const res = await axios.get(
"https://icanhazdadjoke.com/search",
config
)
console.log(res)
} catch (err) {
console.log(err)
}
}
}
</script>
If we check the network tab in our browser we can see the response.
{
"current_page":1,
"limit":20,"next_page":2,
"previous_page":1,
"results":
[
{
"id":"0189hNRf2g",
"joke":"I'm tired of following my dreams. I'm just going to ask them where they are going and meet up with them later."
},
{ ... }
],
"search_term":"",
"status":200,
"total_jokes":649,
"total_pages":33
}
To map over the list of jokes we will need to set res.data.results
to this.jokes
.
// pages/Jokes/index.vue
<template>
...
</template>
<script>
import axios from "axios"
export default {
data() {
return {
jokes: []
}
},
async created() {
const config = {
headers: {
Accept: "application/json"
}
}
try {
const res = await axios.get(
"https://icanhazdadjoke.com/search",
config
)
this.jokes = res.data.results
console.log(this.jokes)
} catch (err) {
console.log(err)
}
}
}
</script>
If we console.log(this.jokes)
we get the array of jokes.
Joke component #
Create Joke
component.
touch components/Joke.vue
// components/Joke.vue
<template>
<div class="joke">
<p></p>
</div>
</template>
<script>
export default {
name: "Joke",
props: [
"joke",
"id"
]
}
</script>
<style>
.joke {
padding: .75rem;
border: 1px solid black;
border-radius: .5rem;
margin: .75rem 0;
font-size: 1.25rem;
}
</style>
Import Joke
component into Joke page #
// pages/Jokes/index.vue
<template>
<div>
<h2>Jokes</h2>
<Joke
v-for="joke in jokes"
:key="joke.id"
:id="joke.id"
:joke="joke.joke"
/>
</div>
</template>
<script>
...
</script>
Joke page #
Dynamic pages can be created when you don't know the name of the page due to it coming from an API or you don't want to create the same page over and over. A dynamic page can be created with an underscore before:
- The
.vue
file name - The name of the directory
Create a dynamic directory inside pages/Jokes
called _id
.
mkdir pages/Jokes/_id
touch pages/Jokes/_id/index.vue
After defining a file named _slug.vue
in your pages folder, you can access the value using the context with params.slug
, which in our case is params.id
.
// pages/Jokes/_id/index.vue
<template>
<div>
<NuxtLink to="/jokes">
Back To Jokes
</NuxtLink>
<h2>
{{ joke }}
</h2>
<small>
ID: {{ $route.params.id }}
</small>
</div>
</template>
<script>
import axios from "axios"
export default {
data() {
return {
joke: {}
}
},
async created() {
const config = {
headers: {
Accept: "application/json"
}
}
try {
const res = await axios.get(
`https://icanhazdadjoke.com/j/${this.$route.params.id}`,
config
)
this.joke = res.data.joke
} catch (err) {
console.log(err)
}
}
}
</script>
If we use an id
from earlier in the article (0189hNRf2g
) we can visit a dynamic page.
Add <NuxtLink>
to link to dynamic pages #
We can link to pages for any joke by including <NuxtLink :to="'jokes/' + id">
in our Joke
component.
// components/Joke.vue
<template>
<NuxtLink :to="'jokes/' + id">
<div class="joke">
<p></p>
</div>
</NuxtLink>
</template>
<script>
...
</script>
<style>
...
</style>
Add Jokes route to layout #
Lastly, add a link to the /jokes
route in the navigation bar.
// layouts/default.vue
<template>
<div class="container">
<header>
<h1>ajcwebdev</h1>
<nav>
<ul>
<li>
<NuxtLink to="/">Home</NuxtLink>
</li>
<li>
<NuxtLink to="/about">About</NuxtLink>
</li>
<li>
<NuxtLink to="/jokes">Jokes</NuxtLink>
</li>
</ul>
</nav>
</header>
<main>
<Nuxt />
</main>
<footer>
...
</footer>
</div>
</template>
<style>
...
</style>
Now we can navigate to the /jokes
route from any page.