Reputation: 31
I am new to vue and I am working on a project to fetch wordpress REST api. so I have "Posts" page and "Pages" page in my project, each one of them has different api endpoint and router links to every post/page in the loop with the slug name of the specific post/page.
When I press on the READ MORE router link button inside "Posts" page it sends me to the "Post" component with the post endpoint. When I press on the READ MORE router link button inside Pages page it also sends me to the "Post" component but I need to get the "Page" component to fetch the page data from the api.
I noticed that if I set the page component before the post component inside index.js so both Posts and Pages will open the page component.
How can I set the "Page" component to the "Pages" router link and the "Post" component to "Posts" router link?
index.js:
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
},
{
path: '/posts',
name: 'Posts',
component: () => import(/* webpackChunkName: "posts" */ '../views/Posts.vue')
},
{
path: '/pages',
name: 'Pages',
component: () => import(/* webpackChunkName: "pages" */ '../views/Pages.vue')
},
{
path: '/:pageSlug',
name: 'Page',
component: () => import(/* webpackChunkName: "page" */ '../components/Page/Page.vue')
},
{
path: '/:postSlug',
name: 'Post',
component: () => import(/* webpackChunkName: "post" */ '../components/Post/Post.vue')
},
]
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
})
router.afterEach((to) => { // (to, from)
// Add a body class specific to the route we're viewing
let body = document.querySelector('body');
const slug = !(to.params.postSlug)
? to.params.pageSlug
: to.params.postSlug;
body.classList.add('vue--page--' + slug);
});
export default router
Pages.vue:
<template>
<div>
<template v-if="pages">
<div class="pages">
<div class="row">
<div class="column" v-for="(page, index) in pages" :key="index">
<div class="card">
<div class="card-image">
<img
v-if="page._embedded['wp:featuredmedia']"
:src="page._embedded['wp:featuredmedia'][0].source_url"
/>
</div>
<div class="card-content" v-html="page.excerpt.rendered"></div>
<div class="card-action">
<h3>{{ page.title.rendered }}</h3>
</div>
</div>
<router-link :to="page.slug" tag="div" key="page.id">
READ MORE </router-link> //this is where I think the problem is..
</div>
</div>
</div>
</template>
<div id="loaded" v-else>Loading...</div>
</div>
</template>
<script>
import axios from "axios";
export default {
data() {
return {
// Wordpress Pages Endpoint
postsUrl: "https://my-domain.com/wp-json/wp/v2/pages",
queryOptions: {
per_page: 6, // Only retrieve the 6 most recent blog pages.
page: 1, // Current page of the collection.
_embed: true //Response should include embedded resources.
},
// Returned Pages in an Array
pages: []
};
},
methods: {
// Get Recent Pages From WordPress Site
getRecentMessages() {
axios
.get(this.postsUrl, { params: this.queryOptions })
.then(response => {
this.pages = response.data;
console.log("Pages retrieved!");
console.log(this.pages);
})
.catch(error => {
console.log(error);
});
},
},
mounted() {
this.getRecentMessages();
}
};
</script>
Posts.vue:
<template>
<div>
<template v-if="posts">
<div class="posts">
<div class="row">
<div class="column" v-for="(post, index) in post" :key="index">
<div class="card">
<div class="card-image">
<img
v-if="post._embedded['wp:featuredmedia']"
:src="post._embedded['wp:featuredmedia'][0].source_url"
/>
</div>
<div class="card-content" v-html="post.excerpt.rendered"></div>
<div class="card-action">
<h3>{{ post.title.rendered }}</h3>
</div>
</div>
<router-link :to="post.slug" tag="div" key="post.id">
READ MORE </router-link>
</div>
</div>
</div>
</template>
<div id="loaded" v-else>Loading...</div>
</div>
</template>
<script>
import axios from "axios";
export default {
data() {
return {
// Wordpress Posts Endpoint
postsUrl: "https://my-domain.com/wp-json/wp/v2/posts",
queryOptions: {
per_page: 6, // Only retrieve the 6 most recent blog posts.
page: 1, // Current page of the collection.
_embed: true //Response should include embedded resources.
},
// Returned Posts in an Array
posts: []
};
},
methods: {
// Get Recent Posts From WordPress Site
getRecentMessages() {
axios
.get(this.postsUrl, { params: this.queryOptions })
.then(response => {
this.posts= response.data;
console.log("Posts retrieved!");
console.log(this.posts);
})
.catch(error => {
console.log(error);
});
},
},
mounted() {
this.getRecentMessages();
}
};
</script>
Upvotes: 0
Views: 1040
Reputation: 31
OK So based on documentation here: https://router.vuejs.org/guide/essentials/named-routes.html I just changed the router links in "Posts" and "Pages" components to piont to their specific component for Posts.vue
You need to change :
<router-link :to="post.slug" tag="div" key="post.id">READ MORE </router-link>
With:
<router-link :to="{ name: 'Post', params: { postSlug: post.slug }}">READ MORE </router-link>
And the same for Pages.vue:
<router-link :to="{ name: 'Page', params: { pageSlug: page.slug }}">READ MORE </router-link>
Upvotes: 1