I have some products that are being iterated over and being displayed. I'd like to use the images of the products as links to the specific page of each individual product. I want each product page to pull from the same template, substituting the props with the appropriate product details.
An example url for a product would be something like: /shop/product/name-of-product
Here is the relevant code:
<template>
<div class="p-avaible" v-for="item in avaibleProducts" :key="item.name">
<router-link :to={ name: 'avaibleProducts' , params: { id: 1 }}>
<img :key="item.image" :src="item.image">
</router-link>
<div class="p-name">{{ item.name }}</div>
<div class="p-price">€{{ item.price }}</div>
<div class="btn-container">
<button class="add-to-cart">ADD TO CART</button>
</div>
</div>
</template>
<script>
export default {
data() {
return {
cart: [],
avaibleProducts: [
{
name: "PLASTIC BAGS 3-PACK v1",
price: 0.33,
image: require('#/assets/plastic-bag-pack.jpg'),
description: 'First version plastic bags pack containing 3 HQ assets. Make sure to get yours today.',
id: 1
},
{
name: "VINYL TEXTURES 2-PACK v1",
price: 0.22,
image: require('#/assets/vinyl-texture-pack.jpg'),
description: 'First version vinyl texture pack containing 2 HQ assets. Make sure to get yours today.',
id: 2
},
{
name: "STICKER PACK 6-PACK v1",
price: 0.66,
image: require('#/assets/sticker-bag-pack.jpg'),
description: 'First version sticker bag pack containing 6 HQ assets. Make sure to get yours today.',
id: 3
}
],
};
}
};
</script>
Router/Index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import Shop from '../views/Shop.vue'
import Product from '../views/Product'
Vue.use(VueRouter)
const routes = [
{
path: '/shop',
name: 'Shop',
component: Shop
},
{
path: '/product/:id',
name: Product,
component: Product
}
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
hey :)) first you must add a unique property to your product list like a uuid or anything, also you can use id property but its not a good method
step 1:
you must add uuid propery to your product object :
{
name: 'PLASTIC BAGS 3-PACK v1',
price: 0.33,
image: require('#/assets/plastic-bag-pack.jpg'),
description:
'First version plastic bags pack containing 3 HQ assets. Make sure to get yours today.',
id: 1,
uuid: 'prd-001' // pay attention to this line
},
step 2:
you need to create an computed propery
computed: {
showProduct() {
const id = this.$route.params.id;
const product = this.avaibleProducts.find((p) => p.uuid == id);
return product;
},
step 3:
and in your template you can access it like this:
<ul>
<li>{{ showProduct.name }} - {{ showProduct.price }} <!-- and etc ... {{ showProduct.image }} --></li>
</ul>
step 4:
you can load single product in this route:
/product/prd-001
the above route return your first product in your available products state
step 5:
change your this line in your Router/Index.js file
name: Product
and put it in single quotation like this :
name: 'Product'
and change your router-link like this :
<router-link :to="{name: 'Product' , params:{ id: product.uuid }}">{{ product.name}}</router-link>
well done!
You're missing one important part in your router index.js file. You need to enable prop passing in the Product components
Router/Index.js
{
path: '/product/:id',
name: Product,
component: Product,
props: true
}
Now you can actually pass props to your routes via a <router-link> element.
Now all you have to do is pass the appropriate props to the component. You can do this by emulating an API call on the component's created() hook.
I recommend you make a JSON file that you put somewhere in your src directory with all the details for the products. Instead of importing your image via webpack, just do it statically by putting the images in public/images.
You then need to make sure that the id is a unique URL-valid string if you want to use it as the param in the URL as you specified. It would look something like this:
#/assets/json/productList.json:
[
{
"id": "plastic-bag",
"name": "PLASTIC BAGS 3-PACK v1",
"price": 0.33,
"image": "/images/products/1.jpg",
"description": "First version plastic bags pack containing 3 HQ assets. Make sure to get yours today."
},
....
]
Then in your Product.vue component:
<template>
<div>
<img :src="product.image" alt="">
<h1>{{ product.name }}</h1>
<pre>${{ product.price }} USD</pre>
<p>{{ product.description }}</p>
</div>
</template>
<script>
import products from "#/assets/json/productList.json";
export default {
data() {
return {
product: null;
};
},
created() {
this.setProduct();
},
methods: {
setProduct() {
const currentProject = products.find(project => project.id === this.$route.params.id); // Find project via the route id param
this.product = currentProject;
}
}
};
</script>
Related
I would like to combine i18n with the Vue Router (vue3). I can setup the i18n module successfully but the integration into the routing system always fails.
The router-view is located in App.vue:
<template>
<div class="container">
<!-- Content here -->
<the-header></the-header>
<router-view></router-view>
</div>
</template>
<script>
import TheHeader from './components/TheHeader.vue'
export default {
name: 'App',
components: {
TheHeader
}
}
</script>
I access the language routes via a global object $t. The languager switcher works. So the following router-links in the TheHeader component contain the right paths to the language specific components (this.$i18n.locale always returns the right path-fragment: eg: 'en','de' etc.., this works!!):
<ul class="navbar-nav">
<li class="nav-item">
<router-link class="nav-link active" aria-current="page"
:to="`/${this.$i18n.locale}/home`">{{ $t('nav.home') }}</router-link>
</li>
<li class="nav-item">
<router-link class="nav-link" :to="`/${this.$i18n.locale}/about`">{{ $t(`nav.about`) }}
</router-link>
</li>
Now I stuck with the router. I found the following example here, but it does not work:
const router = createRouter({
history: createWebHistory(),
routes: [
{
path: "/:lang",
component: {
render: (h) => h("router-view"),
},
children: [
{
path: "home",
name: "home",
component: Home,
},
{
path: "design",
name: "design",
component: Design,
},
{
path: "about",
name: "about",
component: About,
},
{
path: "contact",
name: "contact",
component: Contact,
},
],
},
],
});
stack trace:
Uncaught (in promise) TypeError: h is not a function
at Proxy.render (router.js?41cb:15)
at renderComponentRoot (runtime-core.esm-bundler.js?5c40:464)
at ReactiveEffect.componentUpdateFn [as fn] (runtime-core.esm-bundler.js?5c40:4332)
at ReactiveEffect.run (reactivity.esm-bundler.js?a1e9:160)
at setupRenderEffect (runtime-core.esm-bundler.js?5c40:4458)
at mountComponent (runtime-core.esm-bundler.js?5c40:4241)
at processComponent (runtime-core.esm-bundler.js?5c40:4199)
at patch (runtime-core.esm-bundler.js?5c40:3791)
at ReactiveEffect.componentUpdateFn [as fn] (runtime-core.esm-bundler.js?5c40:4409)
at ReactiveEffect.run (reactivity.esm-bundler.js?a1e9:160)
Principally, the language switcher should work independently from the router, with the independent global variable $t. However, I need the complete path in the URL, I need an integration of i18n into the router! How can I configure the Vue Router correctly?
import { h, resolveComponent } from "vue";
path: "/:lang",
component: {
render() {
return h(resolveComponent("router-view"));
},
},
I built a blog with Gatsby and Tailwind using markdown for blog posts. When querying the data using graphql, I can't get any of the images to display. My images are stored within the src/ directory in an images/ folder. My posts are inside of a pages/ folder within that same directory. At one point the site displayed ALL of the images including the ones in markdown, but wouldn't work when deployed to Netlify. I've gotten the site to deploy, but now none of my images are showing and I've tried everything to get them back. I've also tried using gatsby-image (fixed and fluid) and still nothing.
This is my first project with gatsby, markdown, and graphql. Currently, the deployed site nikkipeel.netlify.app shows the proper path on the blog page for posts when inspected using devtools (../images/example.jpg), but still no image actually displays. 🤷♀️
Github repo: gatsby-blog
project structure:
|-- /public
|-- /src
|-- /components
|-- /pages
|-- /post-one
|--index.md
|-- /post-two
|--index.md
|-- /post-three
|--index.md
|-- /templates
|-- blog-post.js
|-- /images
|-- /static
|-- gatsby-config.js
|-- gatsby-node.js
|-- gatsby-ssr.js
|-- gatsby-browser.js
frontmatter for a blog post (index.md) -
---
path: "/create-a-blog-with-react-and-sanity"
date: "2021-01-10"
title: "Create a blog with React and Sanity"
description: "Create a technical blog built with React, TailwindCSS, and Sanity then deploy it using Github and Netlify"
category: "React"
author: "Nikki Peel"
authorImage: ../images/selfie.png
image: ../images/sanity-blog-collage.jpg
---
Blog.js with Graphql query for displaying all posts:
import React from "react"
import { graphql } from 'gatsby'
import Layout from "../components/layout"
import Link from 'gatsby-link';
import SEO from "../components/seo"
const BlogPage = ({ data }) => (
<Layout>
<SEO title="Blog" />
<main className="bg-brown text-white h-auto p-12">
<section className="container mx-auto">
<h1 className="text-4xl mono pl-4">Latest Blog Posts</h1>
<h2 className="text-lg mb-12 pl-4">Welcome to my page of blog posts</h2>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 justify-center mx-auto md:gap-8 mb-24">
{data.allMarkdownRemark.edges.map(post => (
<article>
<Link to={post.node.frontmatter.path}>
<div className="block lg:h-64 relative leading-snug" key={ post.node.id }>
<img src={post.node.frontmatter.image} alt="" className="lg:block w-full items-center lg:h-full lg:object-cover lg:object-top relative lg:absolute"/>
<span className="block relative lg:h-full lg:flex lg:items-end ">
<h3 className="lg:bg-gray-800 lg:bg-opacity-75 text-white text-xl font-semibold lg:px-3 lg:py-4 rounded text-left">{post.node.frontmatter.title}</h3>
</span>
<div className="mt-4 mb-8">
<p className="text-base mb-4">{post.node.frontmatter.description}</p>
<span id={post.node.frontmatter.category} className="text-black font-semibold text-sm py-2 px-4 mr-2 rounded">{post.node.frontmatter.category}</span>
<small className="text-base ml-2">📅 {post.node.frontmatter.date}</small>
</div>
</div>
</Link>
</article>
))}
</div>
</section>
</main>
</Layout>
)
export const pageQuery = graphql`
query BlogIndexQuery {
allMarkdownRemark (sort: { fields: [frontmatter___date], order: DESC }){
edges {
node {
id
frontmatter {
path
title
description
date
category
image
}
}
}
}
}
`;
export default BlogPage;
And for Single Posts - blog-post.js:
import React from 'react';
import { graphql } from 'gatsby'
import Link from 'gatsby-link';
import Layout from '../components/layout';
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome';
import { faChevronLeft } from '#fortawesome/free-solid-svg-icons';
export default function Template({ data }) {
const post = data.markdownRemark
return (
<Layout>
<main className="container bg-brown min-h-screen p-4 md:p-12">
<Link to="/blog" exact className="text-white text-base items-center"><FontAwesomeIcon icon={faChevronLeft} className="mr-4"></FontAwesomeIcon> Back to Blog</Link>
<article className="container text-white mx-auto rounded-lg mt-4">
<header className="relative">
<div className="absolute h-full w-full flex items-center justify-center p-8">
<div className="bg-white text-brown bg-opacity-75 rounded p-4 md:p-12">
<h1 className="mono text-3xl mb-4">
{post.frontmatter.title}
</h1>
<div className="flex justify-center text-brown">
<img src={post.frontmatter.authorImage} alt="" className="w-10 h-10 rounded-full"/>
<p className="mono flex items-center pl-4 text-xl">{post.frontmatter.author}</p>
</div>
<p className="text-base font-semibold mt-4 text-center">Published on <strong>{post.frontmatter.date}</strong></p>
</div>
</div>
<img src={post.frontmatter.image} alt={post.frontmatter.title} className="w-full object-cover object-left-top rounded-t" style={{ height: "400px", width: "100%"}}/>
</header>
<div className="break-words px-4 lg:px-16 py-12 lg:py-20 prose lg:prose-xl max-w-screen leading-normal">
<div dangerouslySetInnerHTML={{ __html: post.html }} />
</div>
</article>
</main>
</Layout>
)
}
export const postQuery = graphql`
query BlogPostByPath($path: String!) {
markdownRemark(frontmatter: { path: { eq: $path } }){
html
frontmatter {
path
title
date
author
authorImage
image
}
}
}
`
When using the graphiql playground, the proper image path is retrieved for blog.js but not for blog-post.js (individual posts):
blog.js query:
{
"data": {
"allMarkdownRemark": {
"edges": [
{
"node": {
"frontmatter": {
"path": "/customizing-the-scrollbar-with-css",
"title": "Customizing the Scrollbar with CSS",
"description": "Learn how to apply custom styling to the scrollbar on your project with pure CSS",
"date": "2021-01-28",
"category": "CSS",
"image": "../images/scrollbar.png"
}
}
},
blog-post.js query:
{
"errors": [
{
"message": "Variable \"$path\" of required type \"String!\" was not provided.",
"locations": [
{
"line": 1,
"column": 24
}
],
"stack": [
"GraphQLError: Variable \"$path\" of required type \"String!\" was not provided.",
" at _loop (C:\\Users\\npeel\\Microsoft VS Code\\gatsby-blog-main\\gatsby-blog-main\\node_modules\\graphql\\execution\\values.js:92:17)",
" at coerceVariableValues (C:\\Users\\npeel\\Microsoft VS Code\\gatsby-blog-main\\gatsby-blog-main\\node_modules\\graphql\\execution\\values.js:119:16)",
" at getVariableValues (C:\\Users\\npeel\\Microsoft VS Code\\gatsby-blog-main\\gatsby-blog-main\\node_modules\\graphql\\execution\\values.js:48:19)",
" at buildExecutionContext (C:\\Users\\npeel\\Microsoft VS Code\\gatsby-blog-main\\gatsby-blog-main\\node_modules\\graphql\\execution\\execute.js:184:61)",
" at executeImpl (C:\\Users\\npeel\\Microsoft VS Code\\gatsby-blog-main\\gatsby-blog-main\\node_modules\\graphql\\execution\\execute.js:89:20)",
" at execute (C:\\Users\\npeel\\Microsoft VS Code\\gatsby-blog-main\\gatsby-blog-main\\node_modules\\graphql\\execution\\execute.js:64:35)",
" at C:\\Users\\npeel\\Microsoft VS Code\\gatsby-blog-main\\gatsby-blog-main\\node_modules\\express-graphql\\index.js:152:16",
" at runMicrotasks (<anonymous>)",
" at processTicksAndRejections (internal/process/task_queues.js:93:5)"
]
}
],
"extensions": {}
}
gatsby-node.js -
I received an error when adding 'image' and 'authorImage' to frontmatter here
const path = require('path');
exports.createPages = ({actions, graphql}) => {
const { createPage } = actions
const postTemplate = path.resolve('src/templates/blog-post.js');
return graphql(`
{
allMarkdownRemark{
edges {
node {
html
id
frontmatter {
path
title
date
author
category
description
}
}
}
}
}
`).then(res => {
if(res.errors) {
return Promise.reject(res.errors)
}
res.data.allMarkdownRemark.edges.forEach(({node}) => {
createPage({
path: node.frontmatter.path,
component: postTemplate
})
})
})
}
// for RSS feed:
const { createFilePath } = require(`gatsby-source-filesystem`)
exports.onCreateNode = ({ node, actions, getNode }) => {
const { createNodeField } = actions
if (node.internal.type === `MarkdownRemark`) {
const value = createFilePath({ node, getNode })
createNodeField({
name: `slug`,
node,
value,
})
}
}
gatsby-config.js -
module.exports = {
siteMetadata: {
title: `Nikki Peel - Blog`,
description: `Technical blog created with Gatsby and Markdown`,
author: `Nikki Peel`,
siteUrl: `https://nikkipeel.netlify.app`,
},
plugins: [
`gatsby-transformer-remark`,
`gatsby-transformer-sharp`,
`gatsby-plugin-sharp`,
`gatsby-plugin-react-helmet`,
`gatsby-plugin-catch-links`,
{
resolve: `gatsby-source-filesystem`,
options: {
name: `pages`,
path: `${__dirname}/src/pages`,
},
},
{
resolve: `gatsby-source-filesystem`,
options: {
name: `images`,
path: `${__dirname}/src/images`,
},
},
{
resolve: `gatsby-plugin-manifest`,
options: {
name: `gatsby-starter-default`,
short_name: `starter`,
start_url: `/`,
background_color: `#663399`,
theme_color: `#663399`,
display: `minimal-ui`,
icon: `src/images/blog-logo.png`, // This path is relative to the root of the site.
},
},
`gatsby-plugin-feed`,
`gatsby-plugin-postcss`,
`gatsby-plugin-fontawesome-css`,
// this (optional) plugin enables Progressive Web App + Offline functionality
// To learn more, visit: https://gatsby.dev/offline
// `gatsby-plugin-offline`,
],
}
As you can see in the documentation, the when dealing with markdown plus images, the paths should be relative to the markdown file itself so:
---
path: "/create-a-blog-with-react-and-sanity"
date: "2021-01-10"
title: "Create a blog with React and Sanity"
description: "Create a technical blog built with React, TailwindCSS, and Sanity then deploy it using Github and Netlify"
category: "React"
author: "Nikki Peel"
authorImage: /gatsby-blog/images/selfie.png
image: /gatsby-blog/images/sanity-blog-collage.jpg
---
From post-one: https://github.com/nikkipeel/gatsby-blog/blob/main/src/pages/post-one/index.md
Should become:
---
path: "/create-a-blog-with-react-and-sanity"
date: "2021-01-10"
title: "Create a blog with React and Sanity"
description: "Create a technical blog built with React, TailwindCSS, and Sanity then deploy it using Github and Netlify"
category: "React"
author: "Nikki Peel"
authorImage: ../../images/selfie.png
image: ../../sanity-blog-collage.jpg
---
Note the relativity of both images (../../images/selfie.jpg). This will allow Gatsby to create a valid GraphQL node and it will display the childImageSharp node in the GraphQL playground (localhost:8000/___graphql).
Field "image" must not have a selection since type "String" has no
subfields. This can happen if you e.g. accidentally added { } to the
field "image". If you didn't expect "image" to be of type "String"
make sure that your input source and/or plugin is correct.
Unlike it may seem, this is a good error because it's pointing that Gatsby is trying to create nodes from your markdown files (i.e: your paths are well referenced now) and you will be able to use gatsby-image. I've realized that you are missing some plugins, according to the docs.
Add the gatsby-transformer-remark and the gatsby-remark-images plugin.
`gatsby-plugin-sharp`,
{
resolve: `gatsby-transformer-remark`,
options: {
plugins: [
{
resolve: `gatsby-remark-images`,
options: {
maxWidth: 800,
},
},
],
},
},
I wouldn't put the markdown files in the /pages folder by Gatsby to avoid potential issues. Gatsby is a folder-structure based routing, or in other words, Gatsby infers the internal structure of the /pages folder to create the routing and the paths so it's better to avoid mixing stuff.
Your pages can be stored inside any folder if you set the gatsby-source-filesystem accordingly. This will allow Gatsby to create GraphQL nodes from those markdown files.
I was able to get the images to load by referencing an external source in the markdown files but still can't access them by file path 🤷♀️ I'm still researching and working on this issue
---
path: "/post-three"
date: "2020-11-23"
title: "My Third Gatsby Post"
description: "This is my third markdown post with gatsby"
category: "Tailwind"
author: "Nikki Peel"
authorImage: https://i.imgur.com/qyIekvV.png
image: https://i.imgur.com/lKnOCsT.jpg
---
Hi I am starting with VueJS but I have a problem how to connect IMG src in my template with URL writing in my file JSON .for example when I have some product and I like to show full logo for each article I need to add URL exists in file JSON to src IMG .how I do that please thank
<img src="info.imglogo" alt="Media Aside" />
<span v-text="info.logotitle"></span>
</template>
var infos = [
{
compteur: 1,
imglogo: "../imgs/theme.jpg",
logotitle: "Themeforest",
title: "Thrive Themes",
description:
"Conversion Focused WordPress Themes & Plugins, built from the ground up to make your entire website convert more of your visitors into subscribers, customers & clients.",
link1: "Visit ThriveTheme",
link2: "Read Review",
url: "../imgs/theme.jpg"
},
{
compteur: 2,
logotitle: "Elegant",
title: "Sub-Ex",
description: "com.goodreads.Tres-Zap",
link1: "Dr",
link2: "Honorable",
url: "../imgs/theme.jpg"
},
];
export default {
data() {
return {
infos: infos
};
},
name: "Home",
components: {}
};
</script>
like this.
<template>
<div v-for="(info, index) in infos" :key="index">
<img :src="info.imglogo" alt="Media Aside" v-if="info.imgLogo != undefined" />
<span v-text="info.logotitle"></span>
</div>
</template>
You can do as follow:
<img :src="info.imglogo" alt="Media Aside" />
Explanation:
If you use variables and not text, you have to prepend your HTML attributes by ":"
Here is a working code. Replace your entire vue file by this one:
<template>
<div>
<div v-for="info in infos" :key="info.compteur">
<img :src="info.imglogo" alt="Media Aside" />
<span v-text="info.logotitle"></span>
</div>
</div>
</template>
<script>
export default {
name: "Home",
components: {},
data() {
return {
infos: [
{
compteur: 1,
imglogo: "../imgs/theme.jpg",
logotitle: "Themeforest",
title: "Thrive Themes",
description:
"Conversion Focused WordPress Themes & Plugins, built from the ground up to make your entire website convert more of your visitors into subscribers, customers & clients.",
link1: "Visit ThriveTheme",
link2: "Read Review",
url: "../imgs/theme.jpg",
},
{
compteur: 2,
logotitle: "Elegant",
title: "Sub-Ex",
description: "com.goodreads.Tres-Zap",
link1: "Dr",
link2: "Honorable",
url: "../imgs/theme.jpg",
},
],
};
},
};
</script>
I am very new to Laravel and Vuex, I have a simple array of post on my page.
test 1
test 2
test 3
I am trying to link the text on the AppPost.vue component and show the post that has been clicked on a new component (AppShowpost.vue) on the same page. I believe I have to get the post by id and change the state? any help would be good. Thank you.
when you click test 1 it will show "test 1" on a new component (AppShowpost.vue)
In side my store timeline.js, I belive I need to get the post by id and change the state ?
import axios from 'axios'
export default {
namespaced: true,
state: {
posts: []
},
getters: {
posts (state) {
return state.posts
}
},
mutations: {
PUSH_POSTS (state, data) {
state.posts.push(...data)
}
},
actions: {
async getPosts ({ commit }) {
let response = await axios.get('timeline')
commit('PUSH_POSTS', response.data.data)
}
}
}
My AppTimeline.vue component
<template>
<div>
<app-post
v-for="post in posts"
:key="post.id"
:post="post"
/>
</div>
</template>
<script>
import { mapGetters, mapActions } from 'vuex'
export default {
computed: {
...mapGetters({
posts: 'timeline/posts'
})
},
methods: {
...mapActions({
getPosts: 'timeline/getPosts'
})
},
mounted () {
this.getPosts()
}
}
</script>
My AppPost.vue component. I need to link the post.body to display the post in my AppShowpost.vue component.
<template>
<div class="w-full inline-block p-4">
<div class="flex w-full">
<p>
{{ post.body }}
</p>
</div>
</div>
</template>
<script>
export default {
props: {
post: {
required: true,
type: Object
}
}
}
</script>
My AppSowpost.vue component that needs to display the post that is clicked.
<template>
<div>
// Displaypost ?
</div>
</template>
<script>
export default {
// Get post from id ?
}
</script>
Okay you can create a new state in your vuex "current_state", asyou said, you can dispatch a mutation by passing the id to the vuex.
state: {
posts: [],
current_state_id : null
},
In your mutations
set_state_id (state, data) {
state.current_state_id = data;
}
On your app post.vue, you can set a computed property that watches the current state
computed: {
currentState() {
return this.$store.getters["timeline/current_state_id"];
}}
And create a watcher for the computed property to display the current id/post
watch: {
currentState: function(val) {
console.log(val);
},
Maybe this will help you. First I will recommend to use router-link. Read about router link here if your interested. It is very helpful and easy to use. But you will have to define the url and pass parameter on our vue-route(see bellow).
1.You can wrap your post.body in router-link as follow.
//With this approach, you don't need any function in methods
<router-link :to="'/posts/show/' + post.id">
{{ post.body }}
</router-link>
2. In your AppSowpost.vue component, you can find the post in vuex state based on url params as follow.
<template>
<div> {{ thisPost.body }} </div>
</template>
// ****************
computed: {
...mapState({ posts: state=>state.posts }),
// Let's get our single post with the help of url parameter passed on our url
thisPost() { return this.posts.find(p => p.id == this.$route.params.id) || {}; }
},
mounted() { this.$store.dispatch("getPosts");}
3. Let's define our vue route.
path: "posts/show/:id",
name: "showpost",
params: true, // Make sure the params is set to true
component: () => import("#/Components/AppShowPost.vue"),
Your Mutations should look as simple as this.
mutations: {
PUSH_POSTS (state, data) {
state.posts = data;
}
},
Please let me know how it goes.
I am currently working with laravel and vuejs for a booking application, the flow of the app is that once the user clicks to book they get redirected to a page where the booking process starts, this page is where i instantiate vue, and i also call the first component (Book Component) to be rendered:
#section('content')
{{-- <div id="mute" class="on"></div> --}}
<div style="padding: 0.9rem" id="app">
{{-- <router-view name="bookBus"></router-view> --}}
<booker :dref="{{ $route }}" :user="{{ Auth::user()->id }}"></booker>
<router-view></router-view>
</div>
#stop
#section('scripts')
my app.js file looks like this:
// Import Components
import BookComponent from './components/BookComponent.vue';
import ConfirmComponent from './components/ConfirmComponent.vue';
import PayComponent from './components/PayComponent.vue';
Vue.component('booker',BookComponent);
const routes = [
{
path: '/',
component: BookComponent,
name: 'bookBus',
meta: {
mdata: model,
userId: userId
},
},
{
path: '/confirm/:bookId',
component: ConfirmComponent,
name: 'confirmBook',
},
{
path: 'payment/:bookRef',
component: PayComponent,
name: 'payNow',
}
]
const router = new VueRouter({
routes,
mode: 'history',
});
const app = new Vue(
{
router,
}).$mount('#app')
after this the next component to be rendered is the confirmation component that asks the user to confirm the submitted details, and after this is the final payment component. The issue is once the booking component has been processed successfully i programmatically moved to the confirm component. But the confirm component renders directly below the book component. what i want to achieve is for the confirm component to render alone and not below the book component.
#section('content')
{{-- <div id="mute" class="on"></div> --}}
<div style="padding: 0.9rem" id="app">
{{-- <router-view name="bookBus"></router-view> --}}
<router-view></router-view>
</div>
#stop
#section('scripts')
app.js
// Import Components
import BookComponent from './components/BookComponent.vue';
import ConfirmComponent from './components/ConfirmComponent.vue';
import PayComponent from './components/PayComponent.vue';
const routes = [
{
path: '/',
component: BookComponent,
name: 'bookBus',
meta: {
mdata: model,
userId: userId
}
},
{
path: '/confirm/:bookId',
component: ConfirmComponent,
name: 'confirmBook',
},
{
path: 'payment/:bookRef',
component: PayComponent,
name: 'payNow',
},
{
path: '*',
redirect: '/'
}
]